Home | History | Annotate | Download | only in memory
      1 /*-------------------------------------------------------------------------
      2  * Vulkan Conformance Tests
      3  * ------------------------
      4  *
      5  * Copyright (c) 2015 Google Inc.
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18  *
     19  *//*!
     20  * \file
     21  * \brief Pipeline barrier tests
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "vktMemoryPipelineBarrierTests.hpp"
     25 
     26 #include "vktTestCaseUtil.hpp"
     27 
     28 #include "vkDefs.hpp"
     29 #include "vkPlatform.hpp"
     30 #include "vkRefUtil.hpp"
     31 #include "vkQueryUtil.hpp"
     32 #include "vkMemUtil.hpp"
     33 #include "vkTypeUtil.hpp"
     34 #include "vkPrograms.hpp"
     35 
     36 #include "tcuMaybe.hpp"
     37 #include "tcuTextureUtil.hpp"
     38 #include "tcuTestLog.hpp"
     39 #include "tcuResultCollector.hpp"
     40 #include "tcuTexture.hpp"
     41 #include "tcuImageCompare.hpp"
     42 
     43 #include "deUniquePtr.hpp"
     44 #include "deStringUtil.hpp"
     45 #include "deRandom.hpp"
     46 
     47 #include "deInt32.h"
     48 #include "deMath.h"
     49 #include "deMemory.h"
     50 
     51 #include <map>
     52 #include <set>
     53 #include <sstream>
     54 #include <string>
     55 #include <vector>
     56 
     57 using tcu::TestLog;
     58 using tcu::Maybe;
     59 
     60 using de::MovePtr;
     61 
     62 using std::string;
     63 using std::vector;
     64 using std::map;
     65 using std::set;
     66 using std::pair;
     67 
     68 using tcu::IVec2;
     69 using tcu::UVec2;
     70 using tcu::UVec4;
     71 using tcu::Vec4;
     72 using tcu::ConstPixelBufferAccess;
     73 using tcu::PixelBufferAccess;
     74 using tcu::TextureFormat;
     75 using tcu::TextureLevel;
     76 
     77 namespace vkt
     78 {
     79 namespace memory
     80 {
     81 namespace
     82 {
     83 enum
     84 {
     85 	MAX_UNIFORM_BUFFER_SIZE = 1024,
     86 	MAX_STORAGE_BUFFER_SIZE = (1<<28),
     87 	MAX_SIZE = (128 * 1024)
     88 };
     89 
     90 // \todo [mika] Add to utilities
     91 template<typename T>
     92 T divRoundUp (const T& a, const T& b)
     93 {
     94 	return (a / b) + (a % b == 0 ? 0 : 1);
     95 }
     96 
     97 enum
     98 {
     99 	ALL_PIPELINE_STAGES = vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
    100 						| vk::VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT
    101 						| vk::VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT
    102 						| vk::VK_PIPELINE_STAGE_VERTEX_INPUT_BIT
    103 						| vk::VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
    104 						| vk::VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT
    105 						| vk::VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT
    106 						| vk::VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT
    107 						| vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
    108 						| vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
    109 						| vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
    110 						| vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
    111 						| vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT
    112 						| vk::VK_PIPELINE_STAGE_TRANSFER_BIT
    113 						| vk::VK_PIPELINE_STAGE_HOST_BIT
    114 };
    115 
    116 enum
    117 {
    118 	ALL_ACCESSES = vk::VK_ACCESS_INDIRECT_COMMAND_READ_BIT
    119 				 | vk::VK_ACCESS_INDEX_READ_BIT
    120 				 | vk::VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT
    121 				 | vk::VK_ACCESS_UNIFORM_READ_BIT
    122 				 | vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT
    123 				 | vk::VK_ACCESS_SHADER_READ_BIT
    124 				 | vk::VK_ACCESS_SHADER_WRITE_BIT
    125 				 | vk::VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
    126 				 | vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
    127 				 | vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT
    128 				 | vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
    129 				 | vk::VK_ACCESS_TRANSFER_READ_BIT
    130 				 | vk::VK_ACCESS_TRANSFER_WRITE_BIT
    131 				 | vk::VK_ACCESS_HOST_READ_BIT
    132 				 | vk::VK_ACCESS_HOST_WRITE_BIT
    133 				 | vk::VK_ACCESS_MEMORY_READ_BIT
    134 				 | vk::VK_ACCESS_MEMORY_WRITE_BIT
    135 };
    136 
    137 enum Usage
    138 {
    139 	// Mapped host read and write
    140 	USAGE_HOST_READ = (0x1u<<0),
    141 	USAGE_HOST_WRITE = (0x1u<<1),
    142 
    143 	// Copy and other transfer operations
    144 	USAGE_TRANSFER_SRC = (0x1u<<2),
    145 	USAGE_TRANSFER_DST = (0x1u<<3),
    146 
    147 	// Buffer usage flags
    148 	USAGE_INDEX_BUFFER = (0x1u<<4),
    149 	USAGE_VERTEX_BUFFER = (0x1u<<5),
    150 
    151 	USAGE_UNIFORM_BUFFER = (0x1u<<6),
    152 	USAGE_STORAGE_BUFFER = (0x1u<<7),
    153 
    154 	USAGE_UNIFORM_TEXEL_BUFFER = (0x1u<<8),
    155 	USAGE_STORAGE_TEXEL_BUFFER = (0x1u<<9),
    156 
    157 	// \todo [2016-03-09 mika] This is probably almost impossible to do
    158 	USAGE_INDIRECT_BUFFER = (0x1u<<10),
    159 
    160 	// Texture usage flags
    161 	USAGE_SAMPLED_IMAGE = (0x1u<<11),
    162 	USAGE_STORAGE_IMAGE = (0x1u<<12),
    163 	USAGE_COLOR_ATTACHMENT = (0x1u<<13),
    164 	USAGE_INPUT_ATTACHMENT = (0x1u<<14),
    165 	USAGE_DEPTH_STENCIL_ATTACHMENT = (0x1u<<15),
    166 };
    167 
    168 bool supportsDeviceBufferWrites (Usage usage)
    169 {
    170 	if (usage & USAGE_TRANSFER_DST)
    171 		return true;
    172 
    173 	if (usage & USAGE_STORAGE_BUFFER)
    174 		return true;
    175 
    176 	if (usage & USAGE_STORAGE_TEXEL_BUFFER)
    177 		return true;
    178 
    179 	return false;
    180 }
    181 
    182 bool supportsDeviceImageWrites (Usage usage)
    183 {
    184 	if (usage & USAGE_TRANSFER_DST)
    185 		return true;
    186 
    187 	if (usage & USAGE_STORAGE_IMAGE)
    188 		return true;
    189 
    190 	if (usage & USAGE_COLOR_ATTACHMENT)
    191 		return true;
    192 
    193 	return false;
    194 }
    195 
    196 // Sequential access enums
    197 enum Access
    198 {
    199 	ACCESS_INDIRECT_COMMAND_READ_BIT = 0,
    200 	ACCESS_INDEX_READ_BIT,
    201 	ACCESS_VERTEX_ATTRIBUTE_READ_BIT,
    202 	ACCESS_UNIFORM_READ_BIT,
    203 	ACCESS_INPUT_ATTACHMENT_READ_BIT,
    204 	ACCESS_SHADER_READ_BIT,
    205 	ACCESS_SHADER_WRITE_BIT,
    206 	ACCESS_COLOR_ATTACHMENT_READ_BIT,
    207 	ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
    208 	ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
    209 	ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
    210 	ACCESS_TRANSFER_READ_BIT,
    211 	ACCESS_TRANSFER_WRITE_BIT,
    212 	ACCESS_HOST_READ_BIT,
    213 	ACCESS_HOST_WRITE_BIT,
    214 	ACCESS_MEMORY_READ_BIT,
    215 	ACCESS_MEMORY_WRITE_BIT,
    216 
    217 	ACCESS_LAST
    218 };
    219 
    220 // Sequential stage enums
    221 enum PipelineStage
    222 {
    223 	PIPELINESTAGE_TOP_OF_PIPE_BIT = 0,
    224 	PIPELINESTAGE_BOTTOM_OF_PIPE_BIT,
    225 	PIPELINESTAGE_DRAW_INDIRECT_BIT,
    226 	PIPELINESTAGE_VERTEX_INPUT_BIT,
    227 	PIPELINESTAGE_VERTEX_SHADER_BIT,
    228 	PIPELINESTAGE_TESSELLATION_CONTROL_SHADER_BIT,
    229 	PIPELINESTAGE_TESSELLATION_EVALUATION_SHADER_BIT,
    230 	PIPELINESTAGE_GEOMETRY_SHADER_BIT,
    231 	PIPELINESTAGE_FRAGMENT_SHADER_BIT,
    232 	PIPELINESTAGE_EARLY_FRAGMENT_TESTS_BIT,
    233 	PIPELINESTAGE_LATE_FRAGMENT_TESTS_BIT,
    234 	PIPELINESTAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
    235 	PIPELINESTAGE_COMPUTE_SHADER_BIT,
    236 	PIPELINESTAGE_TRANSFER_BIT,
    237 	PIPELINESTAGE_HOST_BIT,
    238 
    239 	PIPELINESTAGE_LAST
    240 };
    241 
    242 PipelineStage pipelineStageFlagToPipelineStage (vk::VkPipelineStageFlagBits flags)
    243 {
    244 	switch (flags)
    245 	{
    246 		case vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT:						return PIPELINESTAGE_TOP_OF_PIPE_BIT;
    247 		case vk::VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT:					return PIPELINESTAGE_BOTTOM_OF_PIPE_BIT;
    248 		case vk::VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT:					return PIPELINESTAGE_DRAW_INDIRECT_BIT;
    249 		case vk::VK_PIPELINE_STAGE_VERTEX_INPUT_BIT:					return PIPELINESTAGE_VERTEX_INPUT_BIT;
    250 		case vk::VK_PIPELINE_STAGE_VERTEX_SHADER_BIT:					return PIPELINESTAGE_VERTEX_SHADER_BIT;
    251 		case vk::VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT:		return PIPELINESTAGE_TESSELLATION_CONTROL_SHADER_BIT;
    252 		case vk::VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT:	return PIPELINESTAGE_TESSELLATION_EVALUATION_SHADER_BIT;
    253 		case vk::VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT:					return PIPELINESTAGE_GEOMETRY_SHADER_BIT;
    254 		case vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT:					return PIPELINESTAGE_FRAGMENT_SHADER_BIT;
    255 		case vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT:			return PIPELINESTAGE_EARLY_FRAGMENT_TESTS_BIT;
    256 		case vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT:				return PIPELINESTAGE_LATE_FRAGMENT_TESTS_BIT;
    257 		case vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT:			return PIPELINESTAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
    258 		case vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT:					return PIPELINESTAGE_COMPUTE_SHADER_BIT;
    259 		case vk::VK_PIPELINE_STAGE_TRANSFER_BIT:						return PIPELINESTAGE_TRANSFER_BIT;
    260 		case vk::VK_PIPELINE_STAGE_HOST_BIT:							return PIPELINESTAGE_HOST_BIT;
    261 
    262 		default:
    263 			DE_FATAL("Unknown pipeline stage flags");
    264 			return PIPELINESTAGE_LAST;
    265 	}
    266 }
    267 
    268 Usage operator| (Usage a, Usage b)
    269 {
    270 	return (Usage)((deUint32)a | (deUint32)b);
    271 }
    272 
    273 Usage operator& (Usage a, Usage b)
    274 {
    275 	return (Usage)((deUint32)a & (deUint32)b);
    276 }
    277 
    278 string usageToName (Usage usage)
    279 {
    280 	const struct
    281 	{
    282 		Usage				usage;
    283 		const char* const	name;
    284 	} usageNames[] =
    285 	{
    286 		{ USAGE_HOST_READ,					"host_read" },
    287 		{ USAGE_HOST_WRITE,					"host_write" },
    288 
    289 		{ USAGE_TRANSFER_SRC,				"transfer_src" },
    290 		{ USAGE_TRANSFER_DST,				"transfer_dst" },
    291 
    292 		{ USAGE_INDEX_BUFFER,				"index_buffer" },
    293 		{ USAGE_VERTEX_BUFFER,				"vertex_buffer" },
    294 		{ USAGE_UNIFORM_BUFFER,				"uniform_buffer" },
    295 		{ USAGE_STORAGE_BUFFER,				"storage_buffer" },
    296 		{ USAGE_UNIFORM_TEXEL_BUFFER,		"uniform_texel_buffer" },
    297 		{ USAGE_STORAGE_TEXEL_BUFFER,		"storage_texel_buffer" },
    298 		{ USAGE_INDIRECT_BUFFER,			"indirect_buffer" },
    299 		{ USAGE_SAMPLED_IMAGE,				"image_sampled" },
    300 		{ USAGE_STORAGE_IMAGE,				"storage_image" },
    301 		{ USAGE_COLOR_ATTACHMENT,			"color_attachment" },
    302 		{ USAGE_INPUT_ATTACHMENT,			"input_attachment" },
    303 		{ USAGE_DEPTH_STENCIL_ATTACHMENT,	"depth_stencil_attachment" },
    304 	};
    305 
    306 	std::ostringstream	stream;
    307 	bool				first = true;
    308 
    309 	for (size_t usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(usageNames); usageNdx++)
    310 	{
    311 		if (usage & usageNames[usageNdx].usage)
    312 		{
    313 			if (!first)
    314 				stream << "_";
    315 			else
    316 				first = false;
    317 
    318 			stream << usageNames[usageNdx].name;
    319 		}
    320 	}
    321 
    322 	return stream.str();
    323 }
    324 
    325 vk::VkBufferUsageFlags usageToBufferUsageFlags (Usage usage)
    326 {
    327 	vk::VkBufferUsageFlags flags = 0;
    328 
    329 	if (usage & USAGE_TRANSFER_SRC)
    330 		flags |= vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
    331 
    332 	if (usage & USAGE_TRANSFER_DST)
    333 		flags |= vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
    334 
    335 	if (usage & USAGE_INDEX_BUFFER)
    336 		flags |= vk::VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
    337 
    338 	if (usage & USAGE_VERTEX_BUFFER)
    339 		flags |= vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
    340 
    341 	if (usage & USAGE_INDIRECT_BUFFER)
    342 		flags |= vk::VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
    343 
    344 	if (usage & USAGE_UNIFORM_BUFFER)
    345 		flags |= vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
    346 
    347 	if (usage & USAGE_STORAGE_BUFFER)
    348 		flags |= vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
    349 
    350 	if (usage & USAGE_UNIFORM_TEXEL_BUFFER)
    351 		flags |= vk::VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT;
    352 
    353 	if (usage & USAGE_STORAGE_TEXEL_BUFFER)
    354 		flags |= vk::VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
    355 
    356 	return flags;
    357 }
    358 
    359 vk::VkImageUsageFlags usageToImageUsageFlags (Usage usage)
    360 {
    361 	vk::VkImageUsageFlags flags = 0;
    362 
    363 	if (usage & USAGE_TRANSFER_SRC)
    364 		flags |= vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
    365 
    366 	if (usage & USAGE_TRANSFER_DST)
    367 		flags |= vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT;
    368 
    369 	if (usage & USAGE_SAMPLED_IMAGE)
    370 		flags |= vk::VK_IMAGE_USAGE_SAMPLED_BIT;
    371 
    372 	if (usage & USAGE_STORAGE_IMAGE)
    373 		flags |= vk::VK_IMAGE_USAGE_STORAGE_BIT;
    374 
    375 	if (usage & USAGE_COLOR_ATTACHMENT)
    376 		flags |= vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
    377 
    378 	if (usage & USAGE_INPUT_ATTACHMENT)
    379 		flags |= vk::VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
    380 
    381 	if (usage & USAGE_DEPTH_STENCIL_ATTACHMENT)
    382 		flags |= vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
    383 
    384 	return flags;
    385 }
    386 
    387 vk::VkPipelineStageFlags usageToStageFlags (Usage usage)
    388 {
    389 	vk::VkPipelineStageFlags flags = 0;
    390 
    391 	if (usage & (USAGE_HOST_READ|USAGE_HOST_WRITE))
    392 		flags |= vk::VK_PIPELINE_STAGE_HOST_BIT;
    393 
    394 	if (usage & (USAGE_TRANSFER_SRC|USAGE_TRANSFER_DST))
    395 		flags |= vk::VK_PIPELINE_STAGE_TRANSFER_BIT;
    396 
    397 	if (usage & (USAGE_VERTEX_BUFFER|USAGE_INDEX_BUFFER))
    398 		flags |= vk::VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
    399 
    400 	if (usage & USAGE_INDIRECT_BUFFER)
    401 		flags |= vk::VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT;
    402 
    403 	if (usage &
    404 			(USAGE_UNIFORM_BUFFER
    405 			| USAGE_STORAGE_BUFFER
    406 			| USAGE_UNIFORM_TEXEL_BUFFER
    407 			| USAGE_STORAGE_TEXEL_BUFFER
    408 			| USAGE_SAMPLED_IMAGE
    409 			| USAGE_STORAGE_IMAGE))
    410 	{
    411 		flags |= (vk::VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
    412 				| vk::VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT
    413 				| vk::VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT
    414 				| vk::VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT
    415 				| vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
    416 				| vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
    417 	}
    418 
    419 	if (usage & USAGE_INPUT_ATTACHMENT)
    420 		flags |= vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
    421 
    422 	if (usage & USAGE_COLOR_ATTACHMENT)
    423 		flags |= vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
    424 
    425 	if (usage & USAGE_DEPTH_STENCIL_ATTACHMENT)
    426 	{
    427 		flags |= vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
    428 				| vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
    429 	}
    430 
    431 	return flags;
    432 }
    433 
    434 vk::VkAccessFlags usageToAccessFlags (Usage usage)
    435 {
    436 	vk::VkAccessFlags flags = 0;
    437 
    438 	if (usage & USAGE_HOST_READ)
    439 		flags |= vk::VK_ACCESS_HOST_READ_BIT;
    440 
    441 	if (usage & USAGE_HOST_WRITE)
    442 		flags |= vk::VK_ACCESS_HOST_WRITE_BIT;
    443 
    444 	if (usage & USAGE_TRANSFER_SRC)
    445 		flags |= vk::VK_ACCESS_TRANSFER_READ_BIT;
    446 
    447 	if (usage & USAGE_TRANSFER_DST)
    448 		flags |= vk::VK_ACCESS_TRANSFER_WRITE_BIT;
    449 
    450 	if (usage & USAGE_INDEX_BUFFER)
    451 		flags |= vk::VK_ACCESS_INDEX_READ_BIT;
    452 
    453 	if (usage & USAGE_VERTEX_BUFFER)
    454 		flags |= vk::VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
    455 
    456 	if (usage & (USAGE_UNIFORM_BUFFER | USAGE_UNIFORM_TEXEL_BUFFER))
    457 		flags |= vk::VK_ACCESS_UNIFORM_READ_BIT;
    458 
    459 	if (usage & USAGE_SAMPLED_IMAGE)
    460 		flags |= vk::VK_ACCESS_SHADER_READ_BIT;
    461 
    462 	if (usage & (USAGE_STORAGE_BUFFER
    463 				| USAGE_STORAGE_TEXEL_BUFFER
    464 				| USAGE_STORAGE_IMAGE))
    465 		flags |= vk::VK_ACCESS_SHADER_READ_BIT | vk::VK_ACCESS_SHADER_WRITE_BIT;
    466 
    467 	if (usage & USAGE_INDIRECT_BUFFER)
    468 		flags |= vk::VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
    469 
    470 	if (usage & USAGE_COLOR_ATTACHMENT)
    471 		flags |= vk::VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
    472 
    473 	if (usage & USAGE_INPUT_ATTACHMENT)
    474 		flags |= vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
    475 
    476 	if (usage & USAGE_DEPTH_STENCIL_ATTACHMENT)
    477 		flags |= vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT
    478 			| vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
    479 
    480 	return flags;
    481 }
    482 
    483 struct TestConfig
    484 {
    485 	Usage				usage;
    486 	vk::VkDeviceSize	size;
    487 	vk::VkSharingMode	sharing;
    488 };
    489 
    490 vk::Move<vk::VkCommandBuffer> createBeginCommandBuffer (const vk::DeviceInterface&	vkd,
    491 														vk::VkDevice				device,
    492 														vk::VkCommandPool			pool,
    493 														vk::VkCommandBufferLevel	level)
    494 {
    495 	const vk::VkCommandBufferInheritanceInfo	inheritInfo	=
    496 	{
    497 		vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
    498 		DE_NULL,
    499 		0,
    500 		0,
    501 		0,
    502 		VK_FALSE,
    503 		0u,
    504 		0u
    505 	};
    506 	const vk::VkCommandBufferBeginInfo			beginInfo =
    507 	{
    508 		vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
    509 		DE_NULL,
    510 		0u,
    511 		(level == vk::VK_COMMAND_BUFFER_LEVEL_SECONDARY ? &inheritInfo : (const vk::VkCommandBufferInheritanceInfo*)DE_NULL),
    512 	};
    513 
    514 	vk::Move<vk::VkCommandBuffer> commandBuffer (allocateCommandBuffer(vkd, device, pool, level));
    515 
    516 	vkd.beginCommandBuffer(*commandBuffer, &beginInfo);
    517 
    518 	return commandBuffer;
    519 }
    520 
    521 vk::Move<vk::VkBuffer> createBuffer (const vk::DeviceInterface&	vkd,
    522 									 vk::VkDevice				device,
    523 									 vk::VkDeviceSize			size,
    524 									 vk::VkBufferUsageFlags		usage,
    525 									 vk::VkSharingMode			sharingMode,
    526 									 const vector<deUint32>&	queueFamilies)
    527 {
    528 	const vk::VkBufferCreateInfo	createInfo =
    529 	{
    530 		vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
    531 		DE_NULL,
    532 
    533 		0,	// flags
    534 		size,
    535 		usage,
    536 		sharingMode,
    537 		(deUint32)queueFamilies.size(),
    538 		&queueFamilies[0]
    539 	};
    540 
    541 	return vk::createBuffer(vkd, device, &createInfo);
    542 }
    543 
    544 vk::Move<vk::VkDeviceMemory> allocMemory (const vk::DeviceInterface&	vkd,
    545 										  vk::VkDevice					device,
    546 										  vk::VkDeviceSize				size,
    547 										  deUint32						memoryTypeIndex)
    548 {
    549 	const vk::VkMemoryAllocateInfo alloc =
    550 	{
    551 		vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,	// sType
    552 		DE_NULL,									// pNext
    553 
    554 		size,
    555 		memoryTypeIndex
    556 	};
    557 
    558 	return vk::allocateMemory(vkd, device, &alloc);
    559 }
    560 
    561 vk::Move<vk::VkDeviceMemory> bindBufferMemory (const vk::InstanceInterface&	vki,
    562 											   const vk::DeviceInterface&	vkd,
    563 											   vk::VkPhysicalDevice			physicalDevice,
    564 											   vk::VkDevice					device,
    565 											   vk::VkBuffer					buffer,
    566 											   vk::VkMemoryPropertyFlags	properties)
    567 {
    568 	const vk::VkMemoryRequirements				memoryRequirements	= vk::getBufferMemoryRequirements(vkd, device, buffer);
    569 	const vk::VkPhysicalDeviceMemoryProperties	memoryProperties	= vk::getPhysicalDeviceMemoryProperties(vki, physicalDevice);
    570 	deUint32									memoryTypeIndex;
    571 
    572 	for (memoryTypeIndex = 0; memoryTypeIndex < memoryProperties.memoryTypeCount; memoryTypeIndex++)
    573 	{
    574 		if ((memoryRequirements.memoryTypeBits & (0x1u << memoryTypeIndex))
    575 			&& (memoryProperties.memoryTypes[memoryTypeIndex].propertyFlags & properties) == properties)
    576 		{
    577 			try
    578 			{
    579 				const vk::VkMemoryAllocateInfo	allocationInfo	=
    580 				{
    581 					vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
    582 					DE_NULL,
    583 					memoryRequirements.size,
    584 					memoryTypeIndex
    585 				};
    586 				vk::Move<vk::VkDeviceMemory>	memory			(vk::allocateMemory(vkd, device, &allocationInfo));
    587 
    588 				VK_CHECK(vkd.bindBufferMemory(device, buffer, *memory, 0));
    589 
    590 				return memory;
    591 			}
    592 			catch (const vk::Error& error)
    593 			{
    594 				if (error.getError() == vk::VK_ERROR_OUT_OF_DEVICE_MEMORY
    595 					|| error.getError() == vk::VK_ERROR_OUT_OF_HOST_MEMORY)
    596 				{
    597 					// Try next memory type/heap if out of memory
    598 				}
    599 				else
    600 				{
    601 					// Throw all other errors forward
    602 					throw;
    603 				}
    604 			}
    605 		}
    606 	}
    607 
    608 	TCU_FAIL("Failed to allocate memory for buffer");
    609 }
    610 
    611 vk::Move<vk::VkDeviceMemory> bindImageMemory (const vk::InstanceInterface&	vki,
    612 											   const vk::DeviceInterface&	vkd,
    613 											   vk::VkPhysicalDevice			physicalDevice,
    614 											   vk::VkDevice					device,
    615 											   vk::VkImage					image,
    616 											   vk::VkMemoryPropertyFlags	properties)
    617 {
    618 	const vk::VkMemoryRequirements				memoryRequirements	= vk::getImageMemoryRequirements(vkd, device, image);
    619 	const vk::VkPhysicalDeviceMemoryProperties	memoryProperties	= vk::getPhysicalDeviceMemoryProperties(vki, physicalDevice);
    620 	deUint32									memoryTypeIndex;
    621 
    622 	for (memoryTypeIndex = 0; memoryTypeIndex < memoryProperties.memoryTypeCount; memoryTypeIndex++)
    623 	{
    624 		if ((memoryRequirements.memoryTypeBits & (0x1u << memoryTypeIndex))
    625 			&& (memoryProperties.memoryTypes[memoryTypeIndex].propertyFlags & properties) == properties)
    626 		{
    627 			try
    628 			{
    629 				const vk::VkMemoryAllocateInfo	allocationInfo	=
    630 				{
    631 					vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
    632 					DE_NULL,
    633 					memoryRequirements.size,
    634 					memoryTypeIndex
    635 				};
    636 				vk::Move<vk::VkDeviceMemory>	memory			(vk::allocateMemory(vkd, device, &allocationInfo));
    637 
    638 				VK_CHECK(vkd.bindImageMemory(device, image, *memory, 0));
    639 
    640 				return memory;
    641 			}
    642 			catch (const vk::Error& error)
    643 			{
    644 				if (error.getError() == vk::VK_ERROR_OUT_OF_DEVICE_MEMORY
    645 					|| error.getError() == vk::VK_ERROR_OUT_OF_HOST_MEMORY)
    646 				{
    647 					// Try next memory type/heap if out of memory
    648 				}
    649 				else
    650 				{
    651 					// Throw all other errors forward
    652 					throw;
    653 				}
    654 			}
    655 		}
    656 	}
    657 
    658 	TCU_FAIL("Failed to allocate memory for image");
    659 }
    660 
    661 void queueRun (const vk::DeviceInterface&	vkd,
    662 			   vk::VkQueue					queue,
    663 			   vk::VkCommandBuffer			commandBuffer)
    664 {
    665 	const vk::VkSubmitInfo	submitInfo	=
    666 	{
    667 		vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
    668 		DE_NULL,
    669 
    670 		0,
    671 		DE_NULL,
    672 		(const vk::VkPipelineStageFlags*)DE_NULL,
    673 
    674 		1,
    675 		&commandBuffer,
    676 
    677 		0,
    678 		DE_NULL
    679 	};
    680 
    681 	VK_CHECK(vkd.queueSubmit(queue, 1, &submitInfo, 0));
    682 	VK_CHECK(vkd.queueWaitIdle(queue));
    683 }
    684 
    685 void* mapMemory (const vk::DeviceInterface&	vkd,
    686 				 vk::VkDevice				device,
    687 				 vk::VkDeviceMemory			memory,
    688 				 vk::VkDeviceSize			size)
    689 {
    690 	void* ptr;
    691 
    692 	VK_CHECK(vkd.mapMemory(device, memory, 0, size, 0, &ptr));
    693 
    694 	return ptr;
    695 }
    696 
    697 class ReferenceMemory
    698 {
    699 public:
    700 			ReferenceMemory	(size_t size);
    701 
    702 	void	set				(size_t pos, deUint8 val);
    703 	deUint8	get				(size_t pos) const;
    704 	bool	isDefined		(size_t pos) const;
    705 
    706 	void	setDefined		(size_t offset, size_t size, const void* data);
    707 	void	setUndefined	(size_t offset, size_t size);
    708 	void	setData			(size_t offset, size_t size, const void* data);
    709 
    710 	size_t	getSize			(void) const { return m_data.size(); }
    711 
    712 private:
    713 	vector<deUint8>		m_data;
    714 	vector<deUint64>	m_defined;
    715 };
    716 
    717 ReferenceMemory::ReferenceMemory (size_t size)
    718 	: m_data	(size, 0)
    719 	, m_defined	(size / 64 + (size % 64 == 0 ? 0 : 1), 0ull)
    720 {
    721 }
    722 
    723 void ReferenceMemory::set (size_t pos, deUint8 val)
    724 {
    725 	DE_ASSERT(pos < m_data.size());
    726 
    727 	m_data[pos] = val;
    728 	m_defined[pos / 64] |= 0x1ull << (pos % 64);
    729 }
    730 
    731 void ReferenceMemory::setData (size_t offset, size_t size, const void* data_)
    732 {
    733 	const deUint8* data = (const deUint8*)data_;
    734 
    735 	DE_ASSERT(offset < m_data.size());
    736 	DE_ASSERT(offset + size <= m_data.size());
    737 
    738 	// \todo [2016-03-09 mika] Optimize
    739 	for (size_t pos = 0; pos < size; pos++)
    740 	{
    741 		m_data[offset + pos] = data[pos];
    742 		m_defined[(offset + pos) / 64] |= 0x1ull << ((offset + pos) % 64);
    743 	}
    744 }
    745 
    746 void ReferenceMemory::setUndefined	(size_t offset, size_t size)
    747 {
    748 	// \todo [2016-03-09 mika] Optimize
    749 	for (size_t pos = 0; pos < size; pos++)
    750 		m_defined[(offset + pos) / 64] |= 0x1ull << ((offset + pos) % 64);
    751 }
    752 
    753 deUint8 ReferenceMemory::get (size_t pos) const
    754 {
    755 	DE_ASSERT(pos < m_data.size());
    756 	DE_ASSERT(isDefined(pos));
    757 	return m_data[pos];
    758 }
    759 
    760 bool ReferenceMemory::isDefined (size_t pos) const
    761 {
    762 	DE_ASSERT(pos < m_data.size());
    763 
    764 	return (m_defined[pos / 64] & (0x1ull << (pos % 64))) != 0;
    765 }
    766 
    767 class Memory
    768 {
    769 public:
    770 							Memory				(const vk::InstanceInterface&	vki,
    771 												 const vk::DeviceInterface&		vkd,
    772 												 vk::VkPhysicalDevice			physicalDevice,
    773 												 vk::VkDevice					device,
    774 												 vk::VkDeviceSize				size,
    775 												 deUint32						memoryTypeIndex,
    776 												 vk::VkDeviceSize				maxBufferSize,
    777 												 deInt32						maxImageWidth,
    778 												 deInt32						maxImageHeight);
    779 
    780 	vk::VkDeviceSize		getSize				(void) const { return m_size; }
    781 	vk::VkDeviceSize		getMaxBufferSize	(void) const { return m_maxBufferSize; }
    782 	bool					getSupportBuffers	(void) const { return m_maxBufferSize > 0; }
    783 
    784 	deInt32					getMaxImageWidth	(void) const { return m_maxImageWidth; }
    785 	deInt32					getMaxImageHeight	(void) const { return m_maxImageHeight; }
    786 	bool					getSupportImages	(void) const { return m_maxImageWidth > 0; }
    787 
    788 	const vk::VkMemoryType&	getMemoryType		(void) const { return m_memoryType; }
    789 	deUint32				getMemoryTypeIndex	(void) const { return m_memoryTypeIndex; }
    790 	vk::VkDeviceMemory		getMemory			(void) const { return *m_memory; }
    791 
    792 private:
    793 	const vk::VkDeviceSize					m_size;
    794 	const deUint32							m_memoryTypeIndex;
    795 	const vk::VkMemoryType					m_memoryType;
    796 	const vk::Unique<vk::VkDeviceMemory>	m_memory;
    797 	const vk::VkDeviceSize					m_maxBufferSize;
    798 	const deInt32							m_maxImageWidth;
    799 	const deInt32							m_maxImageHeight;
    800 };
    801 
    802 vk::VkMemoryType getMemoryTypeInfo (const vk::InstanceInterface&	vki,
    803 									vk::VkPhysicalDevice			device,
    804 									deUint32						memoryTypeIndex)
    805 {
    806 	const vk::VkPhysicalDeviceMemoryProperties memoryProperties = vk::getPhysicalDeviceMemoryProperties(vki, device);
    807 
    808 	DE_ASSERT(memoryTypeIndex < memoryProperties.memoryTypeCount);
    809 
    810 	return memoryProperties.memoryTypes[memoryTypeIndex];
    811 }
    812 
    813 vk::VkDeviceSize findMaxBufferSize (const vk::DeviceInterface&		vkd,
    814 									vk::VkDevice					device,
    815 
    816 									vk::VkBufferUsageFlags			usage,
    817 									vk::VkSharingMode				sharingMode,
    818 									const vector<deUint32>&			queueFamilies,
    819 
    820 									vk::VkDeviceSize				memorySize,
    821 									deUint32						memoryTypeIndex)
    822 {
    823 	vk::VkDeviceSize	lastSuccess	= 0;
    824 	vk::VkDeviceSize	currentSize	= memorySize / 2;
    825 
    826 	{
    827 		const vk::Unique<vk::VkBuffer>  buffer			(createBuffer(vkd, device, memorySize, usage, sharingMode, queueFamilies));
    828 		const vk::VkMemoryRequirements  requirements	(vk::getBufferMemoryRequirements(vkd, device, *buffer));
    829 
    830 		if (requirements.size == memorySize && requirements.memoryTypeBits & (0x1u << memoryTypeIndex))
    831 			return memorySize;
    832 	}
    833 
    834 	for (vk::VkDeviceSize stepSize = memorySize / 4; currentSize > 0; stepSize /= 2)
    835 	{
    836 		const vk::Unique<vk::VkBuffer>	buffer			(createBuffer(vkd, device, currentSize, usage, sharingMode, queueFamilies));
    837 		const vk::VkMemoryRequirements	requirements	(vk::getBufferMemoryRequirements(vkd, device, *buffer));
    838 
    839 		if (requirements.size <= memorySize && requirements.memoryTypeBits & (0x1u << memoryTypeIndex))
    840 		{
    841 			lastSuccess = currentSize;
    842 			currentSize += stepSize;
    843 		}
    844 		else
    845 			currentSize -= stepSize;
    846 
    847 		if (stepSize == 0)
    848 			break;
    849 	}
    850 
    851 	return lastSuccess;
    852 }
    853 
    854 // Round size down maximum W * H * 4, where W and H < 4096
    855 vk::VkDeviceSize roundBufferSizeToWxHx4 (vk::VkDeviceSize size)
    856 {
    857 	const vk::VkDeviceSize	maxTextureSize	= 4096;
    858 	vk::VkDeviceSize		maxTexelCount	= size / 4;
    859 	vk::VkDeviceSize		bestW			= de::max(maxTexelCount, maxTextureSize);
    860 	vk::VkDeviceSize		bestH			= maxTexelCount / bestW;
    861 
    862 	// \todo [2016-03-09 mika] Could probably be faster?
    863 	for (vk::VkDeviceSize w = 1; w * w < maxTexelCount && w < maxTextureSize && bestW * bestH * 4 < size; w++)
    864 	{
    865 		const vk::VkDeviceSize h = maxTexelCount / w;
    866 
    867 		if (bestW * bestH < w * h)
    868 		{
    869 			bestW = w;
    870 			bestH = h;
    871 		}
    872 	}
    873 
    874 	return bestW * bestH * 4;
    875 }
    876 
    877 // Find RGBA8 image size that has exactly "size" of number of bytes.
    878 // "size" must be W * H * 4 where W and H < 4096
    879 IVec2 findImageSizeWxHx4 (vk::VkDeviceSize size)
    880 {
    881 	const vk::VkDeviceSize	maxTextureSize	= 4096;
    882 	vk::VkDeviceSize		texelCount		= size / 4;
    883 
    884 	DE_ASSERT((size % 4) == 0);
    885 
    886 	// \todo [2016-03-09 mika] Could probably be faster?
    887 	for (vk::VkDeviceSize w = 1; w < maxTextureSize && w < texelCount; w++)
    888 	{
    889 		const vk::VkDeviceSize	h	= texelCount / w;
    890 
    891 		if ((texelCount  % w) == 0 && h < maxTextureSize)
    892 			return IVec2((int)w, (int)h);
    893 	}
    894 
    895 	DE_FATAL("Invalid size");
    896 	return IVec2(-1, -1);
    897 }
    898 
    899 IVec2 findMaxRGBA8ImageSize (const vk::DeviceInterface&	vkd,
    900 							 vk::VkDevice				device,
    901 
    902 							 vk::VkImageUsageFlags		usage,
    903 							 vk::VkSharingMode			sharingMode,
    904 							 const vector<deUint32>&	queueFamilies,
    905 
    906 							 vk::VkDeviceSize			memorySize,
    907 							 deUint32					memoryTypeIndex)
    908 {
    909 	IVec2		lastSuccess		(0);
    910 	IVec2		currentSize;
    911 
    912 	{
    913 		const deUint32	texelCount	= (deUint32)(memorySize / 4);
    914 		const deUint32	width		= (deUint32)deFloatSqrt((float)texelCount);
    915 		const deUint32	height		= texelCount / width;
    916 
    917 		currentSize[0] = deMaxu32(width, height);
    918 		currentSize[1] = deMinu32(width, height);
    919 	}
    920 
    921 	for (deInt32 stepSize = currentSize[0] / 2; currentSize[0] > 0; stepSize /= 2)
    922 	{
    923 		const vk::VkImageCreateInfo	createInfo		=
    924 		{
    925 			vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
    926 			DE_NULL,
    927 
    928 			0u,
    929 			vk::VK_IMAGE_TYPE_2D,
    930 			vk::VK_FORMAT_R8G8B8A8_UNORM,
    931 			{
    932 				(deUint32)currentSize[0],
    933 				(deUint32)currentSize[1],
    934 				1u,
    935 			},
    936 			1u, 1u,
    937 			vk::VK_SAMPLE_COUNT_1_BIT,
    938 			vk::VK_IMAGE_TILING_OPTIMAL,
    939 			usage,
    940 			sharingMode,
    941 			(deUint32)queueFamilies.size(),
    942 			&queueFamilies[0],
    943 			vk::VK_IMAGE_LAYOUT_UNDEFINED
    944 		};
    945 		const vk::Unique<vk::VkImage>	image			(vk::createImage(vkd, device, &createInfo));
    946 		const vk::VkMemoryRequirements	requirements	(vk::getImageMemoryRequirements(vkd, device, *image));
    947 
    948 		if (requirements.size <= memorySize && requirements.memoryTypeBits & (0x1u << memoryTypeIndex))
    949 		{
    950 			lastSuccess = currentSize;
    951 			currentSize[0] += stepSize;
    952 			currentSize[1] += stepSize;
    953 		}
    954 		else
    955 		{
    956 			currentSize[0] -= stepSize;
    957 			currentSize[1] -= stepSize;
    958 		}
    959 
    960 		if (stepSize == 0)
    961 			break;
    962 	}
    963 
    964 	return lastSuccess;
    965 }
    966 
    967 Memory::Memory (const vk::InstanceInterface&	vki,
    968 				const vk::DeviceInterface&		vkd,
    969 				vk::VkPhysicalDevice			physicalDevice,
    970 				vk::VkDevice					device,
    971 				vk::VkDeviceSize				size,
    972 				deUint32						memoryTypeIndex,
    973 				vk::VkDeviceSize				maxBufferSize,
    974 				deInt32							maxImageWidth,
    975 				deInt32							maxImageHeight)
    976 	: m_size			(size)
    977 	, m_memoryTypeIndex	(memoryTypeIndex)
    978 	, m_memoryType		(getMemoryTypeInfo(vki, physicalDevice, memoryTypeIndex))
    979 	, m_memory			(allocMemory(vkd, device, size, memoryTypeIndex))
    980 	, m_maxBufferSize	(maxBufferSize)
    981 	, m_maxImageWidth	(maxImageWidth)
    982 	, m_maxImageHeight	(maxImageHeight)
    983 {
    984 }
    985 
    986 class Context
    987 {
    988 public:
    989 													Context					(const vk::InstanceInterface&					vki,
    990 																			 const vk::DeviceInterface&						vkd,
    991 																			 vk::VkPhysicalDevice							physicalDevice,
    992 																			 vk::VkDevice									device,
    993 																			 vk::VkQueue									queue,
    994 																			 deUint32										queueFamilyIndex,
    995 																			 const vector<pair<deUint32, vk::VkQueue> >&	queues,
    996 																			 const vk::BinaryCollection&					binaryCollection)
    997 		: m_vki					(vki)
    998 		, m_vkd					(vkd)
    999 		, m_physicalDevice		(physicalDevice)
   1000 		, m_device				(device)
   1001 		, m_queue				(queue)
   1002 		, m_queueFamilyIndex	(queueFamilyIndex)
   1003 		, m_queues				(queues)
   1004 		, m_commandPool			(createCommandPool(vkd, device, vk::VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex))
   1005 		, m_binaryCollection	(binaryCollection)
   1006 	{
   1007 		for (size_t queueNdx = 0; queueNdx < m_queues.size(); queueNdx++)
   1008 			m_queueFamilies.push_back(m_queues[queueNdx].first);
   1009 	}
   1010 
   1011 	const vk::InstanceInterface&					getInstanceInterface	(void) const { return m_vki; }
   1012 	vk::VkPhysicalDevice							getPhysicalDevice		(void) const { return m_physicalDevice; }
   1013 	vk::VkDevice									getDevice				(void) const { return m_device; }
   1014 	const vk::DeviceInterface&						getDeviceInterface		(void) const { return m_vkd; }
   1015 	vk::VkQueue										getQueue				(void) const { return m_queue; }
   1016 	deUint32										getQueueFamily			(void) const { return m_queueFamilyIndex; }
   1017 	const vector<pair<deUint32, vk::VkQueue> >&		getQueues				(void) const { return m_queues; }
   1018 	const vector<deUint32>							getQueueFamilies		(void) const { return m_queueFamilies; }
   1019 	vk::VkCommandPool								getCommandPool			(void) const { return *m_commandPool; }
   1020 	const vk::BinaryCollection&						getBinaryCollection		(void) const { return m_binaryCollection; }
   1021 
   1022 private:
   1023 	const vk::InstanceInterface&					m_vki;
   1024 	const vk::DeviceInterface&						m_vkd;
   1025 	const vk::VkPhysicalDevice						m_physicalDevice;
   1026 	const vk::VkDevice								m_device;
   1027 	const vk::VkQueue								m_queue;
   1028 	const deUint32									m_queueFamilyIndex;
   1029 	const vector<pair<deUint32, vk::VkQueue> >		m_queues;
   1030 	const vk::Unique<vk::VkCommandPool>				m_commandPool;
   1031 	const vk::BinaryCollection&						m_binaryCollection;
   1032 	vector<deUint32>								m_queueFamilies;
   1033 };
   1034 
   1035 class PrepareContext
   1036 {
   1037 public:
   1038 													PrepareContext			(const Context&	context,
   1039 																			 const Memory&	memory)
   1040 		: m_context	(context)
   1041 		, m_memory	(memory)
   1042 	{
   1043 	}
   1044 
   1045 	const Memory&									getMemory				(void) const { return m_memory; }
   1046 	const Context&									getContext				(void) const { return m_context; }
   1047 	const vk::BinaryCollection&						getBinaryCollection		(void) const { return m_context.getBinaryCollection(); }
   1048 
   1049 	void				setBuffer		(vk::Move<vk::VkBuffer>	buffer,
   1050 										 vk::VkDeviceSize		size)
   1051 	{
   1052 		DE_ASSERT(!m_currentImage);
   1053 		DE_ASSERT(!m_currentBuffer);
   1054 
   1055 		m_currentBuffer		= buffer;
   1056 		m_currentBufferSize	= size;
   1057 	}
   1058 
   1059 	vk::VkBuffer		getBuffer		(void) const { return *m_currentBuffer; }
   1060 	vk::VkDeviceSize	getBufferSize	(void) const
   1061 	{
   1062 		DE_ASSERT(m_currentBuffer);
   1063 		return m_currentBufferSize;
   1064 	}
   1065 
   1066 	void				releaseBuffer	(void) { m_currentBuffer.disown(); }
   1067 
   1068 	void				setImage		(vk::Move<vk::VkImage>	image,
   1069 										 vk::VkImageLayout		layout,
   1070 										 vk::VkDeviceSize		memorySize,
   1071 										 deInt32				width,
   1072 										 deInt32				height)
   1073 	{
   1074 		DE_ASSERT(!m_currentImage);
   1075 		DE_ASSERT(!m_currentBuffer);
   1076 
   1077 		m_currentImage				= image;
   1078 		m_currentImageMemorySize	= memorySize;
   1079 		m_currentImageLayout		= layout;
   1080 		m_currentImageWidth			= width;
   1081 		m_currentImageHeight		= height;
   1082 	}
   1083 
   1084 	void				setImageLayout	(vk::VkImageLayout layout)
   1085 	{
   1086 		DE_ASSERT(m_currentImage);
   1087 		m_currentImageLayout = layout;
   1088 	}
   1089 
   1090 	vk::VkImage			getImage		(void) const { return *m_currentImage; }
   1091 	deInt32				getImageWidth	(void) const
   1092 	{
   1093 		DE_ASSERT(m_currentImage);
   1094 		return m_currentImageWidth;
   1095 	}
   1096 	deInt32				getImageHeight	(void) const
   1097 	{
   1098 		DE_ASSERT(m_currentImage);
   1099 		return m_currentImageHeight;
   1100 	}
   1101 	vk::VkDeviceSize	getImageMemorySize	(void) const
   1102 	{
   1103 		DE_ASSERT(m_currentImage);
   1104 		return m_currentImageMemorySize;
   1105 	}
   1106 
   1107 	void				releaseImage	(void) { m_currentImage.disown(); }
   1108 
   1109 	vk::VkImageLayout	getImageLayout	(void) const
   1110 	{
   1111 		DE_ASSERT(m_currentImage);
   1112 		return m_currentImageLayout;
   1113 	}
   1114 
   1115 private:
   1116 	const Context&			m_context;
   1117 	const Memory&			m_memory;
   1118 
   1119 	vk::Move<vk::VkBuffer>	m_currentBuffer;
   1120 	vk::VkDeviceSize		m_currentBufferSize;
   1121 
   1122 	vk::Move<vk::VkImage>	m_currentImage;
   1123 	vk::VkDeviceSize		m_currentImageMemorySize;
   1124 	vk::VkImageLayout		m_currentImageLayout;
   1125 	deInt32					m_currentImageWidth;
   1126 	deInt32					m_currentImageHeight;
   1127 };
   1128 
   1129 class ExecuteContext
   1130 {
   1131 public:
   1132 					ExecuteContext	(const Context&	context)
   1133 		: m_context	(context)
   1134 	{
   1135 	}
   1136 
   1137 	const Context&	getContext		(void) const { return m_context; }
   1138 	void			setMapping		(void* ptr) { m_mapping = ptr; }
   1139 	void*			getMapping		(void) const { return m_mapping; }
   1140 
   1141 private:
   1142 	const Context&	m_context;
   1143 	void*			m_mapping;
   1144 };
   1145 
   1146 class VerifyContext
   1147 {
   1148 public:
   1149 							VerifyContext		(TestLog&				log,
   1150 												 tcu::ResultCollector&	resultCollector,
   1151 												 const Context&			context,
   1152 												 vk::VkDeviceSize		size)
   1153 		: m_log				(log)
   1154 		, m_resultCollector	(resultCollector)
   1155 		, m_context			(context)
   1156 		, m_reference		((size_t)size)
   1157 	{
   1158 	}
   1159 
   1160 	const Context&			getContext			(void) const { return m_context; }
   1161 	TestLog&				getLog				(void) const { return m_log; }
   1162 	tcu::ResultCollector&	getResultCollector	(void) const { return m_resultCollector; }
   1163 
   1164 	ReferenceMemory&		getReference		(void) { return m_reference; }
   1165 	TextureLevel&			getReferenceImage	(void) { return m_referenceImage;}
   1166 
   1167 private:
   1168 	TestLog&				m_log;
   1169 	tcu::ResultCollector&	m_resultCollector;
   1170 	const Context&			m_context;
   1171 	ReferenceMemory			m_reference;
   1172 	TextureLevel			m_referenceImage;
   1173 };
   1174 
   1175 class Command
   1176 {
   1177 public:
   1178 	// Constructor should allocate all non-vulkan resources.
   1179 	virtual				~Command	(void) {}
   1180 
   1181 	// Get name of the command
   1182 	virtual const char*	getName		(void) const = 0;
   1183 
   1184 	// Log prepare operations
   1185 	virtual void		logPrepare	(TestLog&, size_t) const {}
   1186 	// Log executed operations
   1187 	virtual void		logExecute	(TestLog&, size_t) const {}
   1188 
   1189 	// Prepare should allocate all vulkan resources and resources that require
   1190 	// that buffer or memory has been already allocated. This should build all
   1191 	// command buffers etc.
   1192 	virtual void		prepare		(PrepareContext&) {}
   1193 
   1194 	// Execute command. Write or read mapped memory, submit commands to queue
   1195 	// etc.
   1196 	virtual void		execute		(ExecuteContext&) {}
   1197 
   1198 	// Verify that results are correct.
   1199 	virtual void		verify		(VerifyContext&, size_t) {}
   1200 
   1201 protected:
   1202 	// Allow only inheritance
   1203 						Command		(void) {}
   1204 
   1205 private:
   1206 	// Disallow copying
   1207 						Command		(const Command&);
   1208 	Command&			operator&	(const Command&);
   1209 };
   1210 
   1211 class Map : public Command
   1212 {
   1213 public:
   1214 						Map			(void) {}
   1215 						~Map		(void) {}
   1216 	const char*			getName		(void) const { return "Map"; }
   1217 
   1218 
   1219 	void				logExecute	(TestLog& log, size_t commandIndex) const
   1220 	{
   1221 		log << TestLog::Message << commandIndex << ":" << getName() << " Map memory" << TestLog::EndMessage;
   1222 	}
   1223 
   1224 	void				prepare		(PrepareContext& context)
   1225 	{
   1226 		m_memory	= context.getMemory().getMemory();
   1227 		m_size		= context.getMemory().getSize();
   1228 	}
   1229 
   1230 	void				execute		(ExecuteContext& context)
   1231 	{
   1232 		const vk::DeviceInterface&	vkd		= context.getContext().getDeviceInterface();
   1233 		const vk::VkDevice			device	= context.getContext().getDevice();
   1234 
   1235 		context.setMapping(mapMemory(vkd, device, m_memory, m_size));
   1236 	}
   1237 
   1238 private:
   1239 	vk::VkDeviceMemory	m_memory;
   1240 	vk::VkDeviceSize	m_size;
   1241 };
   1242 
   1243 class UnMap : public Command
   1244 {
   1245 public:
   1246 						UnMap		(void) {}
   1247 						~UnMap		(void) {}
   1248 	const char*			getName		(void) const { return "UnMap"; }
   1249 
   1250 	void				logExecute	(TestLog& log, size_t commandIndex) const
   1251 	{
   1252 		log << TestLog::Message << commandIndex << ": Unmap memory" << TestLog::EndMessage;
   1253 	}
   1254 
   1255 	void				prepare		(PrepareContext& context)
   1256 	{
   1257 		m_memory	= context.getMemory().getMemory();
   1258 	}
   1259 
   1260 	void				execute		(ExecuteContext& context)
   1261 	{
   1262 		const vk::DeviceInterface&	vkd		= context.getContext().getDeviceInterface();
   1263 		const vk::VkDevice			device	= context.getContext().getDevice();
   1264 
   1265 		vkd.unmapMemory(device, m_memory);
   1266 		context.setMapping(DE_NULL);
   1267 	}
   1268 
   1269 private:
   1270 	vk::VkDeviceMemory	m_memory;
   1271 };
   1272 
   1273 class Invalidate : public Command
   1274 {
   1275 public:
   1276 						Invalidate	(void) {}
   1277 						~Invalidate	(void) {}
   1278 	const char*			getName		(void) const { return "Invalidate"; }
   1279 
   1280 	void				logExecute	(TestLog& log, size_t commandIndex) const
   1281 	{
   1282 		log << TestLog::Message << commandIndex << ": Invalidate mapped memory" << TestLog::EndMessage;
   1283 	}
   1284 
   1285 	void				prepare		(PrepareContext& context)
   1286 	{
   1287 		m_memory	= context.getMemory().getMemory();
   1288 		m_size		= context.getMemory().getSize();
   1289 	}
   1290 
   1291 	void				execute		(ExecuteContext& context)
   1292 	{
   1293 		const vk::DeviceInterface&	vkd		= context.getContext().getDeviceInterface();
   1294 		const vk::VkDevice			device	= context.getContext().getDevice();
   1295 
   1296 		vk::invalidateMappedMemoryRange(vkd, device, m_memory, 0, m_size);
   1297 	}
   1298 
   1299 private:
   1300 	vk::VkDeviceMemory	m_memory;
   1301 	vk::VkDeviceSize	m_size;
   1302 };
   1303 
   1304 class Flush : public Command
   1305 {
   1306 public:
   1307 						Flush		(void) {}
   1308 						~Flush		(void) {}
   1309 	const char*			getName		(void) const { return "Flush"; }
   1310 
   1311 	void				logExecute	(TestLog& log, size_t commandIndex) const
   1312 	{
   1313 		log << TestLog::Message << commandIndex << ": Flush mapped memory" << TestLog::EndMessage;
   1314 	}
   1315 
   1316 	void				prepare		(PrepareContext& context)
   1317 	{
   1318 		m_memory	= context.getMemory().getMemory();
   1319 		m_size		= context.getMemory().getSize();
   1320 	}
   1321 
   1322 	void				execute		(ExecuteContext& context)
   1323 	{
   1324 		const vk::DeviceInterface&	vkd		= context.getContext().getDeviceInterface();
   1325 		const vk::VkDevice			device	= context.getContext().getDevice();
   1326 
   1327 		vk::flushMappedMemoryRange(vkd, device, m_memory, 0, m_size);
   1328 	}
   1329 
   1330 private:
   1331 	vk::VkDeviceMemory	m_memory;
   1332 	vk::VkDeviceSize	m_size;
   1333 };
   1334 
   1335 // Host memory reads and writes
   1336 class HostMemoryAccess : public Command
   1337 {
   1338 public:
   1339 					HostMemoryAccess	(bool read, bool write, deUint32 seed);
   1340 					~HostMemoryAccess	(void) {}
   1341 	const char*		getName				(void) const { return "HostMemoryAccess"; }
   1342 
   1343 	void			logExecute			(TestLog& log, size_t commandIndex) const;
   1344 	void			prepare				(PrepareContext& context);
   1345 	void			execute				(ExecuteContext& context);
   1346 	void			verify				(VerifyContext& context, size_t commandIndex);
   1347 
   1348 private:
   1349 	const bool		m_read;
   1350 	const bool		m_write;
   1351 	const deUint32	m_seed;
   1352 
   1353 	size_t			m_size;
   1354 	vector<deUint8>	m_readData;
   1355 };
   1356 
   1357 HostMemoryAccess::HostMemoryAccess (bool read, bool write, deUint32 seed)
   1358 	: m_read	(read)
   1359 	, m_write	(write)
   1360 	, m_seed	(seed)
   1361 {
   1362 }
   1363 
   1364 void HostMemoryAccess::logExecute (TestLog& log, size_t commandIndex) const
   1365 {
   1366 	log << TestLog::Message << commandIndex << ": Host memory access:" << (m_read ? " read" : "") << (m_write ? " write" : "")  << ", seed: " << m_seed << TestLog::EndMessage;
   1367 }
   1368 
   1369 void HostMemoryAccess::prepare (PrepareContext& context)
   1370 {
   1371 	m_size = (size_t)context.getMemory().getSize();
   1372 
   1373 	if (m_read)
   1374 		m_readData.resize(m_size, 0);
   1375 }
   1376 
   1377 void HostMemoryAccess::execute (ExecuteContext& context)
   1378 {
   1379 	de::Random		rng	(m_seed);
   1380 	deUint8* const	ptr	= (deUint8*)context.getMapping();
   1381 
   1382 	if (m_read && m_write)
   1383 	{
   1384 		for (size_t pos = 0; pos < m_size; pos++)
   1385 		{
   1386 			const deUint8	mask	= rng.getUint8();
   1387 			const deUint8	value	= ptr[pos];
   1388 
   1389 			m_readData[pos] = value;
   1390 			ptr[pos] = value ^ mask;
   1391 		}
   1392 	}
   1393 	else if (m_read)
   1394 	{
   1395 		for (size_t pos = 0; pos < m_size; pos++)
   1396 		{
   1397 			const deUint8	value	= ptr[pos];
   1398 
   1399 			m_readData[pos] = value;
   1400 		}
   1401 	}
   1402 	else if (m_write)
   1403 	{
   1404 		for (size_t pos = 0; pos < m_size; pos++)
   1405 		{
   1406 			const deUint8	value	= rng.getUint8();
   1407 
   1408 			ptr[pos] = value;
   1409 		}
   1410 	}
   1411 	else
   1412 		DE_FATAL("Host memory access without read or write.");
   1413 }
   1414 
   1415 void HostMemoryAccess::verify (VerifyContext& context, size_t commandIndex)
   1416 {
   1417 	tcu::ResultCollector&	resultCollector	= context.getResultCollector();
   1418 	ReferenceMemory&		reference		= context.getReference();
   1419 	de::Random				rng				(m_seed);
   1420 
   1421 	if (m_read && m_write)
   1422 	{
   1423 		for (size_t pos = 0; pos < m_size; pos++)
   1424 		{
   1425 			const deUint8	mask	= rng.getUint8();
   1426 			const deUint8	value	= m_readData[pos];
   1427 
   1428 			if (reference.isDefined(pos))
   1429 			{
   1430 				if (value != reference.get(pos))
   1431 				{
   1432 					resultCollector.fail(
   1433 							de::toString(commandIndex) + ":" + getName()
   1434 							+ " Result differs from reference, Expected: "
   1435 							+ de::toString(tcu::toHex<8>(reference.get(pos)))
   1436 							+ ", Got: "
   1437 							+ de::toString(tcu::toHex<8>(value))
   1438 							+ ", At offset: "
   1439 							+ de::toString(pos));
   1440 					break;
   1441 				}
   1442 
   1443 				reference.set(pos, reference.get(pos) ^ mask);
   1444 			}
   1445 		}
   1446 	}
   1447 	else if (m_read)
   1448 	{
   1449 		for (size_t pos = 0; pos < m_size; pos++)
   1450 		{
   1451 			const deUint8	value	= m_readData[pos];
   1452 
   1453 			if (reference.isDefined(pos))
   1454 			{
   1455 				if (value != reference.get(pos))
   1456 				{
   1457 					resultCollector.fail(
   1458 							de::toString(commandIndex) + ":" + getName()
   1459 							+ " Result differs from reference, Expected: "
   1460 							+ de::toString(tcu::toHex<8>(reference.get(pos)))
   1461 							+ ", Got: "
   1462 							+ de::toString(tcu::toHex<8>(value))
   1463 							+ ", At offset: "
   1464 							+ de::toString(pos));
   1465 					break;
   1466 				}
   1467 			}
   1468 		}
   1469 	}
   1470 	else if (m_write)
   1471 	{
   1472 		for (size_t pos = 0; pos < m_size; pos++)
   1473 		{
   1474 			const deUint8	value	= rng.getUint8();
   1475 
   1476 			reference.set(pos, value);
   1477 		}
   1478 	}
   1479 	else
   1480 		DE_FATAL("Host memory access without read or write.");
   1481 }
   1482 
   1483 class CreateBuffer : public Command
   1484 {
   1485 public:
   1486 									CreateBuffer	(vk::VkBufferUsageFlags	usage,
   1487 													 vk::VkSharingMode		sharing);
   1488 									~CreateBuffer	(void) {}
   1489 	const char*						getName			(void) const { return "CreateBuffer"; }
   1490 
   1491 	void							logPrepare		(TestLog& log, size_t commandIndex) const;
   1492 	void							prepare			(PrepareContext& context);
   1493 
   1494 private:
   1495 	const vk::VkBufferUsageFlags	m_usage;
   1496 	const vk::VkSharingMode			m_sharing;
   1497 };
   1498 
   1499 CreateBuffer::CreateBuffer (vk::VkBufferUsageFlags	usage,
   1500 							vk::VkSharingMode		sharing)
   1501 	: m_usage	(usage)
   1502 	, m_sharing	(sharing)
   1503 {
   1504 }
   1505 
   1506 void CreateBuffer::logPrepare (TestLog& log, size_t commandIndex) const
   1507 {
   1508 	log << TestLog::Message << commandIndex << ":" << getName() << " Create buffer, Sharing mode: " << m_sharing << ", Usage: " << vk::getBufferUsageFlagsStr(m_usage) << TestLog::EndMessage;
   1509 }
   1510 
   1511 void CreateBuffer::prepare (PrepareContext& context)
   1512 {
   1513 	const vk::DeviceInterface&	vkd				= context.getContext().getDeviceInterface();
   1514 	const vk::VkDevice			device			= context.getContext().getDevice();
   1515 	const vk::VkDeviceSize		bufferSize		= context.getMemory().getMaxBufferSize();
   1516 	const vector<deUint32>&		queueFamilies	= context.getContext().getQueueFamilies();
   1517 
   1518 	context.setBuffer(createBuffer(vkd, device, bufferSize, m_usage, m_sharing, queueFamilies), bufferSize);
   1519 }
   1520 
   1521 class DestroyBuffer : public Command
   1522 {
   1523 public:
   1524 							DestroyBuffer	(void);
   1525 							~DestroyBuffer	(void) {}
   1526 	const char*				getName			(void) const { return "DestroyBuffer"; }
   1527 
   1528 	void					logExecute		(TestLog& log, size_t commandIndex) const;
   1529 	void					prepare			(PrepareContext& context);
   1530 	void					execute			(ExecuteContext& context);
   1531 
   1532 private:
   1533 	vk::Move<vk::VkBuffer>	m_buffer;
   1534 };
   1535 
   1536 DestroyBuffer::DestroyBuffer (void)
   1537 {
   1538 }
   1539 
   1540 void DestroyBuffer::prepare (PrepareContext& context)
   1541 {
   1542 	m_buffer = vk::Move<vk::VkBuffer>(vk::check(context.getBuffer()), vk::Deleter<vk::VkBuffer>(context.getContext().getDeviceInterface(), context.getContext().getDevice(), DE_NULL));
   1543 	context.releaseBuffer();
   1544 }
   1545 
   1546 void DestroyBuffer::logExecute (TestLog& log, size_t commandIndex) const
   1547 {
   1548 	log << TestLog::Message << commandIndex << ":" << getName() << " Destroy buffer" << TestLog::EndMessage;
   1549 }
   1550 
   1551 void DestroyBuffer::execute (ExecuteContext& context)
   1552 {
   1553 	const vk::DeviceInterface&	vkd				= context.getContext().getDeviceInterface();
   1554 	const vk::VkDevice			device			= context.getContext().getDevice();
   1555 
   1556 	vkd.destroyBuffer(device, m_buffer.disown(), DE_NULL);
   1557 }
   1558 
   1559 class BindBufferMemory : public Command
   1560 {
   1561 public:
   1562 				BindBufferMemory	(void) {}
   1563 				~BindBufferMemory	(void) {}
   1564 	const char*	getName				(void) const { return "BindBufferMemory"; }
   1565 
   1566 	void		logPrepare			(TestLog& log, size_t commandIndex) const;
   1567 	void		prepare				(PrepareContext& context);
   1568 };
   1569 
   1570 void BindBufferMemory::logPrepare (TestLog& log, size_t commandIndex) const
   1571 {
   1572 	log << TestLog::Message << commandIndex << ":" << getName() << " Bind memory to buffer" << TestLog::EndMessage;
   1573 }
   1574 
   1575 void BindBufferMemory::prepare (PrepareContext& context)
   1576 {
   1577 	const vk::DeviceInterface&	vkd				= context.getContext().getDeviceInterface();
   1578 	const vk::VkDevice			device			= context.getContext().getDevice();
   1579 
   1580 	VK_CHECK(vkd.bindBufferMemory(device, context.getBuffer(), context.getMemory().getMemory(), 0));
   1581 }
   1582 
   1583 class CreateImage : public Command
   1584 {
   1585 public:
   1586 									CreateImage		(vk::VkImageUsageFlags	usage,
   1587 													 vk::VkSharingMode		sharing);
   1588 									~CreateImage	(void) {}
   1589 	const char*						getName			(void) const { return "CreateImage"; }
   1590 
   1591 	void							logPrepare		(TestLog& log, size_t commandIndex) const;
   1592 	void							prepare			(PrepareContext& context);
   1593 	void							verify			(VerifyContext& context, size_t commandIndex);
   1594 
   1595 private:
   1596 	const vk::VkImageUsageFlags	m_usage;
   1597 	const vk::VkSharingMode		m_sharing;
   1598 	deInt32						m_imageWidth;
   1599 	deInt32						m_imageHeight;
   1600 };
   1601 
   1602 CreateImage::CreateImage (vk::VkImageUsageFlags	usage,
   1603 						  vk::VkSharingMode		sharing)
   1604 	: m_usage	(usage)
   1605 	, m_sharing	(sharing)
   1606 {
   1607 }
   1608 
   1609 void CreateImage::logPrepare (TestLog& log, size_t commandIndex) const
   1610 {
   1611 	log << TestLog::Message << commandIndex << ":" << getName() << " Create image, sharing: " << m_sharing << ", usage: " << vk::getImageUsageFlagsStr(m_usage)  << TestLog::EndMessage;
   1612 }
   1613 
   1614 void CreateImage::prepare (PrepareContext& context)
   1615 {
   1616 	const vk::DeviceInterface&	vkd				= context.getContext().getDeviceInterface();
   1617 	const vk::VkDevice			device			= context.getContext().getDevice();
   1618 	const vector<deUint32>&		queueFamilies	= context.getContext().getQueueFamilies();
   1619 
   1620 	m_imageWidth	= context.getMemory().getMaxImageWidth();
   1621 	m_imageHeight	= context.getMemory().getMaxImageHeight();
   1622 
   1623 	{
   1624 		const vk::VkImageCreateInfo	createInfo		=
   1625 		{
   1626 			vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
   1627 			DE_NULL,
   1628 
   1629 			0u,
   1630 			vk::VK_IMAGE_TYPE_2D,
   1631 			vk::VK_FORMAT_R8G8B8A8_UNORM,
   1632 			{
   1633 				(deUint32)m_imageWidth,
   1634 				(deUint32)m_imageHeight,
   1635 				1u,
   1636 			},
   1637 			1u, 1u,
   1638 			vk::VK_SAMPLE_COUNT_1_BIT,
   1639 			vk::VK_IMAGE_TILING_OPTIMAL,
   1640 			m_usage,
   1641 			m_sharing,
   1642 			(deUint32)queueFamilies.size(),
   1643 			&queueFamilies[0],
   1644 			vk::VK_IMAGE_LAYOUT_UNDEFINED
   1645 		};
   1646 		vk::Move<vk::VkImage>			image			(createImage(vkd, device, &createInfo));
   1647 		const vk::VkMemoryRequirements	requirements	= vk::getImageMemoryRequirements(vkd, device, *image);
   1648 
   1649 		context.setImage(image, vk::VK_IMAGE_LAYOUT_UNDEFINED, requirements.size, m_imageWidth, m_imageHeight);
   1650 	}
   1651 }
   1652 
   1653 void CreateImage::verify (VerifyContext& context, size_t)
   1654 {
   1655 	context.getReferenceImage() = TextureLevel(TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8), m_imageWidth, m_imageHeight);
   1656 }
   1657 
   1658 class DestroyImage : public Command
   1659 {
   1660 public:
   1661 							DestroyImage	(void);
   1662 							~DestroyImage	(void) {}
   1663 	const char*				getName			(void) const { return "DestroyImage"; }
   1664 
   1665 	void					logExecute		(TestLog& log, size_t commandIndex) const;
   1666 	void					prepare			(PrepareContext& context);
   1667 	void					execute			(ExecuteContext& context);
   1668 
   1669 private:
   1670 	vk::Move<vk::VkImage>	m_image;
   1671 };
   1672 
   1673 DestroyImage::DestroyImage (void)
   1674 {
   1675 }
   1676 
   1677 void DestroyImage::prepare (PrepareContext& context)
   1678 {
   1679 	m_image = vk::Move<vk::VkImage>(vk::check(context.getImage()), vk::Deleter<vk::VkImage>(context.getContext().getDeviceInterface(), context.getContext().getDevice(), DE_NULL));
   1680 	context.releaseImage();
   1681 }
   1682 
   1683 
   1684 void DestroyImage::logExecute (TestLog& log, size_t commandIndex) const
   1685 {
   1686 	log << TestLog::Message << commandIndex << ":" << getName() << " Destroy image" << TestLog::EndMessage;
   1687 }
   1688 
   1689 void DestroyImage::execute (ExecuteContext& context)
   1690 {
   1691 	const vk::DeviceInterface&	vkd				= context.getContext().getDeviceInterface();
   1692 	const vk::VkDevice			device			= context.getContext().getDevice();
   1693 
   1694 	vkd.destroyImage(device, m_image.disown(), DE_NULL);
   1695 }
   1696 
   1697 class BindImageMemory : public Command
   1698 {
   1699 public:
   1700 				BindImageMemory		(void) {}
   1701 				~BindImageMemory	(void) {}
   1702 	const char*	getName				(void) const { return "BindImageMemory"; }
   1703 
   1704 	void		logPrepare			(TestLog& log, size_t commandIndex) const;
   1705 	void		prepare				(PrepareContext& context);
   1706 };
   1707 
   1708 void BindImageMemory::logPrepare (TestLog& log, size_t commandIndex) const
   1709 {
   1710 	log << TestLog::Message << commandIndex << ":" << getName() << " Bind memory to image" << TestLog::EndMessage;
   1711 }
   1712 
   1713 void BindImageMemory::prepare (PrepareContext& context)
   1714 {
   1715 	const vk::DeviceInterface&		vkd				= context.getContext().getDeviceInterface();
   1716 	const vk::VkDevice				device			= context.getContext().getDevice();
   1717 
   1718 	VK_CHECK(vkd.bindImageMemory(device, context.getImage(), context.getMemory().getMemory(), 0));
   1719 }
   1720 
   1721 class QueueWaitIdle : public Command
   1722 {
   1723 public:
   1724 				QueueWaitIdle	(void) {}
   1725 				~QueueWaitIdle	(void) {}
   1726 	const char*	getName			(void) const { return "QueuetWaitIdle"; }
   1727 
   1728 	void		logExecute		(TestLog& log, size_t commandIndex) const;
   1729 	void		execute			(ExecuteContext& context);
   1730 };
   1731 
   1732 void QueueWaitIdle::logExecute (TestLog& log, size_t commandIndex) const
   1733 {
   1734 	log << TestLog::Message << commandIndex << ":" << getName() << " Queue wait idle" << TestLog::EndMessage;
   1735 }
   1736 
   1737 void QueueWaitIdle::execute (ExecuteContext& context)
   1738 {
   1739 	const vk::DeviceInterface&	vkd		= context.getContext().getDeviceInterface();
   1740 	const vk::VkQueue			queue	= context.getContext().getQueue();
   1741 
   1742 	VK_CHECK(vkd.queueWaitIdle(queue));
   1743 }
   1744 
   1745 class DeviceWaitIdle : public Command
   1746 {
   1747 public:
   1748 				DeviceWaitIdle	(void) {}
   1749 				~DeviceWaitIdle	(void) {}
   1750 	const char*	getName			(void) const { return "DeviceWaitIdle"; }
   1751 
   1752 	void		logExecute		(TestLog& log, size_t commandIndex) const;
   1753 	void		execute			(ExecuteContext& context);
   1754 };
   1755 
   1756 void DeviceWaitIdle::logExecute (TestLog& log, size_t commandIndex) const
   1757 {
   1758 	log << TestLog::Message << commandIndex << ":" << getName() << " Device wait idle" << TestLog::EndMessage;
   1759 }
   1760 
   1761 void DeviceWaitIdle::execute (ExecuteContext& context)
   1762 {
   1763 	const vk::DeviceInterface&	vkd		= context.getContext().getDeviceInterface();
   1764 	const vk::VkDevice			device	= context.getContext().getDevice();
   1765 
   1766 	VK_CHECK(vkd.deviceWaitIdle(device));
   1767 }
   1768 
   1769 class SubmitContext
   1770 {
   1771 public:
   1772 								SubmitContext		(const PrepareContext&		context,
   1773 													 const vk::VkCommandBuffer	commandBuffer)
   1774 		: m_context			(context)
   1775 		, m_commandBuffer	(commandBuffer)
   1776 	{
   1777 	}
   1778 
   1779 	const Memory&				getMemory			(void) const { return m_context.getMemory(); }
   1780 	const Context&				getContext			(void) const { return m_context.getContext(); }
   1781 	vk::VkCommandBuffer			getCommandBuffer	(void) const { return m_commandBuffer; }
   1782 
   1783 	vk::VkBuffer				getBuffer			(void) const { return m_context.getBuffer(); }
   1784 	vk::VkDeviceSize			getBufferSize		(void) const { return m_context.getBufferSize(); }
   1785 
   1786 	vk::VkImage					getImage			(void) const { return m_context.getImage(); }
   1787 	deInt32						getImageWidth		(void) const { return m_context.getImageWidth(); }
   1788 	deInt32						getImageHeight		(void) const { return m_context.getImageHeight(); }
   1789 
   1790 private:
   1791 	const PrepareContext&		m_context;
   1792 	const vk::VkCommandBuffer	m_commandBuffer;
   1793 };
   1794 
   1795 class CmdCommand
   1796 {
   1797 public:
   1798 	virtual				~CmdCommand	(void) {}
   1799 	virtual const char*	getName		(void) const = 0;
   1800 
   1801 	// Log things that are done during prepare
   1802 	virtual void		logPrepare	(TestLog&, size_t) const {}
   1803 	// Log submitted calls etc.
   1804 	virtual void		logSubmit	(TestLog&, size_t) const {}
   1805 
   1806 	// Allocate vulkan resources and prepare for submit.
   1807 	virtual void		prepare		(PrepareContext&) {}
   1808 
   1809 	// Submit commands to command buffer.
   1810 	virtual void		submit		(SubmitContext&) {}
   1811 
   1812 	// Verify results
   1813 	virtual void		verify		(VerifyContext&, size_t) {}
   1814 };
   1815 
   1816 class SubmitCommandBuffer : public Command
   1817 {
   1818 public:
   1819 					SubmitCommandBuffer		(const vector<CmdCommand*>& commands);
   1820 					~SubmitCommandBuffer	(void);
   1821 
   1822 	const char*		getName					(void) const { return "SubmitCommandBuffer"; }
   1823 	void			logExecute				(TestLog& log, size_t commandIndex) const;
   1824 	void			logPrepare				(TestLog& log, size_t commandIndex) const;
   1825 
   1826 	// Allocate command buffer and submit commands to command buffer
   1827 	void			prepare					(PrepareContext& context);
   1828 	void			execute					(ExecuteContext& context);
   1829 
   1830 	// Verify that results are correct.
   1831 	void			verify					(VerifyContext& context, size_t commandIndex);
   1832 
   1833 private:
   1834 	vector<CmdCommand*>				m_commands;
   1835 	vk::Move<vk::VkCommandBuffer>	m_commandBuffer;
   1836 };
   1837 
   1838 SubmitCommandBuffer::SubmitCommandBuffer (const vector<CmdCommand*>& commands)
   1839 	: m_commands	(commands)
   1840 {
   1841 }
   1842 
   1843 SubmitCommandBuffer::~SubmitCommandBuffer (void)
   1844 {
   1845 	for (size_t cmdNdx = 0; cmdNdx < m_commands.size(); cmdNdx++)
   1846 		delete m_commands[cmdNdx];
   1847 }
   1848 
   1849 void SubmitCommandBuffer::prepare (PrepareContext& context)
   1850 {
   1851 	const vk::DeviceInterface&	vkd			= context.getContext().getDeviceInterface();
   1852 	const vk::VkDevice			device		= context.getContext().getDevice();
   1853 	const vk::VkCommandPool		commandPool	= context.getContext().getCommandPool();
   1854 
   1855 	m_commandBuffer = createBeginCommandBuffer(vkd, device, commandPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
   1856 
   1857 	for (size_t cmdNdx = 0; cmdNdx < m_commands.size(); cmdNdx++)
   1858 	{
   1859 		CmdCommand& command = *m_commands[cmdNdx];
   1860 
   1861 		command.prepare(context);
   1862 	}
   1863 
   1864 	{
   1865 		SubmitContext submitContext (context, *m_commandBuffer);
   1866 
   1867 		for (size_t cmdNdx = 0; cmdNdx < m_commands.size(); cmdNdx++)
   1868 		{
   1869 			CmdCommand& command = *m_commands[cmdNdx];
   1870 
   1871 			command.submit(submitContext);
   1872 		}
   1873 
   1874 		VK_CHECK(vkd.endCommandBuffer(*m_commandBuffer));
   1875 	}
   1876 }
   1877 
   1878 void SubmitCommandBuffer::execute (ExecuteContext& context)
   1879 {
   1880 	const vk::DeviceInterface&	vkd		= context.getContext().getDeviceInterface();
   1881 	const vk::VkCommandBuffer	cmd		= *m_commandBuffer;
   1882 	const vk::VkQueue			queue	= context.getContext().getQueue();
   1883 	const vk::VkSubmitInfo		submit	=
   1884 	{
   1885 		vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
   1886 		DE_NULL,
   1887 
   1888 		0,
   1889 		DE_NULL,
   1890 		(const vk::VkPipelineStageFlags*)DE_NULL,
   1891 
   1892 		1,
   1893 		&cmd,
   1894 
   1895 		0,
   1896 		DE_NULL
   1897 	};
   1898 
   1899 	vkd.queueSubmit(queue, 1, &submit, 0);
   1900 }
   1901 
   1902 void SubmitCommandBuffer::verify (VerifyContext& context, size_t commandIndex)
   1903 {
   1904 	const string				sectionName	(de::toString(commandIndex) + ":" + getName());
   1905 	const tcu::ScopedLogSection	section		(context.getLog(), sectionName, sectionName);
   1906 
   1907 	for (size_t cmdNdx = 0; cmdNdx < m_commands.size(); cmdNdx++)
   1908 		m_commands[cmdNdx]->verify(context, cmdNdx);
   1909 }
   1910 
   1911 void SubmitCommandBuffer::logPrepare (TestLog& log, size_t commandIndex) const
   1912 {
   1913 	const string				sectionName	(de::toString(commandIndex) + ":" + getName());
   1914 	const tcu::ScopedLogSection	section		(log, sectionName, sectionName);
   1915 
   1916 	for (size_t cmdNdx = 0; cmdNdx < m_commands.size(); cmdNdx++)
   1917 		m_commands[cmdNdx]->logPrepare(log, cmdNdx);
   1918 }
   1919 
   1920 void SubmitCommandBuffer::logExecute (TestLog& log, size_t commandIndex) const
   1921 {
   1922 	const string				sectionName	(de::toString(commandIndex) + ":" + getName());
   1923 	const tcu::ScopedLogSection	section		(log, sectionName, sectionName);
   1924 
   1925 	for (size_t cmdNdx = 0; cmdNdx < m_commands.size(); cmdNdx++)
   1926 		m_commands[cmdNdx]->logSubmit(log, cmdNdx);
   1927 }
   1928 
   1929 class PipelineBarrier : public CmdCommand
   1930 {
   1931 public:
   1932 	enum Type
   1933 	{
   1934 		TYPE_GLOBAL = 0,
   1935 		TYPE_BUFFER,
   1936 		TYPE_IMAGE,
   1937 		TYPE_LAST
   1938 	};
   1939 									PipelineBarrier		(const vk::VkPipelineStageFlags			srcStages,
   1940 														 const vk::VkAccessFlags				srcAccesses,
   1941 														 const vk::VkPipelineStageFlags			dstStages,
   1942 														 const vk::VkAccessFlags				dstAccesses,
   1943 														 Type									type,
   1944 														 const tcu::Maybe<vk::VkImageLayout>	imageLayout);
   1945 									~PipelineBarrier	(void) {}
   1946 	const char*						getName				(void) const { return "PipelineBarrier"; }
   1947 
   1948 	void							logSubmit			(TestLog& log, size_t commandIndex) const;
   1949 	void							submit				(SubmitContext& context);
   1950 
   1951 private:
   1952 	const vk::VkPipelineStageFlags		m_srcStages;
   1953 	const vk::VkAccessFlags				m_srcAccesses;
   1954 	const vk::VkPipelineStageFlags		m_dstStages;
   1955 	const vk::VkAccessFlags				m_dstAccesses;
   1956 	const Type							m_type;
   1957 	const tcu::Maybe<vk::VkImageLayout>	m_imageLayout;
   1958 };
   1959 
   1960 PipelineBarrier::PipelineBarrier (const vk::VkPipelineStageFlags		srcStages,
   1961 								  const vk::VkAccessFlags				srcAccesses,
   1962 								  const vk::VkPipelineStageFlags		dstStages,
   1963 								  const vk::VkAccessFlags				dstAccesses,
   1964 								  Type									type,
   1965 								  const tcu::Maybe<vk::VkImageLayout>	imageLayout)
   1966 	: m_srcStages	(srcStages)
   1967 	, m_srcAccesses	(srcAccesses)
   1968 	, m_dstStages	(dstStages)
   1969 	, m_dstAccesses	(dstAccesses)
   1970 	, m_type		(type)
   1971 	, m_imageLayout	(imageLayout)
   1972 {
   1973 }
   1974 
   1975 void PipelineBarrier::logSubmit (TestLog& log, size_t commandIndex) const
   1976 {
   1977 	log << TestLog::Message << commandIndex << ":" << getName()
   1978 		<< " " << (m_type == TYPE_GLOBAL ? "Global pipeline barrier"
   1979 					: m_type == TYPE_BUFFER ? "Buffer pipeline barrier"
   1980 					: "Image pipeline barrier")
   1981 		<< ", srcStages: " << vk::getPipelineStageFlagsStr(m_srcStages) << ", srcAccesses: " << vk::getAccessFlagsStr(m_srcAccesses)
   1982 		<< ", dstStages: " << vk::getPipelineStageFlagsStr(m_dstStages) << ", dstAccesses: " << vk::getAccessFlagsStr(m_dstAccesses) << TestLog::EndMessage;
   1983 }
   1984 
   1985 void PipelineBarrier::submit (SubmitContext& context)
   1986 {
   1987 	const vk::DeviceInterface&	vkd	= context.getContext().getDeviceInterface();
   1988 	const vk::VkCommandBuffer	cmd	= context.getCommandBuffer();
   1989 
   1990 	switch (m_type)
   1991 	{
   1992 		case TYPE_GLOBAL:
   1993 		{
   1994 			const vk::VkMemoryBarrier	barrier		=
   1995 			{
   1996 				vk::VK_STRUCTURE_TYPE_MEMORY_BARRIER,
   1997 				DE_NULL,
   1998 
   1999 				m_srcAccesses,
   2000 				m_dstAccesses
   2001 			};
   2002 
   2003 			vkd.cmdPipelineBarrier(cmd, m_srcStages, m_dstStages, (vk::VkDependencyFlags)0, 1, &barrier, 0, (const vk::VkBufferMemoryBarrier*)DE_NULL, 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
   2004 			break;
   2005 		}
   2006 
   2007 		case TYPE_BUFFER:
   2008 		{
   2009 			const vk::VkBufferMemoryBarrier	barrier		=
   2010 			{
   2011 				vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
   2012 				DE_NULL,
   2013 
   2014 				m_srcAccesses,
   2015 				m_dstAccesses,
   2016 
   2017 				VK_QUEUE_FAMILY_IGNORED,
   2018 				VK_QUEUE_FAMILY_IGNORED,
   2019 
   2020 				context.getBuffer(),
   2021 				0,
   2022 				VK_WHOLE_SIZE
   2023 			};
   2024 
   2025 			vkd.cmdPipelineBarrier(cmd, m_srcStages, m_dstStages, (vk::VkDependencyFlags)0, 0, (const vk::VkMemoryBarrier*)DE_NULL, 1, &barrier, 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
   2026 			break;
   2027 		}
   2028 
   2029 		case TYPE_IMAGE:
   2030 		{
   2031 			const vk::VkImageMemoryBarrier	barrier		=
   2032 			{
   2033 				vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
   2034 				DE_NULL,
   2035 
   2036 				m_srcAccesses,
   2037 				m_dstAccesses,
   2038 
   2039 				*m_imageLayout,
   2040 				*m_imageLayout,
   2041 
   2042 				VK_QUEUE_FAMILY_IGNORED,
   2043 				VK_QUEUE_FAMILY_IGNORED,
   2044 
   2045 				context.getImage(),
   2046 				{
   2047 					vk::VK_IMAGE_ASPECT_COLOR_BIT,
   2048 					0, 1,
   2049 					0, 1
   2050 				}
   2051 			};
   2052 
   2053 			vkd.cmdPipelineBarrier(cmd, m_srcStages, m_dstStages, (vk::VkDependencyFlags)0, 0, (const vk::VkMemoryBarrier*)DE_NULL, 0, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1, &barrier);
   2054 			break;
   2055 		}
   2056 
   2057 		default:
   2058 			DE_FATAL("Unknown pipeline barrier type");
   2059 	}
   2060 }
   2061 
   2062 class ImageTransition : public CmdCommand
   2063 {
   2064 public:
   2065 						ImageTransition		(vk::VkPipelineStageFlags	srcStages,
   2066 											 vk::VkAccessFlags			srcAccesses,
   2067 
   2068 											 vk::VkPipelineStageFlags	dstStages,
   2069 											 vk::VkAccessFlags			dstAccesses,
   2070 
   2071 											 vk::VkImageLayout			srcLayout,
   2072 											 vk::VkImageLayout			dstLayout);
   2073 
   2074 						~ImageTransition	(void) {}
   2075 	const char*			getName				(void) const { return "ImageTransition"; }
   2076 
   2077 	void				prepare				(PrepareContext& context);
   2078 	void				logSubmit			(TestLog& log, size_t commandIndex) const;
   2079 	void				submit				(SubmitContext& context);
   2080 	void				verify				(VerifyContext& context, size_t);
   2081 
   2082 private:
   2083 	const vk::VkPipelineStageFlags	m_srcStages;
   2084 	const vk::VkAccessFlags			m_srcAccesses;
   2085 	const vk::VkPipelineStageFlags	m_dstStages;
   2086 	const vk::VkAccessFlags			m_dstAccesses;
   2087 	const vk::VkImageLayout			m_srcLayout;
   2088 	const vk::VkImageLayout			m_dstLayout;
   2089 
   2090 	vk::VkDeviceSize				m_imageMemorySize;
   2091 };
   2092 
   2093 ImageTransition::ImageTransition (vk::VkPipelineStageFlags	srcStages,
   2094 								  vk::VkAccessFlags			srcAccesses,
   2095 
   2096 								  vk::VkPipelineStageFlags	dstStages,
   2097 								  vk::VkAccessFlags			dstAccesses,
   2098 
   2099 								  vk::VkImageLayout			srcLayout,
   2100 								  vk::VkImageLayout			dstLayout)
   2101 	: m_srcStages		(srcStages)
   2102 	, m_srcAccesses		(srcAccesses)
   2103 	, m_dstStages		(dstStages)
   2104 	, m_dstAccesses		(dstAccesses)
   2105 	, m_srcLayout		(srcLayout)
   2106 	, m_dstLayout		(dstLayout)
   2107 {
   2108 }
   2109 
   2110 void ImageTransition::logSubmit (TestLog& log, size_t commandIndex) const
   2111 {
   2112 	log << TestLog::Message << commandIndex << ":" << getName()
   2113 		<< " Image transition pipeline barrier"
   2114 		<< ", srcStages: " << vk::getPipelineStageFlagsStr(m_srcStages) << ", srcAccesses: " << vk::getAccessFlagsStr(m_srcAccesses)
   2115 		<< ", dstStages: " << vk::getPipelineStageFlagsStr(m_dstStages) << ", dstAccesses: " << vk::getAccessFlagsStr(m_dstAccesses)
   2116 		<< ", srcLayout: " << m_srcLayout << ", dstLayout: " << m_dstLayout << TestLog::EndMessage;
   2117 }
   2118 
   2119 void ImageTransition::prepare (PrepareContext& context)
   2120 {
   2121 	DE_ASSERT(context.getImageLayout() == vk::VK_IMAGE_LAYOUT_UNDEFINED || m_srcLayout == vk::VK_IMAGE_LAYOUT_UNDEFINED || context.getImageLayout() == m_srcLayout);
   2122 
   2123 	context.setImageLayout(m_dstLayout);
   2124 	m_imageMemorySize = context.getImageMemorySize();
   2125 }
   2126 
   2127 void ImageTransition::submit (SubmitContext& context)
   2128 {
   2129 	const vk::DeviceInterface&		vkd			= context.getContext().getDeviceInterface();
   2130 	const vk::VkCommandBuffer		cmd			= context.getCommandBuffer();
   2131 	const vk::VkImageMemoryBarrier	barrier		=
   2132 	{
   2133 		vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
   2134 		DE_NULL,
   2135 
   2136 		m_srcAccesses,
   2137 		m_dstAccesses,
   2138 
   2139 		m_srcLayout,
   2140 		m_dstLayout,
   2141 
   2142 		VK_QUEUE_FAMILY_IGNORED,
   2143 		VK_QUEUE_FAMILY_IGNORED,
   2144 
   2145 		context.getImage(),
   2146 		{
   2147 			vk::VK_IMAGE_ASPECT_COLOR_BIT,
   2148 			0u, 1u,
   2149 			0u, 1u
   2150 		}
   2151 	};
   2152 
   2153 	vkd.cmdPipelineBarrier(cmd, m_srcStages, m_dstStages, (vk::VkDependencyFlags)0, 0, (const vk::VkMemoryBarrier*)DE_NULL, 0, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1, &barrier);
   2154 }
   2155 
   2156 void ImageTransition::verify (VerifyContext& context, size_t)
   2157 {
   2158 	context.getReference().setUndefined(0, (size_t)m_imageMemorySize);
   2159 }
   2160 
   2161 class FillBuffer : public CmdCommand
   2162 {
   2163 public:
   2164 						FillBuffer	(deUint32 value) : m_value(value) {}
   2165 						~FillBuffer	(void) {}
   2166 	const char*			getName		(void) const { return "FillBuffer"; }
   2167 
   2168 	void				logSubmit	(TestLog& log, size_t commandIndex) const;
   2169 	void				submit		(SubmitContext& context);
   2170 	void				verify		(VerifyContext& context, size_t commandIndex);
   2171 
   2172 private:
   2173 	const deUint32		m_value;
   2174 	vk::VkDeviceSize	m_bufferSize;
   2175 };
   2176 
   2177 void FillBuffer::logSubmit (TestLog& log, size_t commandIndex) const
   2178 {
   2179 	log << TestLog::Message << commandIndex << ":" << getName() << " Fill value: " << m_value << TestLog::EndMessage;
   2180 }
   2181 
   2182 void FillBuffer::submit (SubmitContext& context)
   2183 {
   2184 	const vk::DeviceInterface&	vkd			= context.getContext().getDeviceInterface();
   2185 	const vk::VkCommandBuffer	cmd			= context.getCommandBuffer();
   2186 	const vk::VkBuffer			buffer		= context.getBuffer();
   2187 	const vk::VkDeviceSize		sizeMask	= ~(0x3ull); // \note Round down to multiple of 4
   2188 
   2189 	m_bufferSize = sizeMask & context.getBufferSize();
   2190 	vkd.cmdFillBuffer(cmd, buffer, 0, m_bufferSize, m_value);
   2191 }
   2192 
   2193 void FillBuffer::verify (VerifyContext& context, size_t)
   2194 {
   2195 	ReferenceMemory&	reference	= context.getReference();
   2196 
   2197 	for (size_t ndx = 0; ndx < m_bufferSize; ndx++)
   2198 	{
   2199 #if (DE_ENDIANNESS == DE_LITTLE_ENDIAN)
   2200 		reference.set(ndx, (deUint8)(0xffu & (m_value >> (8*(ndx % 4)))));
   2201 #else
   2202 		reference.set(ndx, (deUint8)(0xffu & (m_value >> (8*(3 - (ndx % 4))))));
   2203 #endif
   2204 	}
   2205 }
   2206 
   2207 class UpdateBuffer : public CmdCommand
   2208 {
   2209 public:
   2210 						UpdateBuffer	(deUint32 seed) : m_seed(seed) {}
   2211 						~UpdateBuffer	(void) {}
   2212 	const char*			getName			(void) const { return "UpdateBuffer"; }
   2213 
   2214 	void				logSubmit		(TestLog& log, size_t commandIndex) const;
   2215 	void				submit			(SubmitContext& context);
   2216 	void				verify			(VerifyContext& context, size_t commandIndex);
   2217 
   2218 private:
   2219 	const deUint32		m_seed;
   2220 	vk::VkDeviceSize	m_bufferSize;
   2221 };
   2222 
   2223 void UpdateBuffer::logSubmit (TestLog& log, size_t commandIndex) const
   2224 {
   2225 	log << TestLog::Message << commandIndex << ":" << getName() << " Update buffer, seed: " << m_seed << TestLog::EndMessage;
   2226 }
   2227 
   2228 void UpdateBuffer::submit (SubmitContext& context)
   2229 {
   2230 	const vk::DeviceInterface&	vkd			= context.getContext().getDeviceInterface();
   2231 	const vk::VkCommandBuffer	cmd			= context.getCommandBuffer();
   2232 	const vk::VkBuffer			buffer		= context.getBuffer();
   2233 	const size_t				blockSize	= 65536;
   2234 	std::vector<deUint8>		data		(blockSize, 0);
   2235 	de::Random					rng			(m_seed);
   2236 
   2237 	m_bufferSize = context.getBufferSize();
   2238 
   2239 	for (size_t updated = 0; updated < m_bufferSize; updated += blockSize)
   2240 	{
   2241 		for (size_t ndx = 0; ndx < data.size(); ndx++)
   2242 			data[ndx] = rng.getUint8();
   2243 
   2244 		if (m_bufferSize - updated > blockSize)
   2245 			vkd.cmdUpdateBuffer(cmd, buffer, updated, blockSize, (const deUint32*)(&data[0]));
   2246 		else
   2247 			vkd.cmdUpdateBuffer(cmd, buffer, updated, m_bufferSize - updated, (const deUint32*)(&data[0]));
   2248 	}
   2249 }
   2250 
   2251 void UpdateBuffer::verify (VerifyContext& context, size_t)
   2252 {
   2253 	ReferenceMemory&	reference	= context.getReference();
   2254 	const size_t		blockSize	= 65536;
   2255 	vector<deUint8>		data		(blockSize, 0);
   2256 	de::Random			rng			(m_seed);
   2257 
   2258 	for (size_t updated = 0; updated < m_bufferSize; updated += blockSize)
   2259 	{
   2260 		for (size_t ndx = 0; ndx < data.size(); ndx++)
   2261 			data[ndx] = rng.getUint8();
   2262 
   2263 		if (m_bufferSize - updated > blockSize)
   2264 			reference.setData(updated, blockSize, &data[0]);
   2265 		else
   2266 			reference.setData(updated, (size_t)(m_bufferSize - updated), &data[0]);
   2267 	}
   2268 }
   2269 
   2270 class BufferCopyToBuffer : public CmdCommand
   2271 {
   2272 public:
   2273 									BufferCopyToBuffer	(void) {}
   2274 									~BufferCopyToBuffer	(void) {}
   2275 	const char*						getName				(void) const { return "BufferCopyToBuffer"; }
   2276 
   2277 	void							logPrepare			(TestLog& log, size_t commandIndex) const;
   2278 	void							prepare				(PrepareContext& context);
   2279 	void							logSubmit			(TestLog& log, size_t commandIndex) const;
   2280 	void							submit				(SubmitContext& context);
   2281 	void							verify				(VerifyContext& context, size_t commandIndex);
   2282 
   2283 private:
   2284 	vk::VkDeviceSize				m_bufferSize;
   2285 	vk::Move<vk::VkBuffer>			m_dstBuffer;
   2286 	vk::Move<vk::VkDeviceMemory>	m_memory;
   2287 };
   2288 
   2289 void BufferCopyToBuffer::logPrepare (TestLog& log, size_t commandIndex) const
   2290 {
   2291 	log << TestLog::Message << commandIndex << ":" << getName() << " Allocate destination buffer for buffer to buffer copy." << TestLog::EndMessage;
   2292 }
   2293 
   2294 void BufferCopyToBuffer::prepare (PrepareContext& context)
   2295 {
   2296 	const vk::InstanceInterface&	vki				= context.getContext().getInstanceInterface();
   2297 	const vk::DeviceInterface&		vkd				= context.getContext().getDeviceInterface();
   2298 	const vk::VkPhysicalDevice		physicalDevice	= context.getContext().getPhysicalDevice();
   2299 	const vk::VkDevice				device			= context.getContext().getDevice();
   2300 	const vector<deUint32>&			queueFamilies	= context.getContext().getQueueFamilies();
   2301 
   2302 	m_bufferSize = context.getBufferSize();
   2303 
   2304 	m_dstBuffer	= createBuffer(vkd, device, m_bufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT, vk::VK_SHARING_MODE_EXCLUSIVE, queueFamilies);
   2305 	m_memory	= bindBufferMemory(vki, vkd, physicalDevice, device, *m_dstBuffer, vk::VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
   2306 }
   2307 
   2308 void BufferCopyToBuffer::logSubmit (TestLog& log, size_t commandIndex) const
   2309 {
   2310 	log << TestLog::Message << commandIndex << ":" << getName() << " Copy buffer to another buffer" << TestLog::EndMessage;
   2311 }
   2312 
   2313 void BufferCopyToBuffer::submit (SubmitContext& context)
   2314 {
   2315 	const vk::DeviceInterface&	vkd				= context.getContext().getDeviceInterface();
   2316 	const vk::VkCommandBuffer	commandBuffer	= context.getCommandBuffer();
   2317 	const vk::VkBufferCopy		range			=
   2318 	{
   2319 		0, 0, // Offsets
   2320 		m_bufferSize
   2321 	};
   2322 
   2323 	vkd.cmdCopyBuffer(commandBuffer, context.getBuffer(), *m_dstBuffer, 1, &range);
   2324 }
   2325 
   2326 void BufferCopyToBuffer::verify (VerifyContext& context, size_t commandIndex)
   2327 {
   2328 	tcu::ResultCollector&					resultCollector	(context.getResultCollector());
   2329 	ReferenceMemory&						reference		(context.getReference());
   2330 	const vk::DeviceInterface&				vkd				= context.getContext().getDeviceInterface();
   2331 	const vk::VkDevice						device			= context.getContext().getDevice();
   2332 	const vk::VkQueue						queue			= context.getContext().getQueue();
   2333 	const vk::VkCommandPool					commandPool		= context.getContext().getCommandPool();
   2334 	const vk::Unique<vk::VkCommandBuffer>	commandBuffer	(createBeginCommandBuffer(vkd, device, commandPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
   2335 	const vk::VkBufferMemoryBarrier			barrier			=
   2336 	{
   2337 		vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
   2338 		DE_NULL,
   2339 
   2340 		vk::VK_ACCESS_TRANSFER_WRITE_BIT,
   2341 		vk::VK_ACCESS_HOST_READ_BIT,
   2342 
   2343 		VK_QUEUE_FAMILY_IGNORED,
   2344 		VK_QUEUE_FAMILY_IGNORED,
   2345 		*m_dstBuffer,
   2346 		0,
   2347 		VK_WHOLE_SIZE
   2348 	};
   2349 
   2350 	vkd.cmdPipelineBarrier(*commandBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, (vk::VkDependencyFlags)0, 0, (const vk::VkMemoryBarrier*)DE_NULL, 1, &barrier, 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
   2351 
   2352 	VK_CHECK(vkd.endCommandBuffer(*commandBuffer));
   2353 	queueRun(vkd, queue, *commandBuffer);
   2354 
   2355 	{
   2356 		void* const	ptr		= mapMemory(vkd, device, *m_memory, m_bufferSize);
   2357 		bool		isOk	= true;
   2358 
   2359 		vk::invalidateMappedMemoryRange(vkd, device, *m_memory, 0, m_bufferSize);
   2360 
   2361 		{
   2362 			const deUint8* const data = (const deUint8*)ptr;
   2363 
   2364 			for (size_t pos = 0; pos < (size_t)m_bufferSize; pos++)
   2365 			{
   2366 				if (reference.isDefined(pos))
   2367 				{
   2368 					if (data[pos] != reference.get(pos))
   2369 					{
   2370 						resultCollector.fail(
   2371 								de::toString(commandIndex) + ":" + getName()
   2372 								+ " Result differs from reference, Expected: "
   2373 								+ de::toString(tcu::toHex<8>(reference.get(pos)))
   2374 								+ ", Got: "
   2375 								+ de::toString(tcu::toHex<8>(data[pos]))
   2376 								+ ", At offset: "
   2377 								+ de::toString(pos));
   2378 						break;
   2379 					}
   2380 				}
   2381 			}
   2382 		}
   2383 
   2384 		vkd.unmapMemory(device, *m_memory);
   2385 
   2386 		if (!isOk)
   2387 			context.getLog() << TestLog::Message << commandIndex << ": Buffer copy to buffer verification failed" << TestLog::EndMessage;
   2388 	}
   2389 }
   2390 
   2391 class BufferCopyFromBuffer : public CmdCommand
   2392 {
   2393 public:
   2394 									BufferCopyFromBuffer	(deUint32 seed) : m_seed(seed) {}
   2395 									~BufferCopyFromBuffer	(void) {}
   2396 	const char*						getName					(void) const { return "BufferCopyFromBuffer"; }
   2397 
   2398 	void							logPrepare				(TestLog& log, size_t commandIndex) const;
   2399 	void							prepare					(PrepareContext& context);
   2400 	void							logSubmit				(TestLog& log, size_t commandIndex) const;
   2401 	void							submit					(SubmitContext& context);
   2402 	void							verify					(VerifyContext& context, size_t commandIndex);
   2403 
   2404 private:
   2405 	const deUint32					m_seed;
   2406 	vk::VkDeviceSize				m_bufferSize;
   2407 	vk::Move<vk::VkBuffer>			m_srcBuffer;
   2408 	vk::Move<vk::VkDeviceMemory>	m_memory;
   2409 };
   2410 
   2411 void BufferCopyFromBuffer::logPrepare (TestLog& log, size_t commandIndex) const
   2412 {
   2413 	log << TestLog::Message << commandIndex << ":" << getName() << " Allocate source buffer for buffer to buffer copy. Seed: " << m_seed << TestLog::EndMessage;
   2414 }
   2415 
   2416 void BufferCopyFromBuffer::prepare (PrepareContext& context)
   2417 {
   2418 	const vk::InstanceInterface&	vki				= context.getContext().getInstanceInterface();
   2419 	const vk::DeviceInterface&		vkd				= context.getContext().getDeviceInterface();
   2420 	const vk::VkPhysicalDevice		physicalDevice	= context.getContext().getPhysicalDevice();
   2421 	const vk::VkDevice				device			= context.getContext().getDevice();
   2422 	const vector<deUint32>&			queueFamilies	= context.getContext().getQueueFamilies();
   2423 
   2424 	m_bufferSize	= context.getBufferSize();
   2425 	m_srcBuffer		= createBuffer(vkd, device, m_bufferSize, vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT, vk::VK_SHARING_MODE_EXCLUSIVE, queueFamilies);
   2426 	m_memory		= bindBufferMemory(vki, vkd, physicalDevice, device, *m_srcBuffer, vk::VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
   2427 
   2428 	{
   2429 		void* const	ptr	= mapMemory(vkd, device, *m_memory, m_bufferSize);
   2430 		de::Random	rng	(m_seed);
   2431 
   2432 		{
   2433 			deUint8* const	data = (deUint8*)ptr;
   2434 
   2435 			for (size_t ndx = 0; ndx < (size_t)m_bufferSize; ndx++)
   2436 				data[ndx] = rng.getUint8();
   2437 		}
   2438 
   2439 		vk::flushMappedMemoryRange(vkd, device, *m_memory, 0, m_bufferSize);
   2440 		vkd.unmapMemory(device, *m_memory);
   2441 	}
   2442 }
   2443 
   2444 void BufferCopyFromBuffer::logSubmit (TestLog& log, size_t commandIndex) const
   2445 {
   2446 	log << TestLog::Message << commandIndex << ":" << getName() << " Copy buffer data from another buffer" << TestLog::EndMessage;
   2447 }
   2448 
   2449 void BufferCopyFromBuffer::submit (SubmitContext& context)
   2450 {
   2451 	const vk::DeviceInterface&	vkd				= context.getContext().getDeviceInterface();
   2452 	const vk::VkCommandBuffer	commandBuffer	= context.getCommandBuffer();
   2453 	const vk::VkBufferCopy		range			=
   2454 	{
   2455 		0, 0, // Offsets
   2456 		m_bufferSize
   2457 	};
   2458 
   2459 	vkd.cmdCopyBuffer(commandBuffer, *m_srcBuffer, context.getBuffer(), 1, &range);
   2460 }
   2461 
   2462 void BufferCopyFromBuffer::verify (VerifyContext& context, size_t)
   2463 {
   2464 	ReferenceMemory&	reference	(context.getReference());
   2465 	de::Random			rng			(m_seed);
   2466 
   2467 	for (size_t ndx = 0; ndx < (size_t)m_bufferSize; ndx++)
   2468 		reference.set(ndx, rng.getUint8());
   2469 }
   2470 
   2471 class BufferCopyToImage : public CmdCommand
   2472 {
   2473 public:
   2474 									BufferCopyToImage	(void) {}
   2475 									~BufferCopyToImage	(void) {}
   2476 	const char*						getName				(void) const { return "BufferCopyToImage"; }
   2477 
   2478 	void							logPrepare			(TestLog& log, size_t commandIndex) const;
   2479 	void							prepare				(PrepareContext& context);
   2480 	void							logSubmit			(TestLog& log, size_t commandIndex) const;
   2481 	void							submit				(SubmitContext& context);
   2482 	void							verify				(VerifyContext& context, size_t commandIndex);
   2483 
   2484 private:
   2485 	deInt32							m_imageWidth;
   2486 	deInt32							m_imageHeight;
   2487 	vk::Move<vk::VkImage>			m_dstImage;
   2488 	vk::Move<vk::VkDeviceMemory>	m_memory;
   2489 };
   2490 
   2491 void BufferCopyToImage::logPrepare (TestLog& log, size_t commandIndex) const
   2492 {
   2493 	log << TestLog::Message << commandIndex << ":" << getName() << " Allocate destination image for buffer to image copy." << TestLog::EndMessage;
   2494 }
   2495 
   2496 void BufferCopyToImage::prepare (PrepareContext& context)
   2497 {
   2498 	const vk::InstanceInterface&	vki				= context.getContext().getInstanceInterface();
   2499 	const vk::DeviceInterface&		vkd				= context.getContext().getDeviceInterface();
   2500 	const vk::VkPhysicalDevice		physicalDevice	= context.getContext().getPhysicalDevice();
   2501 	const vk::VkDevice				device			= context.getContext().getDevice();
   2502 	const vk::VkQueue				queue			= context.getContext().getQueue();
   2503 	const vk::VkCommandPool			commandPool		= context.getContext().getCommandPool();
   2504 	const vector<deUint32>&			queueFamilies	= context.getContext().getQueueFamilies();
   2505 	const IVec2						imageSize		= findImageSizeWxHx4(context.getBufferSize());
   2506 
   2507 	m_imageWidth	= imageSize[0];
   2508 	m_imageHeight	= imageSize[1];
   2509 
   2510 	{
   2511 		const vk::VkImageCreateInfo	createInfo =
   2512 		{
   2513 			vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
   2514 			DE_NULL,
   2515 
   2516 			0,
   2517 			vk::VK_IMAGE_TYPE_2D,
   2518 			vk::VK_FORMAT_R8G8B8A8_UNORM,
   2519 			{
   2520 				(deUint32)m_imageWidth,
   2521 				(deUint32)m_imageHeight,
   2522 				1u,
   2523 			},
   2524 			1, 1, // mipLevels, arrayLayers
   2525 			vk::VK_SAMPLE_COUNT_1_BIT,
   2526 
   2527 			vk::VK_IMAGE_TILING_OPTIMAL,
   2528 			vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT|vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
   2529 			vk::VK_SHARING_MODE_EXCLUSIVE,
   2530 
   2531 			(deUint32)queueFamilies.size(),
   2532 			&queueFamilies[0],
   2533 			vk::VK_IMAGE_LAYOUT_UNDEFINED
   2534 		};
   2535 
   2536 		m_dstImage = vk::createImage(vkd, device, &createInfo);
   2537 	}
   2538 
   2539 	m_memory = bindImageMemory(vki, vkd, physicalDevice, device, *m_dstImage, 0);
   2540 
   2541 	{
   2542 		const vk::Unique<vk::VkCommandBuffer>	commandBuffer	(createBeginCommandBuffer(vkd, device, commandPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
   2543 		const vk::VkImageMemoryBarrier			barrier			=
   2544 		{
   2545 			vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
   2546 			DE_NULL,
   2547 
   2548 			0,
   2549 			vk::VK_ACCESS_TRANSFER_WRITE_BIT,
   2550 
   2551 			vk::VK_IMAGE_LAYOUT_UNDEFINED,
   2552 			vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
   2553 
   2554 			VK_QUEUE_FAMILY_IGNORED,
   2555 			VK_QUEUE_FAMILY_IGNORED,
   2556 
   2557 			*m_dstImage,
   2558 			{
   2559 				vk::VK_IMAGE_ASPECT_COLOR_BIT,
   2560 				0,	// Mip level
   2561 				1,	// Mip level count
   2562 				0,	// Layer
   2563 				1	// Layer count
   2564 			}
   2565 		};
   2566 
   2567 		vkd.cmdPipelineBarrier(*commandBuffer, vk::VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0, 0, (const vk::VkMemoryBarrier*)DE_NULL, 0, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1, &barrier);
   2568 
   2569 		VK_CHECK(vkd.endCommandBuffer(*commandBuffer));
   2570 		queueRun(vkd, queue, *commandBuffer);
   2571 	}
   2572 }
   2573 
   2574 void BufferCopyToImage::logSubmit (TestLog& log, size_t commandIndex) const
   2575 {
   2576 	log << TestLog::Message << commandIndex << ":" << getName() << " Copy buffer to image" << TestLog::EndMessage;
   2577 }
   2578 
   2579 void BufferCopyToImage::submit (SubmitContext& context)
   2580 {
   2581 	const vk::DeviceInterface&	vkd				= context.getContext().getDeviceInterface();
   2582 	const vk::VkCommandBuffer	commandBuffer	= context.getCommandBuffer();
   2583 	const vk::VkBufferImageCopy	region			=
   2584 	{
   2585 		0,
   2586 		0, 0,
   2587 		{
   2588 			vk::VK_IMAGE_ASPECT_COLOR_BIT,
   2589 			0,	// mipLevel
   2590 			0,	// arrayLayer
   2591 			1	// layerCount
   2592 		},
   2593 		{ 0, 0, 0 },
   2594 		{
   2595 			(deUint32)m_imageWidth,
   2596 			(deUint32)m_imageHeight,
   2597 			1u
   2598 		}
   2599 	};
   2600 
   2601 	vkd.cmdCopyBufferToImage(commandBuffer, context.getBuffer(), *m_dstImage, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
   2602 }
   2603 
   2604 void BufferCopyToImage::verify (VerifyContext& context, size_t commandIndex)
   2605 {
   2606 	tcu::ResultCollector&					resultCollector	(context.getResultCollector());
   2607 	ReferenceMemory&						reference		(context.getReference());
   2608 	const vk::InstanceInterface&			vki				= context.getContext().getInstanceInterface();
   2609 	const vk::DeviceInterface&				vkd				= context.getContext().getDeviceInterface();
   2610 	const vk::VkPhysicalDevice				physicalDevice	= context.getContext().getPhysicalDevice();
   2611 	const vk::VkDevice						device			= context.getContext().getDevice();
   2612 	const vk::VkQueue						queue			= context.getContext().getQueue();
   2613 	const vk::VkCommandPool					commandPool		= context.getContext().getCommandPool();
   2614 	const vk::Unique<vk::VkCommandBuffer>	commandBuffer	(createBeginCommandBuffer(vkd, device, commandPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
   2615 	const vector<deUint32>&					queueFamilies	= context.getContext().getQueueFamilies();
   2616 	const vk::Unique<vk::VkBuffer>			dstBuffer		(createBuffer(vkd, device, 4 * m_imageWidth * m_imageHeight, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT, vk::VK_SHARING_MODE_EXCLUSIVE, queueFamilies));
   2617 	const vk::Unique<vk::VkDeviceMemory>	memory			(bindBufferMemory(vki, vkd, physicalDevice, device, *dstBuffer, vk::VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT));
   2618 	{
   2619 		const vk::VkImageMemoryBarrier		imageBarrier	=
   2620 		{
   2621 			vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
   2622 			DE_NULL,
   2623 
   2624 			vk::VK_ACCESS_TRANSFER_WRITE_BIT,
   2625 			vk::VK_ACCESS_TRANSFER_READ_BIT,
   2626 
   2627 			vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
   2628 			vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
   2629 
   2630 			VK_QUEUE_FAMILY_IGNORED,
   2631 			VK_QUEUE_FAMILY_IGNORED,
   2632 
   2633 			*m_dstImage,
   2634 			{
   2635 				vk::VK_IMAGE_ASPECT_COLOR_BIT,
   2636 				0,	// Mip level
   2637 				1,	// Mip level count
   2638 				0,	// Layer
   2639 				1	// Layer count
   2640 			}
   2641 		};
   2642 		const vk::VkBufferMemoryBarrier bufferBarrier =
   2643 		{
   2644 			vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
   2645 			DE_NULL,
   2646 
   2647 			vk::VK_ACCESS_TRANSFER_WRITE_BIT,
   2648 			vk::VK_ACCESS_HOST_READ_BIT,
   2649 
   2650 			VK_QUEUE_FAMILY_IGNORED,
   2651 			VK_QUEUE_FAMILY_IGNORED,
   2652 			*dstBuffer,
   2653 			0,
   2654 			VK_WHOLE_SIZE
   2655 		};
   2656 
   2657 		const vk::VkBufferImageCopy	region =
   2658 		{
   2659 			0,
   2660 			0, 0,
   2661 			{
   2662 				vk::VK_IMAGE_ASPECT_COLOR_BIT,
   2663 				0,	// mipLevel
   2664 				0,	// arrayLayer
   2665 				1	// layerCount
   2666 			},
   2667 			{ 0, 0, 0 },
   2668 			{
   2669 				(deUint32)m_imageWidth,
   2670 				(deUint32)m_imageHeight,
   2671 				1u
   2672 			}
   2673 		};
   2674 
   2675 		vkd.cmdPipelineBarrier(*commandBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0, 0, (const vk::VkMemoryBarrier*)DE_NULL, 0, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier);
   2676 		vkd.cmdCopyImageToBuffer(*commandBuffer, *m_dstImage, vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *dstBuffer, 1, &region);
   2677 		vkd.cmdPipelineBarrier(*commandBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, (vk::VkDependencyFlags)0, 0, (const vk::VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
   2678 	}
   2679 
   2680 	VK_CHECK(vkd.endCommandBuffer(*commandBuffer));
   2681 	queueRun(vkd, queue, *commandBuffer);
   2682 
   2683 	{
   2684 		void* const	ptr		= mapMemory(vkd, device, *memory, 4 * m_imageWidth * m_imageHeight);
   2685 
   2686 		vk::invalidateMappedMemoryRange(vkd, device, *memory, 0,  4 * m_imageWidth * m_imageHeight);
   2687 
   2688 		{
   2689 			const deUint8* const	data = (const deUint8*)ptr;
   2690 
   2691 			for (size_t pos = 0; pos < (size_t)( 4 * m_imageWidth * m_imageHeight); pos++)
   2692 			{
   2693 				if (reference.isDefined(pos))
   2694 				{
   2695 					if (data[pos] != reference.get(pos))
   2696 					{
   2697 						resultCollector.fail(
   2698 								de::toString(commandIndex) + ":" + getName()
   2699 								+ " Result differs from reference, Expected: "
   2700 								+ de::toString(tcu::toHex<8>(reference.get(pos)))
   2701 								+ ", Got: "
   2702 								+ de::toString(tcu::toHex<8>(data[pos]))
   2703 								+ ", At offset: "
   2704 								+ de::toString(pos));
   2705 						break;
   2706 					}
   2707 				}
   2708 			}
   2709 		}
   2710 
   2711 		vkd.unmapMemory(device, *memory);
   2712 	}
   2713 }
   2714 
   2715 class BufferCopyFromImage : public CmdCommand
   2716 {
   2717 public:
   2718 									BufferCopyFromImage		(deUint32 seed) : m_seed(seed) {}
   2719 									~BufferCopyFromImage	(void) {}
   2720 	const char*						getName					(void) const { return "BufferCopyFromImage"; }
   2721 
   2722 	void							logPrepare				(TestLog& log, size_t commandIndex) const;
   2723 	void							prepare					(PrepareContext& context);
   2724 	void							logSubmit				(TestLog& log, size_t commandIndex) const;
   2725 	void							submit					(SubmitContext& context);
   2726 	void							verify					(VerifyContext& context, size_t commandIndex);
   2727 
   2728 private:
   2729 	const deUint32					m_seed;
   2730 	deInt32							m_imageWidth;
   2731 	deInt32							m_imageHeight;
   2732 	vk::Move<vk::VkImage>			m_srcImage;
   2733 	vk::Move<vk::VkDeviceMemory>	m_memory;
   2734 };
   2735 
   2736 void BufferCopyFromImage::logPrepare (TestLog& log, size_t commandIndex) const
   2737 {
   2738 	log << TestLog::Message << commandIndex << ":" << getName() << " Allocate source image for image to buffer copy." << TestLog::EndMessage;
   2739 }
   2740 
   2741 void BufferCopyFromImage::prepare (PrepareContext& context)
   2742 {
   2743 	const vk::InstanceInterface&	vki				= context.getContext().getInstanceInterface();
   2744 	const vk::DeviceInterface&		vkd				= context.getContext().getDeviceInterface();
   2745 	const vk::VkPhysicalDevice		physicalDevice	= context.getContext().getPhysicalDevice();
   2746 	const vk::VkDevice				device			= context.getContext().getDevice();
   2747 	const vk::VkQueue				queue			= context.getContext().getQueue();
   2748 	const vk::VkCommandPool			commandPool		= context.getContext().getCommandPool();
   2749 	const vector<deUint32>&			queueFamilies	= context.getContext().getQueueFamilies();
   2750 	const IVec2						imageSize		= findImageSizeWxHx4(context.getBufferSize());
   2751 
   2752 	m_imageWidth	= imageSize[0];
   2753 	m_imageHeight	= imageSize[1];
   2754 
   2755 	{
   2756 		const vk::VkImageCreateInfo	createInfo =
   2757 		{
   2758 			vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
   2759 			DE_NULL,
   2760 
   2761 			0,
   2762 			vk::VK_IMAGE_TYPE_2D,
   2763 			vk::VK_FORMAT_R8G8B8A8_UNORM,
   2764 			{
   2765 				(deUint32)m_imageWidth,
   2766 				(deUint32)m_imageHeight,
   2767 				1u,
   2768 			},
   2769 			1, 1, // mipLevels, arrayLayers
   2770 			vk::VK_SAMPLE_COUNT_1_BIT,
   2771 
   2772 			vk::VK_IMAGE_TILING_OPTIMAL,
   2773 			vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT|vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
   2774 			vk::VK_SHARING_MODE_EXCLUSIVE,
   2775 
   2776 			(deUint32)queueFamilies.size(),
   2777 			&queueFamilies[0],
   2778 			vk::VK_IMAGE_LAYOUT_UNDEFINED
   2779 		};
   2780 
   2781 		m_srcImage = vk::createImage(vkd, device, &createInfo);
   2782 	}
   2783 
   2784 	m_memory = bindImageMemory(vki, vkd, physicalDevice, device, *m_srcImage, 0);
   2785 
   2786 	{
   2787 		const vk::Unique<vk::VkBuffer>			srcBuffer		(createBuffer(vkd, device, 4 * m_imageWidth * m_imageHeight, vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT, vk::VK_SHARING_MODE_EXCLUSIVE, queueFamilies));
   2788 		const vk::Unique<vk::VkDeviceMemory>	memory			(bindBufferMemory(vki, vkd, physicalDevice, device, *srcBuffer, vk::VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT));
   2789 		const vk::Unique<vk::VkCommandBuffer>	commandBuffer	(createBeginCommandBuffer(vkd, device, commandPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
   2790 		const vk::VkImageMemoryBarrier			preImageBarrier	=
   2791 		{
   2792 			vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
   2793 			DE_NULL,
   2794 
   2795 			0,
   2796 			vk::VK_ACCESS_TRANSFER_WRITE_BIT,
   2797 
   2798 			vk::VK_IMAGE_LAYOUT_UNDEFINED,
   2799 			vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
   2800 
   2801 			VK_QUEUE_FAMILY_IGNORED,
   2802 			VK_QUEUE_FAMILY_IGNORED,
   2803 
   2804 			*m_srcImage,
   2805 			{
   2806 				vk::VK_IMAGE_ASPECT_COLOR_BIT,
   2807 				0,	// Mip level
   2808 				1,	// Mip level count
   2809 				0,	// Layer
   2810 				1	// Layer count
   2811 			}
   2812 		};
   2813 		const vk::VkImageMemoryBarrier			postImageBarrier =
   2814 		{
   2815 			vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
   2816 			DE_NULL,
   2817 
   2818 			vk::VK_ACCESS_TRANSFER_WRITE_BIT,
   2819 			0,
   2820 
   2821 			vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
   2822 			vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
   2823 
   2824 			VK_QUEUE_FAMILY_IGNORED,
   2825 			VK_QUEUE_FAMILY_IGNORED,
   2826 
   2827 			*m_srcImage,
   2828 			{
   2829 				vk::VK_IMAGE_ASPECT_COLOR_BIT,
   2830 				0,	// Mip level
   2831 				1,	// Mip level count
   2832 				0,	// Layer
   2833 				1	// Layer count
   2834 			}
   2835 		};
   2836 		const vk::VkBufferImageCopy				region				=
   2837 		{
   2838 			0,
   2839 			0, 0,
   2840 			{
   2841 				vk::VK_IMAGE_ASPECT_COLOR_BIT,
   2842 				0,	// mipLevel
   2843 				0,	// arrayLayer
   2844 				1	// layerCount
   2845 			},
   2846 			{ 0, 0, 0 },
   2847 			{
   2848 				(deUint32)m_imageWidth,
   2849 				(deUint32)m_imageHeight,
   2850 				1u
   2851 			}
   2852 		};
   2853 
   2854 		{
   2855 			void* const	ptr	= mapMemory(vkd, device, *memory, 4 * m_imageWidth * m_imageHeight);
   2856 			de::Random	rng	(m_seed);
   2857 
   2858 			{
   2859 				deUint8* const	data = (deUint8*)ptr;
   2860 
   2861 				for (size_t ndx = 0; ndx < (size_t)(4 * m_imageWidth * m_imageHeight); ndx++)
   2862 					data[ndx] = rng.getUint8();
   2863 			}
   2864 
   2865 			vk::flushMappedMemoryRange(vkd, device, *memory, 0, 4 * m_imageWidth * m_imageHeight);
   2866 			vkd.unmapMemory(device, *memory);
   2867 		}
   2868 
   2869 		vkd.cmdPipelineBarrier(*commandBuffer, vk::VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0, 0, (const vk::VkMemoryBarrier*)DE_NULL, 0, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1, &preImageBarrier);
   2870 		vkd.cmdCopyBufferToImage(*commandBuffer, *srcBuffer, *m_srcImage, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
   2871 		vkd.cmdPipelineBarrier(*commandBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0, 0, (const vk::VkMemoryBarrier*)DE_NULL, 0, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
   2872 
   2873 		VK_CHECK(vkd.endCommandBuffer(*commandBuffer));
   2874 		queueRun(vkd, queue, *commandBuffer);
   2875 	}
   2876 }
   2877 
   2878 void BufferCopyFromImage::logSubmit (TestLog& log, size_t commandIndex) const
   2879 {
   2880 	log << TestLog::Message << commandIndex << ":" << getName() << " Copy buffer data from image" << TestLog::EndMessage;
   2881 }
   2882 
   2883 void BufferCopyFromImage::submit (SubmitContext& context)
   2884 {
   2885 	const vk::DeviceInterface&	vkd				= context.getContext().getDeviceInterface();
   2886 	const vk::VkCommandBuffer	commandBuffer	= context.getCommandBuffer();
   2887 	const vk::VkBufferImageCopy	region			=
   2888 	{
   2889 		0,
   2890 		0, 0,
   2891 		{
   2892 			vk::VK_IMAGE_ASPECT_COLOR_BIT,
   2893 			0,	// mipLevel
   2894 			0,	// arrayLayer
   2895 			1	// layerCount
   2896 		},
   2897 		{ 0, 0, 0 },
   2898 		{
   2899 			(deUint32)m_imageWidth,
   2900 			(deUint32)m_imageHeight,
   2901 			1u
   2902 		}
   2903 	};
   2904 
   2905 	vkd.cmdCopyImageToBuffer(commandBuffer, *m_srcImage, vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, context.getBuffer(), 1, &region);
   2906 }
   2907 
   2908 void BufferCopyFromImage::verify (VerifyContext& context, size_t)
   2909 {
   2910 	ReferenceMemory&	reference		(context.getReference());
   2911 	de::Random			rng	(m_seed);
   2912 
   2913 	for (size_t ndx = 0; ndx < (size_t)(4 * m_imageWidth * m_imageHeight); ndx++)
   2914 		reference.set(ndx, rng.getUint8());
   2915 }
   2916 
   2917 class ImageCopyToBuffer : public CmdCommand
   2918 {
   2919 public:
   2920 									ImageCopyToBuffer	(vk::VkImageLayout imageLayout) : m_imageLayout (imageLayout) {}
   2921 									~ImageCopyToBuffer	(void) {}
   2922 	const char*						getName				(void) const { return "BufferCopyToImage"; }
   2923 
   2924 	void							logPrepare			(TestLog& log, size_t commandIndex) const;
   2925 	void							prepare				(PrepareContext& context);
   2926 	void							logSubmit			(TestLog& log, size_t commandIndex) const;
   2927 	void							submit				(SubmitContext& context);
   2928 	void							verify				(VerifyContext& context, size_t commandIndex);
   2929 
   2930 private:
   2931 	vk::VkImageLayout				m_imageLayout;
   2932 	vk::VkDeviceSize				m_bufferSize;
   2933 	vk::Move<vk::VkBuffer>			m_dstBuffer;
   2934 	vk::Move<vk::VkDeviceMemory>	m_memory;
   2935 	vk::VkDeviceSize				m_imageMemorySize;
   2936 	deInt32							m_imageWidth;
   2937 	deInt32							m_imageHeight;
   2938 };
   2939 
   2940 void ImageCopyToBuffer::logPrepare (TestLog& log, size_t commandIndex) const
   2941 {
   2942 	log << TestLog::Message << commandIndex << ":" << getName() << " Allocate destination buffer for image to buffer copy." << TestLog::EndMessage;
   2943 }
   2944 
   2945 void ImageCopyToBuffer::prepare (PrepareContext& context)
   2946 {
   2947 	const vk::InstanceInterface&	vki				= context.getContext().getInstanceInterface();
   2948 	const vk::DeviceInterface&		vkd				= context.getContext().getDeviceInterface();
   2949 	const vk::VkPhysicalDevice		physicalDevice	= context.getContext().getPhysicalDevice();
   2950 	const vk::VkDevice				device			= context.getContext().getDevice();
   2951 	const vector<deUint32>&			queueFamilies	= context.getContext().getQueueFamilies();
   2952 
   2953 	m_imageWidth		= context.getImageWidth();
   2954 	m_imageHeight		= context.getImageHeight();
   2955 	m_bufferSize		= 4 * m_imageWidth * m_imageHeight;
   2956 	m_imageMemorySize	= context.getImageMemorySize();
   2957 	m_dstBuffer			= createBuffer(vkd, device, m_bufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT, vk::VK_SHARING_MODE_EXCLUSIVE, queueFamilies);
   2958 	m_memory			= bindBufferMemory(vki, vkd, physicalDevice, device, *m_dstBuffer, vk::VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
   2959 }
   2960 
   2961 void ImageCopyToBuffer::logSubmit (TestLog& log, size_t commandIndex) const
   2962 {
   2963 	log << TestLog::Message << commandIndex << ":" << getName() << " Copy image to buffer" << TestLog::EndMessage;
   2964 }
   2965 
   2966 void ImageCopyToBuffer::submit (SubmitContext& context)
   2967 {
   2968 	const vk::DeviceInterface&	vkd				= context.getContext().getDeviceInterface();
   2969 	const vk::VkCommandBuffer	commandBuffer	= context.getCommandBuffer();
   2970 	const vk::VkBufferImageCopy	region			=
   2971 	{
   2972 		0,
   2973 		0, 0,
   2974 		{
   2975 			vk::VK_IMAGE_ASPECT_COLOR_BIT,
   2976 			0,	// mipLevel
   2977 			0,	// arrayLayer
   2978 			1	// layerCount
   2979 		},
   2980 		{ 0, 0, 0 },
   2981 		{
   2982 			(deUint32)m_imageWidth,
   2983 			(deUint32)m_imageHeight,
   2984 			1u
   2985 		}
   2986 	};
   2987 
   2988 	vkd.cmdCopyImageToBuffer(commandBuffer, context.getImage(), m_imageLayout, *m_dstBuffer, 1, &region);
   2989 }
   2990 
   2991 void ImageCopyToBuffer::verify (VerifyContext& context, size_t commandIndex)
   2992 {
   2993 	tcu::ResultCollector&					resultCollector	(context.getResultCollector());
   2994 	ReferenceMemory&						reference		(context.getReference());
   2995 	const vk::DeviceInterface&				vkd				= context.getContext().getDeviceInterface();
   2996 	const vk::VkDevice						device			= context.getContext().getDevice();
   2997 	const vk::VkQueue						queue			= context.getContext().getQueue();
   2998 	const vk::VkCommandPool					commandPool		= context.getContext().getCommandPool();
   2999 	const vk::Unique<vk::VkCommandBuffer>	commandBuffer	(createBeginCommandBuffer(vkd, device, commandPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
   3000 	const vk::VkBufferMemoryBarrier			barrier			=
   3001 	{
   3002 		vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
   3003 		DE_NULL,
   3004 
   3005 		vk::VK_ACCESS_TRANSFER_WRITE_BIT,
   3006 		vk::VK_ACCESS_HOST_READ_BIT,
   3007 
   3008 		VK_QUEUE_FAMILY_IGNORED,
   3009 		VK_QUEUE_FAMILY_IGNORED,
   3010 		*m_dstBuffer,
   3011 		0,
   3012 		VK_WHOLE_SIZE
   3013 	};
   3014 
   3015 	vkd.cmdPipelineBarrier(*commandBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, (vk::VkDependencyFlags)0, 0, (const vk::VkMemoryBarrier*)DE_NULL, 1, &barrier, 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
   3016 
   3017 	VK_CHECK(vkd.endCommandBuffer(*commandBuffer));
   3018 	queueRun(vkd, queue, *commandBuffer);
   3019 
   3020 	reference.setUndefined(0, (size_t)m_imageMemorySize);
   3021 	{
   3022 		void* const						ptr				= mapMemory(vkd, device, *m_memory, m_bufferSize);
   3023 		const ConstPixelBufferAccess	referenceImage	(context.getReferenceImage().getAccess());
   3024 		const ConstPixelBufferAccess	resultImage		(TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8), m_imageWidth, m_imageHeight, 1, ptr);
   3025 
   3026 		vk::invalidateMappedMemoryRange(vkd, device, *m_memory, 0, m_bufferSize);
   3027 
   3028 		if (!tcu::intThresholdCompare(context.getLog(), (de::toString(commandIndex) + ":" + getName()).c_str(), (de::toString(commandIndex) + ":" + getName()).c_str(), referenceImage, resultImage, UVec4(0), tcu::COMPARE_LOG_ON_ERROR))
   3029 			resultCollector.fail(de::toString(commandIndex) + ":" + getName() + " Image comparison failed");
   3030 
   3031 		vkd.unmapMemory(device, *m_memory);
   3032 	}
   3033 }
   3034 
   3035 class ImageCopyFromBuffer : public CmdCommand
   3036 {
   3037 public:
   3038 									ImageCopyFromBuffer		(deUint32 seed, vk::VkImageLayout imageLayout) : m_seed(seed), m_imageLayout(imageLayout) {}
   3039 									~ImageCopyFromBuffer	(void) {}
   3040 	const char*						getName					(void) const { return "ImageCopyFromBuffer"; }
   3041 
   3042 	void							logPrepare				(TestLog& log, size_t commandIndex) const;
   3043 	void							prepare					(PrepareContext& context);
   3044 	void							logSubmit				(TestLog& log, size_t commandIndex) const;
   3045 	void							submit					(SubmitContext& context);
   3046 	void							verify					(VerifyContext& context, size_t commandIndex);
   3047 
   3048 private:
   3049 	const deUint32					m_seed;
   3050 	const vk::VkImageLayout			m_imageLayout;
   3051 	deInt32							m_imageWidth;
   3052 	deInt32							m_imageHeight;
   3053 	vk::VkDeviceSize				m_imageMemorySize;
   3054 	vk::VkDeviceSize				m_bufferSize;
   3055 	vk::Move<vk::VkBuffer>			m_srcBuffer;
   3056 	vk::Move<vk::VkDeviceMemory>	m_memory;
   3057 };
   3058 
   3059 void ImageCopyFromBuffer::logPrepare (TestLog& log, size_t commandIndex) const
   3060 {
   3061 	log << TestLog::Message << commandIndex << ":" << getName() << " Allocate source buffer for buffer to image copy. Seed: " << m_seed << TestLog::EndMessage;
   3062 }
   3063 
   3064 void ImageCopyFromBuffer::prepare (PrepareContext& context)
   3065 {
   3066 	const vk::InstanceInterface&	vki				= context.getContext().getInstanceInterface();
   3067 	const vk::DeviceInterface&		vkd				= context.getContext().getDeviceInterface();
   3068 	const vk::VkPhysicalDevice		physicalDevice	= context.getContext().getPhysicalDevice();
   3069 	const vk::VkDevice				device			= context.getContext().getDevice();
   3070 	const vector<deUint32>&			queueFamilies	= context.getContext().getQueueFamilies();
   3071 
   3072 	m_imageWidth		= context.getImageHeight();
   3073 	m_imageHeight		= context.getImageWidth();
   3074 	m_imageMemorySize	= context.getImageMemorySize();
   3075 	m_bufferSize		= m_imageWidth * m_imageHeight * 4;
   3076 	m_srcBuffer			= createBuffer(vkd, device, m_bufferSize, vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT, vk::VK_SHARING_MODE_EXCLUSIVE, queueFamilies);
   3077 	m_memory			= bindBufferMemory(vki, vkd, physicalDevice, device, *m_srcBuffer, vk::VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
   3078 
   3079 	{
   3080 		void* const	ptr	= mapMemory(vkd, device, *m_memory, m_bufferSize);
   3081 		de::Random	rng	(m_seed);
   3082 
   3083 		{
   3084 			deUint8* const	data = (deUint8*)ptr;
   3085 
   3086 			for (size_t ndx = 0; ndx < (size_t)m_bufferSize; ndx++)
   3087 				data[ndx] = rng.getUint8();
   3088 		}
   3089 
   3090 		vk::flushMappedMemoryRange(vkd, device, *m_memory, 0, m_bufferSize);
   3091 		vkd.unmapMemory(device, *m_memory);
   3092 	}
   3093 }
   3094 
   3095 void ImageCopyFromBuffer::logSubmit (TestLog& log, size_t commandIndex) const
   3096 {
   3097 	log << TestLog::Message << commandIndex << ":" << getName() << " Copy image data from buffer" << TestLog::EndMessage;
   3098 }
   3099 
   3100 void ImageCopyFromBuffer::submit (SubmitContext& context)
   3101 {
   3102 	const vk::DeviceInterface&	vkd				= context.getContext().getDeviceInterface();
   3103 	const vk::VkCommandBuffer	commandBuffer	= context.getCommandBuffer();
   3104 	const vk::VkBufferImageCopy	region			=
   3105 	{
   3106 		0,
   3107 		0, 0,
   3108 		{
   3109 			vk::VK_IMAGE_ASPECT_COLOR_BIT,
   3110 			0,	// mipLevel
   3111 			0,	// arrayLayer
   3112 			1	// layerCount
   3113 		},
   3114 		{ 0, 0, 0 },
   3115 		{
   3116 			(deUint32)m_imageWidth,
   3117 			(deUint32)m_imageHeight,
   3118 			1u
   3119 		}
   3120 	};
   3121 
   3122 	vkd.cmdCopyBufferToImage(commandBuffer, *m_srcBuffer, context.getImage(), m_imageLayout, 1, &region);
   3123 }
   3124 
   3125 void ImageCopyFromBuffer::verify (VerifyContext& context, size_t)
   3126 {
   3127 	ReferenceMemory&	reference	(context.getReference());
   3128 	de::Random			rng			(m_seed);
   3129 
   3130 	reference.setUndefined(0, (size_t)m_imageMemorySize);
   3131 
   3132 	{
   3133 		const PixelBufferAccess&	refAccess	(context.getReferenceImage().getAccess());
   3134 
   3135 		for (deInt32 y = 0; y < m_imageHeight; y++)
   3136 		for (deInt32 x = 0; x < m_imageWidth; x++)
   3137 		{
   3138 			const deUint8 r8 = rng.getUint8();
   3139 			const deUint8 g8 = rng.getUint8();
   3140 			const deUint8 b8 = rng.getUint8();
   3141 			const deUint8 a8 = rng.getUint8();
   3142 
   3143 			refAccess.setPixel(UVec4(r8, g8, b8, a8), x, y);
   3144 		}
   3145 	}
   3146 }
   3147 
   3148 class ImageCopyFromImage : public CmdCommand
   3149 {
   3150 public:
   3151 									ImageCopyFromImage	(deUint32 seed, vk::VkImageLayout imageLayout) : m_seed(seed), m_imageLayout(imageLayout) {}
   3152 									~ImageCopyFromImage	(void) {}
   3153 	const char*						getName				(void) const { return "ImageCopyFromImage"; }
   3154 
   3155 	void							logPrepare			(TestLog& log, size_t commandIndex) const;
   3156 	void							prepare				(PrepareContext& context);
   3157 	void							logSubmit			(TestLog& log, size_t commandIndex) const;
   3158 	void							submit				(SubmitContext& context);
   3159 	void							verify				(VerifyContext& context, size_t commandIndex);
   3160 
   3161 private:
   3162 	const deUint32					m_seed;
   3163 	const vk::VkImageLayout			m_imageLayout;
   3164 	deInt32							m_imageWidth;
   3165 	deInt32							m_imageHeight;
   3166 	vk::VkDeviceSize				m_imageMemorySize;
   3167 	vk::Move<vk::VkImage>			m_srcImage;
   3168 	vk::Move<vk::VkDeviceMemory>	m_memory;
   3169 };
   3170 
   3171 void ImageCopyFromImage::logPrepare (TestLog& log, size_t commandIndex) const
   3172 {
   3173 	log << TestLog::Message << commandIndex << ":" << getName() << " Allocate source image for image to image copy." << TestLog::EndMessage;
   3174 }
   3175 
   3176 void ImageCopyFromImage::prepare (PrepareContext& context)
   3177 {
   3178 	const vk::InstanceInterface&	vki				= context.getContext().getInstanceInterface();
   3179 	const vk::DeviceInterface&		vkd				= context.getContext().getDeviceInterface();
   3180 	const vk::VkPhysicalDevice		physicalDevice	= context.getContext().getPhysicalDevice();
   3181 	const vk::VkDevice				device			= context.getContext().getDevice();
   3182 	const vk::VkQueue				queue			= context.getContext().getQueue();
   3183 	const vk::VkCommandPool			commandPool		= context.getContext().getCommandPool();
   3184 	const vector<deUint32>&			queueFamilies	= context.getContext().getQueueFamilies();
   3185 
   3186 	m_imageWidth		= context.getImageWidth();
   3187 	m_imageHeight		= context.getImageHeight();
   3188 	m_imageMemorySize	= context.getImageMemorySize();
   3189 
   3190 	{
   3191 		const vk::VkImageCreateInfo	createInfo =
   3192 		{
   3193 			vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
   3194 			DE_NULL,
   3195 
   3196 			0,
   3197 			vk::VK_IMAGE_TYPE_2D,
   3198 			vk::VK_FORMAT_R8G8B8A8_UNORM,
   3199 			{
   3200 				(deUint32)m_imageWidth,
   3201 				(deUint32)m_imageHeight,
   3202 				1u,
   3203 			},
   3204 			1, 1, // mipLevels, arrayLayers
   3205 			vk::VK_SAMPLE_COUNT_1_BIT,
   3206 
   3207 			vk::VK_IMAGE_TILING_OPTIMAL,
   3208 			vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT|vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
   3209 			vk::VK_SHARING_MODE_EXCLUSIVE,
   3210 
   3211 			(deUint32)queueFamilies.size(),
   3212 			&queueFamilies[0],
   3213 			vk::VK_IMAGE_LAYOUT_UNDEFINED
   3214 		};
   3215 
   3216 		m_srcImage = vk::createImage(vkd, device, &createInfo);
   3217 	}
   3218 
   3219 	m_memory = bindImageMemory(vki, vkd, physicalDevice, device, *m_srcImage, 0);
   3220 
   3221 	{
   3222 		const vk::Unique<vk::VkBuffer>			srcBuffer		(createBuffer(vkd, device, 4 * m_imageWidth * m_imageHeight, vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT, vk::VK_SHARING_MODE_EXCLUSIVE, queueFamilies));
   3223 		const vk::Unique<vk::VkDeviceMemory>	memory			(bindBufferMemory(vki, vkd, physicalDevice, device, *srcBuffer, vk::VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT));
   3224 		const vk::Unique<vk::VkCommandBuffer>	commandBuffer	(createBeginCommandBuffer(vkd, device, commandPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
   3225 		const vk::VkImageMemoryBarrier			preImageBarrier	=
   3226 		{
   3227 			vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
   3228 			DE_NULL,
   3229 
   3230 			0,
   3231 			vk::VK_ACCESS_TRANSFER_WRITE_BIT,
   3232 
   3233 			vk::VK_IMAGE_LAYOUT_UNDEFINED,
   3234 			vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
   3235 
   3236 			VK_QUEUE_FAMILY_IGNORED,
   3237 			VK_QUEUE_FAMILY_IGNORED,
   3238 
   3239 			*m_srcImage,
   3240 			{
   3241 				vk::VK_IMAGE_ASPECT_COLOR_BIT,
   3242 				0,	// Mip level
   3243 				1,	// Mip level count
   3244 				0,	// Layer
   3245 				1	// Layer count
   3246 			}
   3247 		};
   3248 		const vk::VkImageMemoryBarrier			postImageBarrier =
   3249 		{
   3250 			vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
   3251 			DE_NULL,
   3252 
   3253 			vk::VK_ACCESS_TRANSFER_WRITE_BIT,
   3254 			0,
   3255 
   3256 			vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
   3257 			vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
   3258 
   3259 			VK_QUEUE_FAMILY_IGNORED,
   3260 			VK_QUEUE_FAMILY_IGNORED,
   3261 
   3262 			*m_srcImage,
   3263 			{
   3264 				vk::VK_IMAGE_ASPECT_COLOR_BIT,
   3265 				0,	// Mip level
   3266 				1,	// Mip level count
   3267 				0,	// Layer
   3268 				1	// Layer count
   3269 			}
   3270 		};
   3271 		const vk::VkBufferImageCopy				region				=
   3272 		{
   3273 			0,
   3274 			0, 0,
   3275 			{
   3276 				vk::VK_IMAGE_ASPECT_COLOR_BIT,
   3277 				0,	// mipLevel
   3278 				0,	// arrayLayer
   3279 				1	// layerCount
   3280 			},
   3281 			{ 0, 0, 0 },
   3282 			{
   3283 				(deUint32)m_imageWidth,
   3284 				(deUint32)m_imageHeight,
   3285 				1u
   3286 			}
   3287 		};
   3288 
   3289 		{
   3290 			void* const	ptr	= mapMemory(vkd, device, *memory, 4 * m_imageWidth * m_imageHeight);
   3291 			de::Random	rng	(m_seed);
   3292 
   3293 			{
   3294 				deUint8* const	data = (deUint8*)ptr;
   3295 
   3296 				for (size_t ndx = 0; ndx < (size_t)(4 * m_imageWidth * m_imageHeight); ndx++)
   3297 					data[ndx] = rng.getUint8();
   3298 			}
   3299 
   3300 			vk::flushMappedMemoryRange(vkd, device, *memory, 0, 4 * m_imageWidth * m_imageHeight);
   3301 			vkd.unmapMemory(device, *memory);
   3302 		}
   3303 
   3304 		vkd.cmdPipelineBarrier(*commandBuffer, vk::VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0, 0, (const vk::VkMemoryBarrier*)DE_NULL, 0, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1, &preImageBarrier);
   3305 		vkd.cmdCopyBufferToImage(*commandBuffer, *srcBuffer, *m_srcImage, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
   3306 		vkd.cmdPipelineBarrier(*commandBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0, 0, (const vk::VkMemoryBarrier*)DE_NULL, 0, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
   3307 
   3308 		VK_CHECK(vkd.endCommandBuffer(*commandBuffer));
   3309 		queueRun(vkd, queue, *commandBuffer);
   3310 	}
   3311 }
   3312 
   3313 void ImageCopyFromImage::logSubmit (TestLog& log, size_t commandIndex) const
   3314 {
   3315 	log << TestLog::Message << commandIndex << ":" << getName() << " Copy image data from another image" << TestLog::EndMessage;
   3316 }
   3317 
   3318 void ImageCopyFromImage::submit (SubmitContext& context)
   3319 {
   3320 	const vk::DeviceInterface&	vkd				= context.getContext().getDeviceInterface();
   3321 	const vk::VkCommandBuffer	commandBuffer	= context.getCommandBuffer();
   3322 	const vk::VkImageCopy		region			=
   3323 	{
   3324 		{
   3325 			vk::VK_IMAGE_ASPECT_COLOR_BIT,
   3326 			0,	// mipLevel
   3327 			0,	// arrayLayer
   3328 			1	// layerCount
   3329 		},
   3330 		{ 0, 0, 0 },
   3331 
   3332 		{
   3333 			vk::VK_IMAGE_ASPECT_COLOR_BIT,
   3334 			0,	// mipLevel
   3335 			0,	// arrayLayer
   3336 			1	// layerCount
   3337 		},
   3338 		{ 0, 0, 0 },
   3339 		{
   3340 			(deUint32)m_imageWidth,
   3341 			(deUint32)m_imageHeight,
   3342 			1u
   3343 		}
   3344 	};
   3345 
   3346 	vkd.cmdCopyImage(commandBuffer, *m_srcImage, vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, context.getImage(), m_imageLayout, 1, &region);
   3347 }
   3348 
   3349 void ImageCopyFromImage::verify (VerifyContext& context, size_t)
   3350 {
   3351 	ReferenceMemory&	reference	(context.getReference());
   3352 	de::Random			rng			(m_seed);
   3353 
   3354 	reference.setUndefined(0, (size_t)m_imageMemorySize);
   3355 
   3356 	{
   3357 		const PixelBufferAccess&	refAccess	(context.getReferenceImage().getAccess());
   3358 
   3359 		for (deInt32 y = 0; y < m_imageHeight; y++)
   3360 		for (deInt32 x = 0; x < m_imageWidth; x++)
   3361 		{
   3362 			const deUint8 r8 = rng.getUint8();
   3363 			const deUint8 g8 = rng.getUint8();
   3364 			const deUint8 b8 = rng.getUint8();
   3365 			const deUint8 a8 = rng.getUint8();
   3366 
   3367 			refAccess.setPixel(UVec4(r8, g8, b8, a8), x, y);
   3368 		}
   3369 	}
   3370 }
   3371 
   3372 class ImageCopyToImage : public CmdCommand
   3373 {
   3374 public:
   3375 									ImageCopyToImage	(vk::VkImageLayout imageLayout) : m_imageLayout(imageLayout) {}
   3376 									~ImageCopyToImage	(void) {}
   3377 	const char*						getName				(void) const { return "ImageCopyToImage"; }
   3378 
   3379 	void							logPrepare			(TestLog& log, size_t commandIndex) const;
   3380 	void							prepare				(PrepareContext& context);
   3381 	void							logSubmit			(TestLog& log, size_t commandIndex) const;
   3382 	void							submit				(SubmitContext& context);
   3383 	void							verify				(VerifyContext& context, size_t commandIndex);
   3384 
   3385 private:
   3386 	const vk::VkImageLayout			m_imageLayout;
   3387 	deInt32							m_imageWidth;
   3388 	deInt32							m_imageHeight;
   3389 	vk::VkDeviceSize				m_imageMemorySize;
   3390 	vk::Move<vk::VkImage>			m_dstImage;
   3391 	vk::Move<vk::VkDeviceMemory>	m_memory;
   3392 };
   3393 
   3394 void ImageCopyToImage::logPrepare (TestLog& log, size_t commandIndex) const
   3395 {
   3396 	log << TestLog::Message << commandIndex << ":" << getName() << " Allocate destination image for image to image copy." << TestLog::EndMessage;
   3397 }
   3398 
   3399 void ImageCopyToImage::prepare (PrepareContext& context)
   3400 {
   3401 	const vk::InstanceInterface&	vki				= context.getContext().getInstanceInterface();
   3402 	const vk::DeviceInterface&		vkd				= context.getContext().getDeviceInterface();
   3403 	const vk::VkPhysicalDevice		physicalDevice	= context.getContext().getPhysicalDevice();
   3404 	const vk::VkDevice				device			= context.getContext().getDevice();
   3405 	const vk::VkQueue				queue			= context.getContext().getQueue();
   3406 	const vk::VkCommandPool			commandPool		= context.getContext().getCommandPool();
   3407 	const vector<deUint32>&			queueFamilies	= context.getContext().getQueueFamilies();
   3408 
   3409 	m_imageWidth		= context.getImageWidth();
   3410 	m_imageHeight		= context.getImageHeight();
   3411 	m_imageMemorySize	= context.getImageMemorySize();
   3412 
   3413 	{
   3414 		const vk::VkImageCreateInfo	createInfo =
   3415 		{
   3416 			vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
   3417 			DE_NULL,
   3418 
   3419 			0,
   3420 			vk::VK_IMAGE_TYPE_2D,
   3421 			vk::VK_FORMAT_R8G8B8A8_UNORM,
   3422 			{
   3423 				(deUint32)m_imageWidth,
   3424 				(deUint32)m_imageHeight,
   3425 				1u,
   3426 			},
   3427 			1, 1, // mipLevels, arrayLayers
   3428 			vk::VK_SAMPLE_COUNT_1_BIT,
   3429 
   3430 			vk::VK_IMAGE_TILING_OPTIMAL,
   3431 			vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT|vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
   3432 			vk::VK_SHARING_MODE_EXCLUSIVE,
   3433 
   3434 			(deUint32)queueFamilies.size(),
   3435 			&queueFamilies[0],
   3436 			vk::VK_IMAGE_LAYOUT_UNDEFINED
   3437 		};
   3438 
   3439 		m_dstImage = vk::createImage(vkd, device, &createInfo);
   3440 	}
   3441 
   3442 	m_memory = bindImageMemory(vki, vkd, physicalDevice, device, *m_dstImage, 0);
   3443 
   3444 	{
   3445 		const vk::Unique<vk::VkCommandBuffer>	commandBuffer	(createBeginCommandBuffer(vkd, device, commandPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
   3446 		const vk::VkImageMemoryBarrier			barrier			=
   3447 		{
   3448 			vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
   3449 			DE_NULL,
   3450 
   3451 			0,
   3452 			vk::VK_ACCESS_TRANSFER_WRITE_BIT,
   3453 
   3454 			vk::VK_IMAGE_LAYOUT_UNDEFINED,
   3455 			vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
   3456 
   3457 			VK_QUEUE_FAMILY_IGNORED,
   3458 			VK_QUEUE_FAMILY_IGNORED,
   3459 
   3460 			*m_dstImage,
   3461 			{
   3462 				vk::VK_IMAGE_ASPECT_COLOR_BIT,
   3463 				0,	// Mip level
   3464 				1,	// Mip level count
   3465 				0,	// Layer
   3466 				1	// Layer count
   3467 			}
   3468 		};
   3469 
   3470 		vkd.cmdPipelineBarrier(*commandBuffer, vk::VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0, 0, (const vk::VkMemoryBarrier*)DE_NULL, 0, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1, &barrier);
   3471 
   3472 		VK_CHECK(vkd.endCommandBuffer(*commandBuffer));
   3473 		queueRun(vkd, queue, *commandBuffer);
   3474 	}
   3475 }
   3476 
   3477 void ImageCopyToImage::logSubmit (TestLog& log, size_t commandIndex) const
   3478 {
   3479 	log << TestLog::Message << commandIndex << ":" << getName() << " Copy image to another image" << TestLog::EndMessage;
   3480 }
   3481 
   3482 void ImageCopyToImage::submit (SubmitContext& context)
   3483 {
   3484 	const vk::DeviceInterface&	vkd				= context.getContext().getDeviceInterface();
   3485 	const vk::VkCommandBuffer	commandBuffer	= context.getCommandBuffer();
   3486 	const vk::VkImageCopy		region			=
   3487 	{
   3488 		{
   3489 			vk::VK_IMAGE_ASPECT_COLOR_BIT,
   3490 			0,	// mipLevel
   3491 			0,	// arrayLayer
   3492 			1	// layerCount
   3493 		},
   3494 		{ 0, 0, 0 },
   3495 
   3496 		{
   3497 			vk::VK_IMAGE_ASPECT_COLOR_BIT,
   3498 			0,	// mipLevel
   3499 			0,	// arrayLayer
   3500 			1	// layerCount
   3501 		},
   3502 		{ 0, 0, 0 },
   3503 		{
   3504 			(deUint32)m_imageWidth,
   3505 			(deUint32)m_imageHeight,
   3506 			1u
   3507 		}
   3508 	};
   3509 
   3510 	vkd.cmdCopyImage(commandBuffer, context.getImage(), m_imageLayout, *m_dstImage, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
   3511 }
   3512 
   3513 void ImageCopyToImage::verify (VerifyContext& context, size_t commandIndex)
   3514 {
   3515 	tcu::ResultCollector&					resultCollector	(context.getResultCollector());
   3516 	const vk::InstanceInterface&			vki				= context.getContext().getInstanceInterface();
   3517 	const vk::DeviceInterface&				vkd				= context.getContext().getDeviceInterface();
   3518 	const vk::VkPhysicalDevice				physicalDevice	= context.getContext().getPhysicalDevice();
   3519 	const vk::VkDevice						device			= context.getContext().getDevice();
   3520 	const vk::VkQueue						queue			= context.getContext().getQueue();
   3521 	const vk::VkCommandPool					commandPool		= context.getContext().getCommandPool();
   3522 	const vk::Unique<vk::VkCommandBuffer>	commandBuffer	(createBeginCommandBuffer(vkd, device, commandPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
   3523 	const vector<deUint32>&					queueFamilies	= context.getContext().getQueueFamilies();
   3524 	const vk::Unique<vk::VkBuffer>			dstBuffer		(createBuffer(vkd, device, 4 * m_imageWidth * m_imageHeight, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT, vk::VK_SHARING_MODE_EXCLUSIVE, queueFamilies));
   3525 	const vk::Unique<vk::VkDeviceMemory>	memory			(bindBufferMemory(vki, vkd, physicalDevice, device, *dstBuffer, vk::VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT));
   3526 	{
   3527 		const vk::VkImageMemoryBarrier		imageBarrier	=
   3528 		{
   3529 			vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
   3530 			DE_NULL,
   3531 
   3532 			vk::VK_ACCESS_TRANSFER_WRITE_BIT,
   3533 			vk::VK_ACCESS_TRANSFER_READ_BIT,
   3534 
   3535 			vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
   3536 			vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
   3537 
   3538 			VK_QUEUE_FAMILY_IGNORED,
   3539 			VK_QUEUE_FAMILY_IGNORED,
   3540 
   3541 			*m_dstImage,
   3542 			{
   3543 				vk::VK_IMAGE_ASPECT_COLOR_BIT,
   3544 				0,	// Mip level
   3545 				1,	// Mip level count
   3546 				0,	// Layer
   3547 				1	// Layer count
   3548 			}
   3549 		};
   3550 		const vk::VkBufferMemoryBarrier bufferBarrier =
   3551 		{
   3552 			vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
   3553 			DE_NULL,
   3554 
   3555 			vk::VK_ACCESS_TRANSFER_WRITE_BIT,
   3556 			vk::VK_ACCESS_HOST_READ_BIT,
   3557 
   3558 			VK_QUEUE_FAMILY_IGNORED,
   3559 			VK_QUEUE_FAMILY_IGNORED,
   3560 			*dstBuffer,
   3561 			0,
   3562 			VK_WHOLE_SIZE
   3563 		};
   3564 		const vk::VkBufferImageCopy	region =
   3565 		{
   3566 			0,
   3567 			0, 0,
   3568 			{
   3569 				vk::VK_IMAGE_ASPECT_COLOR_BIT,
   3570 				0,	// mipLevel
   3571 				0,	// arrayLayer
   3572 				1	// layerCount
   3573 			},
   3574 			{ 0, 0, 0 },
   3575 			{
   3576 				(deUint32)m_imageWidth,
   3577 				(deUint32)m_imageHeight,
   3578 				1u
   3579 			}
   3580 		};
   3581 
   3582 		vkd.cmdPipelineBarrier(*commandBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0, 0, (const vk::VkMemoryBarrier*)DE_NULL, 0, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier);
   3583 		vkd.cmdCopyImageToBuffer(*commandBuffer, *m_dstImage, vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *dstBuffer, 1, &region);
   3584 		vkd.cmdPipelineBarrier(*commandBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, (vk::VkDependencyFlags)0, 0, (const vk::VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
   3585 	}
   3586 
   3587 	VK_CHECK(vkd.endCommandBuffer(*commandBuffer));
   3588 	queueRun(vkd, queue, *commandBuffer);
   3589 
   3590 	{
   3591 		void* const	ptr		= mapMemory(vkd, device, *memory, 4 * m_imageWidth * m_imageHeight);
   3592 
   3593 		vk::invalidateMappedMemoryRange(vkd, device, *memory, 0,  4 * m_imageWidth * m_imageHeight);
   3594 
   3595 		{
   3596 			const deUint8* const			data		= (const deUint8*)ptr;
   3597 			const ConstPixelBufferAccess	resAccess	(TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8), m_imageWidth, m_imageHeight, 1, data);
   3598 			const ConstPixelBufferAccess&	refAccess	(context.getReferenceImage().getAccess());
   3599 
   3600 			if (!tcu::intThresholdCompare(context.getLog(), (de::toString(commandIndex) + ":" + getName()).c_str(), (de::toString(commandIndex) + ":" + getName()).c_str(), refAccess, resAccess, UVec4(0), tcu::COMPARE_LOG_ON_ERROR))
   3601 				resultCollector.fail(de::toString(commandIndex) + ":" + getName() + " Image comparison failed");
   3602 		}
   3603 
   3604 		vkd.unmapMemory(device, *memory);
   3605 	}
   3606 }
   3607 
   3608 enum BlitScale
   3609 {
   3610 	BLIT_SCALE_20,
   3611 	BLIT_SCALE_10,
   3612 };
   3613 
   3614 class ImageBlitFromImage : public CmdCommand
   3615 {
   3616 public:
   3617 									ImageBlitFromImage	(deUint32 seed, BlitScale scale, vk::VkImageLayout imageLayout) : m_seed(seed), m_scale(scale), m_imageLayout(imageLayout) {}
   3618 									~ImageBlitFromImage	(void) {}
   3619 	const char*						getName				(void) const { return "ImageBlitFromImage"; }
   3620 
   3621 	void							logPrepare			(TestLog& log, size_t commandIndex) const;
   3622 	void							prepare				(PrepareContext& context);
   3623 	void							logSubmit			(TestLog& log, size_t commandIndex) const;
   3624 	void							submit				(SubmitContext& context);
   3625 	void							verify				(VerifyContext& context, size_t commandIndex);
   3626 
   3627 private:
   3628 	const deUint32					m_seed;
   3629 	const BlitScale					m_scale;
   3630 	const vk::VkImageLayout			m_imageLayout;
   3631 	deInt32							m_imageWidth;
   3632 	deInt32							m_imageHeight;
   3633 	vk::VkDeviceSize				m_imageMemorySize;
   3634 	deInt32							m_srcImageWidth;
   3635 	deInt32							m_srcImageHeight;
   3636 	vk::Move<vk::VkImage>			m_srcImage;
   3637 	vk::Move<vk::VkDeviceMemory>	m_memory;
   3638 };
   3639 
   3640 void ImageBlitFromImage::logPrepare (TestLog& log, size_t commandIndex) const
   3641 {
   3642 	log << TestLog::Message << commandIndex << ":" << getName() << " Allocate source image for image to image blit." << TestLog::EndMessage;
   3643 }
   3644 
   3645 void ImageBlitFromImage::prepare (PrepareContext& context)
   3646 {
   3647 	const vk::InstanceInterface&	vki				= context.getContext().getInstanceInterface();
   3648 	const vk::DeviceInterface&		vkd				= context.getContext().getDeviceInterface();
   3649 	const vk::VkPhysicalDevice		physicalDevice	= context.getContext().getPhysicalDevice();
   3650 	const vk::VkDevice				device			= context.getContext().getDevice();
   3651 	const vk::VkQueue				queue			= context.getContext().getQueue();
   3652 	const vk::VkCommandPool			commandPool		= context.getContext().getCommandPool();
   3653 	const vector<deUint32>&			queueFamilies	= context.getContext().getQueueFamilies();
   3654 
   3655 	m_imageWidth		= context.getImageWidth();
   3656 	m_imageHeight		= context.getImageHeight();
   3657 	m_imageMemorySize	= context.getImageMemorySize();
   3658 
   3659 	if (m_scale == BLIT_SCALE_10)
   3660 	{
   3661 		m_srcImageWidth			= m_imageWidth;
   3662 		m_srcImageHeight		= m_imageHeight;
   3663 	}
   3664 	else if (m_scale == BLIT_SCALE_20)
   3665 	{
   3666 		m_srcImageWidth			= m_imageWidth / 2;
   3667 		m_srcImageHeight		= m_imageHeight / 2;
   3668 	}
   3669 	else
   3670 		DE_FATAL("Unsupported scale");
   3671 
   3672 	{
   3673 		const vk::VkImageCreateInfo	createInfo =
   3674 		{
   3675 			vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
   3676 			DE_NULL,
   3677 
   3678 			0,
   3679 			vk::VK_IMAGE_TYPE_2D,
   3680 			vk::VK_FORMAT_R8G8B8A8_UNORM,
   3681 			{
   3682 				(deUint32)m_srcImageWidth,
   3683 				(deUint32)m_srcImageHeight,
   3684 				1u,
   3685 			},
   3686 			1, 1, // mipLevels, arrayLayers
   3687 			vk::VK_SAMPLE_COUNT_1_BIT,
   3688 
   3689 			vk::VK_IMAGE_TILING_OPTIMAL,
   3690 			vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT|vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
   3691 			vk::VK_SHARING_MODE_EXCLUSIVE,
   3692 
   3693 			(deUint32)queueFamilies.size(),
   3694 			&queueFamilies[0],
   3695 			vk::VK_IMAGE_LAYOUT_UNDEFINED
   3696 		};
   3697 
   3698 		m_srcImage = vk::createImage(vkd, device, &createInfo);
   3699 	}
   3700 
   3701 	m_memory = bindImageMemory(vki, vkd, physicalDevice, device, *m_srcImage, 0);
   3702 
   3703 	{
   3704 		const vk::Unique<vk::VkBuffer>			srcBuffer		(createBuffer(vkd, device, 4 * m_srcImageWidth * m_srcImageHeight, vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT, vk::VK_SHARING_MODE_EXCLUSIVE, queueFamilies));
   3705 		const vk::Unique<vk::VkDeviceMemory>	memory			(bindBufferMemory(vki, vkd, physicalDevice, device, *srcBuffer, vk::VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT));
   3706 		const vk::Unique<vk::VkCommandBuffer>	commandBuffer	(createBeginCommandBuffer(vkd, device, commandPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
   3707 		const vk::VkImageMemoryBarrier			preImageBarrier	=
   3708 		{
   3709 			vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
   3710 			DE_NULL,
   3711 
   3712 			0,
   3713 			vk::VK_ACCESS_TRANSFER_WRITE_BIT,
   3714 
   3715 			vk::VK_IMAGE_LAYOUT_UNDEFINED,
   3716 			vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
   3717 
   3718 			VK_QUEUE_FAMILY_IGNORED,
   3719 			VK_QUEUE_FAMILY_IGNORED,
   3720 
   3721 			*m_srcImage,
   3722 			{
   3723 				vk::VK_IMAGE_ASPECT_COLOR_BIT,
   3724 				0,	// Mip level
   3725 				1,	// Mip level count
   3726 				0,	// Layer
   3727 				1	// Layer count
   3728 			}
   3729 		};
   3730 		const vk::VkImageMemoryBarrier			postImageBarrier =
   3731 		{
   3732 			vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
   3733 			DE_NULL,
   3734 
   3735 			vk::VK_ACCESS_TRANSFER_WRITE_BIT,
   3736 			0,
   3737 
   3738 			vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
   3739 			vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
   3740 
   3741 			VK_QUEUE_FAMILY_IGNORED,
   3742 			VK_QUEUE_FAMILY_IGNORED,
   3743 
   3744 			*m_srcImage,
   3745 			{
   3746 				vk::VK_IMAGE_ASPECT_COLOR_BIT,
   3747 				0,	// Mip level
   3748 				1,	// Mip level count
   3749 				0,	// Layer
   3750 				1	// Layer count
   3751 			}
   3752 		};
   3753 		const vk::VkBufferImageCopy				region				=
   3754 		{
   3755 			0,
   3756 			0, 0,
   3757 			{
   3758 				vk::VK_IMAGE_ASPECT_COLOR_BIT,
   3759 				0,	// mipLevel
   3760 				0,	// arrayLayer
   3761 				1	// layerCount
   3762 			},
   3763 			{ 0, 0, 0 },
   3764 			{
   3765 				(deUint32)m_srcImageWidth,
   3766 				(deUint32)m_srcImageHeight,
   3767 				1u
   3768 			}
   3769 		};
   3770 
   3771 		{
   3772 			void* const	ptr	= mapMemory(vkd, device, *memory, 4 * m_srcImageWidth * m_srcImageHeight);
   3773 			de::Random	rng	(m_seed);
   3774 
   3775 			{
   3776 				deUint8* const	data = (deUint8*)ptr;
   3777 
   3778 				for (size_t ndx = 0; ndx < (size_t)(4 * m_srcImageWidth * m_srcImageHeight); ndx++)
   3779 					data[ndx] = rng.getUint8();
   3780 			}
   3781 
   3782 			vk::flushMappedMemoryRange(vkd, device, *memory, 0, 4 * m_srcImageWidth * m_srcImageHeight);
   3783 			vkd.unmapMemory(device, *memory);
   3784 		}
   3785 
   3786 		vkd.cmdPipelineBarrier(*commandBuffer, vk::VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0, 0, (const vk::VkMemoryBarrier*)DE_NULL, 0, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1, &preImageBarrier);
   3787 		vkd.cmdCopyBufferToImage(*commandBuffer, *srcBuffer, *m_srcImage, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
   3788 		vkd.cmdPipelineBarrier(*commandBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0, 0, (const vk::VkMemoryBarrier*)DE_NULL, 0, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
   3789 
   3790 		VK_CHECK(vkd.endCommandBuffer(*commandBuffer));
   3791 		queueRun(vkd, queue, *commandBuffer);
   3792 	}
   3793 }
   3794 
   3795 void ImageBlitFromImage::logSubmit (TestLog& log, size_t commandIndex) const
   3796 {
   3797 	log << TestLog::Message << commandIndex << ":" << getName() << " Blit from another image" << (m_scale == BLIT_SCALE_20 ? " scale 2x" : "")  << TestLog::EndMessage;
   3798 }
   3799 
   3800 void ImageBlitFromImage::submit (SubmitContext& context)
   3801 {
   3802 	const vk::DeviceInterface&	vkd				= context.getContext().getDeviceInterface();
   3803 	const vk::VkCommandBuffer	commandBuffer	= context.getCommandBuffer();
   3804 	const vk::VkImageBlit		region			=
   3805 	{
   3806 		// Src
   3807 		{
   3808 			vk::VK_IMAGE_ASPECT_COLOR_BIT,
   3809 			0,	// mipLevel
   3810 			0,	// arrayLayer
   3811 			1	// layerCount
   3812 		},
   3813 		{
   3814 			{ 0, 0, 0 },
   3815 			{
   3816 				m_srcImageWidth,
   3817 				m_srcImageHeight,
   3818 				1
   3819 			},
   3820 		},
   3821 
   3822 		// Dst
   3823 		{
   3824 			vk::VK_IMAGE_ASPECT_COLOR_BIT,
   3825 			0,	// mipLevel
   3826 			0,	// arrayLayer
   3827 			1	// layerCount
   3828 		},
   3829 		{
   3830 			{ 0, 0, 0 },
   3831 			{
   3832 				m_imageWidth,
   3833 				m_imageHeight,
   3834 				1u
   3835 			}
   3836 		}
   3837 	};
   3838 	vkd.cmdBlitImage(commandBuffer, *m_srcImage, vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, context.getImage(), m_imageLayout, 1, &region, vk::VK_FILTER_NEAREST);
   3839 }
   3840 
   3841 void ImageBlitFromImage::verify (VerifyContext& context, size_t)
   3842 {
   3843 	ReferenceMemory&	reference	(context.getReference());
   3844 	de::Random			rng			(m_seed);
   3845 
   3846 	reference.setUndefined(0, (size_t)m_imageMemorySize);
   3847 
   3848 	{
   3849 		const PixelBufferAccess&	refAccess	(context.getReferenceImage().getAccess());
   3850 
   3851 		if (m_scale == BLIT_SCALE_10)
   3852 		{
   3853 			for (deInt32 y = 0; y < m_imageHeight; y++)
   3854 			for (deInt32 x = 0; x < m_imageWidth; x++)
   3855 			{
   3856 				const deUint8 r8 = rng.getUint8();
   3857 				const deUint8 g8 = rng.getUint8();
   3858 				const deUint8 b8 = rng.getUint8();
   3859 				const deUint8 a8 = rng.getUint8();
   3860 
   3861 				refAccess.setPixel(UVec4(r8, g8, b8, a8), x, y);
   3862 			}
   3863 		}
   3864 		else if (m_scale == BLIT_SCALE_20)
   3865 		{
   3866 			tcu::TextureLevel	source	(TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8), m_srcImageWidth, m_srcImageHeight);
   3867 			const float			xscale	= ((float)m_srcImageWidth)  / (float)m_imageWidth;
   3868 			const float			yscale	= ((float)m_srcImageHeight) / (float)m_imageHeight;
   3869 
   3870 			for (deInt32 y = 0; y < m_srcImageHeight; y++)
   3871 			for (deInt32 x = 0; x < m_srcImageWidth; x++)
   3872 			{
   3873 				const deUint8 r8 = rng.getUint8();
   3874 				const deUint8 g8 = rng.getUint8();
   3875 				const deUint8 b8 = rng.getUint8();
   3876 				const deUint8 a8 = rng.getUint8();
   3877 
   3878 				source.getAccess().setPixel(UVec4(r8, g8, b8, a8), x, y);
   3879 			}
   3880 
   3881 			for (deInt32 y = 0; y < m_imageHeight; y++)
   3882 			for (deInt32 x = 0; x < m_imageWidth; x++)
   3883 				refAccess.setPixel(source.getAccess().getPixelUint(int((float(x) + 0.5f) * xscale), int((float(y) + 0.5f) * yscale)), x, y);
   3884 		}
   3885 		else
   3886 			DE_FATAL("Unsupported scale");
   3887 	}
   3888 }
   3889 
   3890 class ImageBlitToImage : public CmdCommand
   3891 {
   3892 public:
   3893 									ImageBlitToImage	(BlitScale scale, vk::VkImageLayout imageLayout) : m_scale(scale), m_imageLayout(imageLayout) {}
   3894 									~ImageBlitToImage	(void) {}
   3895 	const char*						getName				(void) const { return "ImageBlitToImage"; }
   3896 
   3897 	void							logPrepare			(TestLog& log, size_t commandIndex) const;
   3898 	void							prepare				(PrepareContext& context);
   3899 	void							logSubmit			(TestLog& log, size_t commandIndex) const;
   3900 	void							submit				(SubmitContext& context);
   3901 	void							verify				(VerifyContext& context, size_t commandIndex);
   3902 
   3903 private:
   3904 	const BlitScale					m_scale;
   3905 	const vk::VkImageLayout			m_imageLayout;
   3906 	deInt32							m_imageWidth;
   3907 	deInt32							m_imageHeight;
   3908 	vk::VkDeviceSize				m_imageMemorySize;
   3909 	deInt32							m_dstImageWidth;
   3910 	deInt32							m_dstImageHeight;
   3911 	vk::Move<vk::VkImage>			m_dstImage;
   3912 	vk::Move<vk::VkDeviceMemory>	m_memory;
   3913 };
   3914 
   3915 void ImageBlitToImage::logPrepare (TestLog& log, size_t commandIndex) const
   3916 {
   3917 	log << TestLog::Message << commandIndex << ":" << getName() << " Allocate destination image for image to image blit." << TestLog::EndMessage;
   3918 }
   3919 
   3920 void ImageBlitToImage::prepare (PrepareContext& context)
   3921 {
   3922 	const vk::InstanceInterface&	vki				= context.getContext().getInstanceInterface();
   3923 	const vk::DeviceInterface&		vkd				= context.getContext().getDeviceInterface();
   3924 	const vk::VkPhysicalDevice		physicalDevice	= context.getContext().getPhysicalDevice();
   3925 	const vk::VkDevice				device			= context.getContext().getDevice();
   3926 	const vk::VkQueue				queue			= context.getContext().getQueue();
   3927 	const vk::VkCommandPool			commandPool		= context.getContext().getCommandPool();
   3928 	const vector<deUint32>&			queueFamilies	= context.getContext().getQueueFamilies();
   3929 
   3930 	m_imageWidth		= context.getImageWidth();
   3931 	m_imageHeight		= context.getImageHeight();
   3932 	m_imageMemorySize	= context.getImageMemorySize();
   3933 
   3934 	if (m_scale == BLIT_SCALE_10)
   3935 	{
   3936 		m_dstImageWidth		= context.getImageWidth();
   3937 		m_dstImageHeight	= context.getImageHeight();
   3938 	}
   3939 	else if (m_scale == BLIT_SCALE_20)
   3940 	{
   3941 		m_dstImageWidth		= context.getImageWidth() * 2;
   3942 		m_dstImageHeight	= context.getImageHeight() * 2;
   3943 	}
   3944 	else
   3945 		DE_FATAL("Unsupportd blit scale");
   3946 
   3947 	{
   3948 		const vk::VkImageCreateInfo	createInfo =
   3949 		{
   3950 			vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
   3951 			DE_NULL,
   3952 
   3953 			0,
   3954 			vk::VK_IMAGE_TYPE_2D,
   3955 			vk::VK_FORMAT_R8G8B8A8_UNORM,
   3956 			{
   3957 				(deUint32)m_dstImageWidth,
   3958 				(deUint32)m_dstImageHeight,
   3959 				1u,
   3960 			},
   3961 			1, 1, // mipLevels, arrayLayers
   3962 			vk::VK_SAMPLE_COUNT_1_BIT,
   3963 
   3964 			vk::VK_IMAGE_TILING_OPTIMAL,
   3965 			vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT|vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
   3966 			vk::VK_SHARING_MODE_EXCLUSIVE,
   3967 
   3968 			(deUint32)queueFamilies.size(),
   3969 			&queueFamilies[0],
   3970 			vk::VK_IMAGE_LAYOUT_UNDEFINED
   3971 		};
   3972 
   3973 		m_dstImage = vk::createImage(vkd, device, &createInfo);
   3974 	}
   3975 
   3976 	m_memory = bindImageMemory(vki, vkd, physicalDevice, device, *m_dstImage, 0);
   3977 
   3978 	{
   3979 		const vk::Unique<vk::VkCommandBuffer>	commandBuffer	(createBeginCommandBuffer(vkd, device, commandPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
   3980 		const vk::VkImageMemoryBarrier			barrier			=
   3981 		{
   3982 			vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
   3983 			DE_NULL,
   3984 
   3985 			0,
   3986 			vk::VK_ACCESS_TRANSFER_WRITE_BIT,
   3987 
   3988 			vk::VK_IMAGE_LAYOUT_UNDEFINED,
   3989 			vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
   3990 
   3991 			VK_QUEUE_FAMILY_IGNORED,
   3992 			VK_QUEUE_FAMILY_IGNORED,
   3993 
   3994 			*m_dstImage,
   3995 			{
   3996 				vk::VK_IMAGE_ASPECT_COLOR_BIT,
   3997 				0,	// Mip level
   3998 				1,	// Mip level count
   3999 				0,	// Layer
   4000 				1	// Layer count
   4001 			}
   4002 		};
   4003 
   4004 		vkd.cmdPipelineBarrier(*commandBuffer, vk::VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0, 0, (const vk::VkMemoryBarrier*)DE_NULL, 0, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1, &barrier);
   4005 
   4006 		VK_CHECK(vkd.endCommandBuffer(*commandBuffer));
   4007 		queueRun(vkd, queue, *commandBuffer);
   4008 	}
   4009 }
   4010 
   4011 void ImageBlitToImage::logSubmit (TestLog& log, size_t commandIndex) const
   4012 {
   4013 	log << TestLog::Message << commandIndex << ":" << getName() << " Blit image to another image" << (m_scale == BLIT_SCALE_20 ? " scale 2x" : "")  << TestLog::EndMessage;
   4014 }
   4015 
   4016 void ImageBlitToImage::submit (SubmitContext& context)
   4017 {
   4018 	const vk::DeviceInterface&	vkd				= context.getContext().getDeviceInterface();
   4019 	const vk::VkCommandBuffer	commandBuffer	= context.getCommandBuffer();
   4020 	const vk::VkImageBlit		region			=
   4021 	{
   4022 		// Src
   4023 		{
   4024 			vk::VK_IMAGE_ASPECT_COLOR_BIT,
   4025 			0,	// mipLevel
   4026 			0,	// arrayLayer
   4027 			1	// layerCount
   4028 		},
   4029 		{
   4030 			{ 0, 0, 0 },
   4031 			{
   4032 				m_imageWidth,
   4033 				m_imageHeight,
   4034 				1
   4035 			},
   4036 		},
   4037 
   4038 		// Dst
   4039 		{
   4040 			vk::VK_IMAGE_ASPECT_COLOR_BIT,
   4041 			0,	// mipLevel
   4042 			0,	// arrayLayer
   4043 			1	// layerCount
   4044 		},
   4045 		{
   4046 			{ 0, 0, 0 },
   4047 			{
   4048 				m_dstImageWidth,
   4049 				m_dstImageHeight,
   4050 				1u
   4051 			}
   4052 		}
   4053 	};
   4054 	vkd.cmdBlitImage(commandBuffer, context.getImage(), m_imageLayout, *m_dstImage, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region, vk::VK_FILTER_NEAREST);
   4055 }
   4056 
   4057 void ImageBlitToImage::verify (VerifyContext& context, size_t commandIndex)
   4058 {
   4059 	tcu::ResultCollector&					resultCollector	(context.getResultCollector());
   4060 	const vk::InstanceInterface&			vki				= context.getContext().getInstanceInterface();
   4061 	const vk::DeviceInterface&				vkd				= context.getContext().getDeviceInterface();
   4062 	const vk::VkPhysicalDevice				physicalDevice	= context.getContext().getPhysicalDevice();
   4063 	const vk::VkDevice						device			= context.getContext().getDevice();
   4064 	const vk::VkQueue						queue			= context.getContext().getQueue();
   4065 	const vk::VkCommandPool					commandPool		= context.getContext().getCommandPool();
   4066 	const vk::Unique<vk::VkCommandBuffer>	commandBuffer	(createBeginCommandBuffer(vkd, device, commandPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
   4067 	const vector<deUint32>&					queueFamilies	= context.getContext().getQueueFamilies();
   4068 	const vk::Unique<vk::VkBuffer>			dstBuffer		(createBuffer(vkd, device, 4 * m_dstImageWidth * m_dstImageHeight, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT, vk::VK_SHARING_MODE_EXCLUSIVE, queueFamilies));
   4069 	const vk::Unique<vk::VkDeviceMemory>	memory			(bindBufferMemory(vki, vkd, physicalDevice, device, *dstBuffer, vk::VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT));
   4070 	{
   4071 		const vk::VkImageMemoryBarrier		imageBarrier	=
   4072 		{
   4073 			vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
   4074 			DE_NULL,
   4075 
   4076 			vk::VK_ACCESS_TRANSFER_WRITE_BIT,
   4077 			vk::VK_ACCESS_TRANSFER_READ_BIT,
   4078 
   4079 			vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
   4080 			vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
   4081 
   4082 			VK_QUEUE_FAMILY_IGNORED,
   4083 			VK_QUEUE_FAMILY_IGNORED,
   4084 
   4085 			*m_dstImage,
   4086 			{
   4087 				vk::VK_IMAGE_ASPECT_COLOR_BIT,
   4088 				0,	// Mip level
   4089 				1,	// Mip level count
   4090 				0,	// Layer
   4091 				1	// Layer count
   4092 			}
   4093 		};
   4094 		const vk::VkBufferMemoryBarrier bufferBarrier =
   4095 		{
   4096 			vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
   4097 			DE_NULL,
   4098 
   4099 			vk::VK_ACCESS_TRANSFER_WRITE_BIT,
   4100 			vk::VK_ACCESS_HOST_READ_BIT,
   4101 
   4102 			VK_QUEUE_FAMILY_IGNORED,
   4103 			VK_QUEUE_FAMILY_IGNORED,
   4104 			*dstBuffer,
   4105 			0,
   4106 			VK_WHOLE_SIZE
   4107 		};
   4108 		const vk::VkBufferImageCopy	region =
   4109 		{
   4110 			0,
   4111 			0, 0,
   4112 			{
   4113 				vk::VK_IMAGE_ASPECT_COLOR_BIT,
   4114 				0,	// mipLevel
   4115 				0,	// arrayLayer
   4116 				1	// layerCount
   4117 			},
   4118 			{ 0, 0, 0 },
   4119 			{
   4120 				(deUint32)m_dstImageWidth,
   4121 				(deUint32)m_dstImageHeight,
   4122 				1
   4123 			}
   4124 		};
   4125 
   4126 		vkd.cmdPipelineBarrier(*commandBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0, 0, (const vk::VkMemoryBarrier*)DE_NULL, 0, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier);
   4127 		vkd.cmdCopyImageToBuffer(*commandBuffer, *m_dstImage, vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *dstBuffer, 1, &region);
   4128 		vkd.cmdPipelineBarrier(*commandBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, (vk::VkDependencyFlags)0, 0, (const vk::VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
   4129 	}
   4130 
   4131 	VK_CHECK(vkd.endCommandBuffer(*commandBuffer));
   4132 	queueRun(vkd, queue, *commandBuffer);
   4133 
   4134 	{
   4135 		void* const	ptr		= mapMemory(vkd, device, *memory, 4 * m_dstImageWidth * m_dstImageHeight);
   4136 
   4137 		vk::invalidateMappedMemoryRange(vkd, device, *memory, 0,  4 * m_dstImageWidth * m_dstImageHeight);
   4138 
   4139 		if (m_scale == BLIT_SCALE_10)
   4140 		{
   4141 			const deUint8* const			data		= (const deUint8*)ptr;
   4142 			const ConstPixelBufferAccess	resAccess	(TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8), m_dstImageWidth, m_dstImageHeight, 1, data);
   4143 			const ConstPixelBufferAccess&	refAccess	(context.getReferenceImage().getAccess());
   4144 
   4145 			if (!tcu::intThresholdCompare(context.getLog(), (de::toString(commandIndex) + ":" + getName()).c_str(), (de::toString(commandIndex) + ":" + getName()).c_str(), refAccess, resAccess, UVec4(0), tcu::COMPARE_LOG_ON_ERROR))
   4146 				resultCollector.fail(de::toString(commandIndex) + ":" + getName() + " Image comparison failed");
   4147 		}
   4148 		else if (m_scale == BLIT_SCALE_20)
   4149 		{
   4150 			const deUint8* const			data		= (const deUint8*)ptr;
   4151 			const ConstPixelBufferAccess	resAccess	(TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8), m_dstImageWidth, m_dstImageHeight, 1, data);
   4152 			tcu::TextureLevel				reference	(TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8), m_dstImageWidth, m_dstImageHeight, 1);
   4153 
   4154 			{
   4155 				const ConstPixelBufferAccess&	refAccess	(context.getReferenceImage().getAccess());
   4156 
   4157 				for (deInt32 y = 0; y < m_dstImageHeight; y++)
   4158 				for (deInt32 x = 0; x < m_dstImageWidth; x++)
   4159 				{
   4160 					reference.getAccess().setPixel(refAccess.getPixel(x/2, y/2), x, y);
   4161 				}
   4162 			}
   4163 
   4164 			if (!tcu::intThresholdCompare(context.getLog(), (de::toString(commandIndex) + ":" + getName()).c_str(), (de::toString(commandIndex) + ":" + getName()).c_str(), reference.getAccess(), resAccess, UVec4(0), tcu::COMPARE_LOG_ON_ERROR))
   4165 				resultCollector.fail(de::toString(commandIndex) + ":" + getName() + " Image comparison failed");
   4166 		}
   4167 		else
   4168 			DE_FATAL("Unknown scale");
   4169 
   4170 		vkd.unmapMemory(device, *memory);
   4171 	}
   4172 }
   4173 
   4174 class PrepareRenderPassContext
   4175 {
   4176 public:
   4177 								PrepareRenderPassContext	(PrepareContext&	context,
   4178 															 vk::VkRenderPass	renderPass,
   4179 															 vk::VkFramebuffer	framebuffer,
   4180 															 deInt32			targetWidth,
   4181 															 deInt32			targetHeight)
   4182 		: m_context			(context)
   4183 		, m_renderPass		(renderPass)
   4184 		, m_framebuffer		(framebuffer)
   4185 		, m_targetWidth		(targetWidth)
   4186 		, m_targetHeight	(targetHeight)
   4187 	{
   4188 	}
   4189 
   4190 	const Memory&				getMemory					(void) const { return m_context.getMemory(); }
   4191 	const Context&				getContext					(void) const { return m_context.getContext(); }
   4192 	const vk::BinaryCollection&	getBinaryCollection			(void) const { return m_context.getBinaryCollection(); }
   4193 
   4194 	vk::VkBuffer				getBuffer					(void) const { return m_context.getBuffer(); }
   4195 	vk::VkDeviceSize			getBufferSize				(void) const { return m_context.getBufferSize(); }
   4196 
   4197 	vk::VkImage					getImage					(void) const { return m_context.getImage(); }
   4198 	deInt32						getImageWidth				(void) const { return m_context.getImageWidth(); }
   4199 	deInt32						getImageHeight				(void) const { return m_context.getImageHeight(); }
   4200 	vk::VkImageLayout			getImageLayout				(void) const { return m_context.getImageLayout(); }
   4201 
   4202 	deInt32						getTargetWidth				(void) const { return m_targetWidth; }
   4203 	deInt32						getTargetHeight				(void) const { return m_targetHeight; }
   4204 
   4205 	vk::VkRenderPass			getRenderPass				(void) const { return m_renderPass; }
   4206 
   4207 private:
   4208 	PrepareContext&				m_context;
   4209 	const vk::VkRenderPass		m_renderPass;
   4210 	const vk::VkFramebuffer		m_framebuffer;
   4211 	const deInt32				m_targetWidth;
   4212 	const deInt32				m_targetHeight;
   4213 };
   4214 
   4215 class VerifyRenderPassContext
   4216 {
   4217 public:
   4218 							VerifyRenderPassContext		(VerifyContext&			context,
   4219 														 deInt32				targetWidth,
   4220 														 deInt32				targetHeight)
   4221 		: m_context			(context)
   4222 		, m_referenceTarget	(TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8), targetWidth, targetHeight)
   4223 	{
   4224 	}
   4225 
   4226 	const Context&			getContext			(void) const { return m_context.getContext(); }
   4227 	TestLog&				getLog				(void) const { return m_context.getLog(); }
   4228 	tcu::ResultCollector&	getResultCollector	(void) const { return m_context.getResultCollector(); }
   4229 
   4230 	TextureLevel&			getReferenceTarget	(void) { return m_referenceTarget; }
   4231 
   4232 	ReferenceMemory&		getReference		(void) { return m_context.getReference(); }
   4233 	TextureLevel&			getReferenceImage	(void) { return m_context.getReferenceImage();}
   4234 
   4235 private:
   4236 	VerifyContext&	m_context;
   4237 	TextureLevel	m_referenceTarget;
   4238 };
   4239 
   4240 class RenderPassCommand
   4241 {
   4242 public:
   4243 	virtual				~RenderPassCommand	(void) {}
   4244 	virtual const char*	getName				(void) const = 0;
   4245 
   4246 	// Log things that are done during prepare
   4247 	virtual void		logPrepare			(TestLog&, size_t) const {}
   4248 	// Log submitted calls etc.
   4249 	virtual void		logSubmit			(TestLog&, size_t) const {}
   4250 
   4251 	// Allocate vulkan resources and prepare for submit.
   4252 	virtual void		prepare				(PrepareRenderPassContext&) {}
   4253 
   4254 	// Submit commands to command buffer.
   4255 	virtual void		submit				(SubmitContext&) {}
   4256 
   4257 	// Verify results
   4258 	virtual void		verify				(VerifyRenderPassContext&, size_t) {}
   4259 };
   4260 
   4261 class SubmitRenderPass : public CmdCommand
   4262 {
   4263 public:
   4264 				SubmitRenderPass	(const vector<RenderPassCommand*>& commands);
   4265 				~SubmitRenderPass	(void);
   4266 	const char*	getName				(void) const { return "SubmitRenderPass"; }
   4267 
   4268 	void		logPrepare			(TestLog&, size_t) const;
   4269 	void		logSubmit			(TestLog&, size_t) const;
   4270 
   4271 	void		prepare				(PrepareContext&);
   4272 	void		submit				(SubmitContext&);
   4273 
   4274 	void		verify				(VerifyContext&, size_t);
   4275 
   4276 private:
   4277 	const deInt32					m_targetWidth;
   4278 	const deInt32					m_targetHeight;
   4279 	vk::Move<vk::VkRenderPass>		m_renderPass;
   4280 	vk::Move<vk::VkDeviceMemory>	m_colorTargetMemory;
   4281 	de::MovePtr<vk::Allocation>		m_colorTargetMemory2;
   4282 	vk::Move<vk::VkImage>			m_colorTarget;
   4283 	vk::Move<vk::VkImageView>		m_colorTargetView;
   4284 	vk::Move<vk::VkFramebuffer>		m_framebuffer;
   4285 	vector<RenderPassCommand*>		m_commands;
   4286 };
   4287 
   4288 SubmitRenderPass::SubmitRenderPass (const vector<RenderPassCommand*>& commands)
   4289 	: m_targetWidth		(256)
   4290 	, m_targetHeight	(256)
   4291 	, m_commands		(commands)
   4292 {
   4293 }
   4294 
   4295 SubmitRenderPass::~SubmitRenderPass()
   4296 {
   4297 	for (size_t cmdNdx = 0; cmdNdx < m_commands.size(); cmdNdx++)
   4298 		delete m_commands[cmdNdx];
   4299 }
   4300 
   4301 void SubmitRenderPass::logPrepare (TestLog& log, size_t commandIndex) const
   4302 {
   4303 	const string				sectionName	(de::toString(commandIndex) + ":" + getName());
   4304 	const tcu::ScopedLogSection	section		(log, sectionName, sectionName);
   4305 
   4306 	for (size_t cmdNdx = 0; cmdNdx < m_commands.size(); cmdNdx++)
   4307 	{
   4308 		RenderPassCommand& command = *m_commands[cmdNdx];
   4309 		command.logPrepare(log, cmdNdx);
   4310 	}
   4311 }
   4312 
   4313 void SubmitRenderPass::logSubmit (TestLog& log, size_t commandIndex) const
   4314 {
   4315 	const string				sectionName	(de::toString(commandIndex) + ":" + getName());
   4316 	const tcu::ScopedLogSection	section		(log, sectionName, sectionName);
   4317 
   4318 	for (size_t cmdNdx = 0; cmdNdx < m_commands.size(); cmdNdx++)
   4319 	{
   4320 		RenderPassCommand& command = *m_commands[cmdNdx];
   4321 		command.logSubmit(log, cmdNdx);
   4322 	}
   4323 }
   4324 
   4325 void SubmitRenderPass::prepare (PrepareContext& context)
   4326 {
   4327 	const vk::InstanceInterface&			vki				= context.getContext().getInstanceInterface();
   4328 	const vk::DeviceInterface&				vkd				= context.getContext().getDeviceInterface();
   4329 	const vk::VkPhysicalDevice				physicalDevice	= context.getContext().getPhysicalDevice();
   4330 	const vk::VkDevice						device			= context.getContext().getDevice();
   4331 	const vector<deUint32>&					queueFamilies	= context.getContext().getQueueFamilies();
   4332 
   4333 	const vk::VkAttachmentReference	colorAttachments[]	=
   4334 	{
   4335 		{ 0, vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }
   4336 	};
   4337 	const vk::VkSubpassDescription	subpass				=
   4338 	{
   4339 		0u,
   4340 		vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
   4341 
   4342 		0u,
   4343 		DE_NULL,
   4344 
   4345 		DE_LENGTH_OF_ARRAY(colorAttachments),
   4346 		colorAttachments,
   4347 		DE_NULL,
   4348 		DE_NULL,
   4349 		0u,
   4350 		DE_NULL
   4351 	};
   4352 	const vk::VkAttachmentDescription attachment =
   4353 	{
   4354 		0u,
   4355 		vk::VK_FORMAT_R8G8B8A8_UNORM,
   4356 		vk::VK_SAMPLE_COUNT_1_BIT,
   4357 
   4358 		vk::VK_ATTACHMENT_LOAD_OP_CLEAR,
   4359 		vk::VK_ATTACHMENT_STORE_OP_STORE,
   4360 
   4361 		vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   4362 		vk::VK_ATTACHMENT_STORE_OP_DONT_CARE,
   4363 
   4364 		vk::VK_IMAGE_LAYOUT_UNDEFINED,
   4365 		vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
   4366 	};
   4367 	{
   4368 		const vk::VkImageCreateInfo createInfo =
   4369 		{
   4370 			vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
   4371 			DE_NULL,
   4372 			0u,
   4373 
   4374 			vk::VK_IMAGE_TYPE_2D,
   4375 			vk::VK_FORMAT_R8G8B8A8_UNORM,
   4376 			{ (deUint32)m_targetWidth, (deUint32)m_targetHeight, 1u },
   4377 			1u,
   4378 			1u,
   4379 			vk::VK_SAMPLE_COUNT_1_BIT,
   4380 			vk::VK_IMAGE_TILING_OPTIMAL,
   4381 			vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
   4382 			vk::VK_SHARING_MODE_EXCLUSIVE,
   4383 			(deUint32)queueFamilies.size(),
   4384 			&queueFamilies[0],
   4385 			vk::VK_IMAGE_LAYOUT_UNDEFINED
   4386 		};
   4387 
   4388 		m_colorTarget = vk::createImage(vkd, device, &createInfo);
   4389 	}
   4390 
   4391 	m_colorTargetMemory = bindImageMemory(vki, vkd, physicalDevice, device, *m_colorTarget, 0);
   4392 
   4393 	{
   4394 		const vk::VkImageViewCreateInfo createInfo =
   4395 		{
   4396 			vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
   4397 			DE_NULL,
   4398 
   4399 			0u,
   4400 			*m_colorTarget,
   4401 			vk::VK_IMAGE_VIEW_TYPE_2D,
   4402 			vk::VK_FORMAT_R8G8B8A8_UNORM,
   4403 			{
   4404 				vk::VK_COMPONENT_SWIZZLE_R,
   4405 				vk::VK_COMPONENT_SWIZZLE_G,
   4406 				vk::VK_COMPONENT_SWIZZLE_B,
   4407 				vk::VK_COMPONENT_SWIZZLE_A
   4408 			},
   4409 			{
   4410 				vk::VK_IMAGE_ASPECT_COLOR_BIT,
   4411 				0u,
   4412 				1u,
   4413 				0u,
   4414 				1u
   4415 			}
   4416 		};
   4417 
   4418 		m_colorTargetView = vk::createImageView(vkd, device, &createInfo);
   4419 	}
   4420 	{
   4421 		const vk::VkRenderPassCreateInfo createInfo =
   4422 		{
   4423 			vk::VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
   4424 			DE_NULL,
   4425 			0u,
   4426 
   4427 			1u,
   4428 			&attachment,
   4429 
   4430 			1u,
   4431 			&subpass,
   4432 
   4433 			0,
   4434 			DE_NULL
   4435 		};
   4436 
   4437 		m_renderPass = vk::createRenderPass(vkd, device, &createInfo);
   4438 	}
   4439 
   4440 	{
   4441 		const vk::VkImageView				imageViews[]	=
   4442 		{
   4443 			*m_colorTargetView
   4444 		};
   4445 		const vk::VkFramebufferCreateInfo	createInfo		=
   4446 		{
   4447 			vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
   4448 			DE_NULL,
   4449 			0u,
   4450 
   4451 			*m_renderPass,
   4452 			DE_LENGTH_OF_ARRAY(imageViews),
   4453 			imageViews,
   4454 			(deUint32)m_targetWidth,
   4455 			(deUint32)m_targetHeight,
   4456 			1u
   4457 		};
   4458 
   4459 		m_framebuffer = vk::createFramebuffer(vkd, device, &createInfo);
   4460 	}
   4461 
   4462 	{
   4463 		PrepareRenderPassContext renderpassContext (context, *m_renderPass, *m_framebuffer, m_targetWidth, m_targetHeight);
   4464 
   4465 		for (size_t cmdNdx = 0; cmdNdx < m_commands.size(); cmdNdx++)
   4466 		{
   4467 			RenderPassCommand& command = *m_commands[cmdNdx];
   4468 			command.prepare(renderpassContext);
   4469 		}
   4470 	}
   4471 }
   4472 
   4473 void SubmitRenderPass::submit (SubmitContext& context)
   4474 {
   4475 	const vk::DeviceInterface&		vkd				= context.getContext().getDeviceInterface();
   4476 	const vk::VkCommandBuffer		commandBuffer	= context.getCommandBuffer();
   4477 	const vk::VkClearValue			clearValue		= vk::makeClearValueColorF32(0.0f, 0.0f, 0.0f, 1.0f);
   4478 
   4479 	const vk::VkRenderPassBeginInfo	beginInfo		=
   4480 	{
   4481 		vk::VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
   4482 		DE_NULL,
   4483 
   4484 		*m_renderPass,
   4485 		*m_framebuffer,
   4486 
   4487 		{ { 0, 0 },  { (deUint32)m_targetWidth, (deUint32)m_targetHeight } },
   4488 		1u,
   4489 		&clearValue
   4490 	};
   4491 
   4492 	vkd.cmdBeginRenderPass(commandBuffer, &beginInfo, vk::VK_SUBPASS_CONTENTS_INLINE);
   4493 
   4494 	for (size_t cmdNdx = 0; cmdNdx < m_commands.size(); cmdNdx++)
   4495 	{
   4496 		RenderPassCommand& command = *m_commands[cmdNdx];
   4497 
   4498 		command.submit(context);
   4499 	}
   4500 
   4501 	vkd.cmdEndRenderPass(commandBuffer);
   4502 }
   4503 
   4504 void SubmitRenderPass::verify (VerifyContext& context, size_t commandIndex)
   4505 {
   4506 	TestLog&					log				(context.getLog());
   4507 	tcu::ResultCollector&		resultCollector	(context.getResultCollector());
   4508 	const string				sectionName		(de::toString(commandIndex) + ":" + getName());
   4509 	const tcu::ScopedLogSection	section			(log, sectionName, sectionName);
   4510 	VerifyRenderPassContext		verifyContext	(context, m_targetWidth, m_targetHeight);
   4511 
   4512 	tcu::clear(verifyContext.getReferenceTarget().getAccess(), Vec4(0.0f, 0.0f, 0.0f, 1.0f));
   4513 
   4514 	for (size_t cmdNdx = 0; cmdNdx < m_commands.size(); cmdNdx++)
   4515 	{
   4516 		RenderPassCommand& command = *m_commands[cmdNdx];
   4517 		command.verify(verifyContext, cmdNdx);
   4518 	}
   4519 
   4520 	{
   4521 		const vk::InstanceInterface&			vki				= context.getContext().getInstanceInterface();
   4522 		const vk::DeviceInterface&				vkd				= context.getContext().getDeviceInterface();
   4523 		const vk::VkPhysicalDevice				physicalDevice	= context.getContext().getPhysicalDevice();
   4524 		const vk::VkDevice						device			= context.getContext().getDevice();
   4525 		const vk::VkQueue						queue			= context.getContext().getQueue();
   4526 		const vk::VkCommandPool					commandPool		= context.getContext().getCommandPool();
   4527 		const vk::Unique<vk::VkCommandBuffer>	commandBuffer	(createBeginCommandBuffer(vkd, device, commandPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
   4528 		const vector<deUint32>&					queueFamilies	= context.getContext().getQueueFamilies();
   4529 		const vk::Unique<vk::VkBuffer>			dstBuffer		(createBuffer(vkd, device, 4 * m_targetWidth * m_targetHeight, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT, vk::VK_SHARING_MODE_EXCLUSIVE, queueFamilies));
   4530 		const vk::Unique<vk::VkDeviceMemory>	memory			(bindBufferMemory(vki, vkd, physicalDevice, device, *dstBuffer, vk::VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT));
   4531 		{
   4532 			const vk::VkImageMemoryBarrier		imageBarrier	=
   4533 			{
   4534 				vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
   4535 				DE_NULL,
   4536 
   4537 				vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
   4538 				vk::VK_ACCESS_TRANSFER_READ_BIT,
   4539 
   4540 				vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
   4541 				vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
   4542 
   4543 				VK_QUEUE_FAMILY_IGNORED,
   4544 				VK_QUEUE_FAMILY_IGNORED,
   4545 
   4546 				*m_colorTarget,
   4547 				{
   4548 					vk::VK_IMAGE_ASPECT_COLOR_BIT,
   4549 					0,	// Mip level
   4550 					1,	// Mip level count
   4551 					0,	// Layer
   4552 					1	// Layer count
   4553 				}
   4554 			};
   4555 			const vk::VkBufferMemoryBarrier bufferBarrier =
   4556 			{
   4557 				vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
   4558 				DE_NULL,
   4559 
   4560 				vk::VK_ACCESS_TRANSFER_WRITE_BIT,
   4561 				vk::VK_ACCESS_HOST_READ_BIT,
   4562 
   4563 				VK_QUEUE_FAMILY_IGNORED,
   4564 				VK_QUEUE_FAMILY_IGNORED,
   4565 				*dstBuffer,
   4566 				0,
   4567 				VK_WHOLE_SIZE
   4568 			};
   4569 			const vk::VkBufferImageCopy	region =
   4570 			{
   4571 				0,
   4572 				0, 0,
   4573 				{
   4574 					vk::VK_IMAGE_ASPECT_COLOR_BIT,
   4575 					0,	// mipLevel
   4576 					0,	// arrayLayer
   4577 					1	// layerCount
   4578 				},
   4579 				{ 0, 0, 0 },
   4580 				{
   4581 					(deUint32)m_targetWidth,
   4582 					(deUint32)m_targetHeight,
   4583 					1u
   4584 				}
   4585 			};
   4586 
   4587 			vkd.cmdPipelineBarrier(*commandBuffer, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0, 0, (const vk::VkMemoryBarrier*)DE_NULL, 0, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier);
   4588 			vkd.cmdCopyImageToBuffer(*commandBuffer, *m_colorTarget, vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *dstBuffer, 1, &region);
   4589 			vkd.cmdPipelineBarrier(*commandBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, (vk::VkDependencyFlags)0, 0, (const vk::VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
   4590 		}
   4591 
   4592 		VK_CHECK(vkd.endCommandBuffer(*commandBuffer));
   4593 		queueRun(vkd, queue, *commandBuffer);
   4594 
   4595 		{
   4596 			void* const	ptr		= mapMemory(vkd, device, *memory, 4 * m_targetWidth * m_targetHeight);
   4597 
   4598 			vk::invalidateMappedMemoryRange(vkd, device, *memory, 0,  4 * m_targetWidth * m_targetHeight);
   4599 
   4600 			{
   4601 				const deUint8* const			data		= (const deUint8*)ptr;
   4602 				const ConstPixelBufferAccess	resAccess	(TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8), m_targetWidth, m_targetHeight, 1, data);
   4603 				const ConstPixelBufferAccess&	refAccess	(verifyContext.getReferenceTarget().getAccess());
   4604 
   4605 				if (!tcu::intThresholdCompare(context.getLog(), (de::toString(commandIndex) + ":" + getName()).c_str(), (de::toString(commandIndex) + ":" + getName()).c_str(), refAccess, resAccess, UVec4(0), tcu::COMPARE_LOG_ON_ERROR))
   4606 					resultCollector.fail(de::toString(commandIndex) + ":" + getName() + " Image comparison failed");
   4607 			}
   4608 
   4609 			vkd.unmapMemory(device, *memory);
   4610 		}
   4611 	}
   4612 }
   4613 
   4614 struct PipelineResources
   4615 {
   4616 	vk::Move<vk::VkPipeline>			pipeline;
   4617 	vk::Move<vk::VkDescriptorSetLayout>	descriptorSetLayout;
   4618 	vk::Move<vk::VkPipelineLayout>		pipelineLayout;
   4619 };
   4620 
   4621 void createPipelineWithResources (const vk::DeviceInterface&							vkd,
   4622 								  const vk::VkDevice									device,
   4623 								  const vk::VkRenderPass								renderPass,
   4624 								  const deUint32										subpass,
   4625 								  const vk::VkShaderModule&								vertexShaderModule,
   4626 								  const vk::VkShaderModule&								fragmentShaderModule,
   4627 								  const deUint32										viewPortWidth,
   4628 								  const deUint32										viewPortHeight,
   4629 								  const vector<vk::VkVertexInputBindingDescription>&	vertexBindingDescriptions,
   4630 								  const vector<vk::VkVertexInputAttributeDescription>&	vertexAttributeDescriptions,
   4631 								  const vector<vk::VkDescriptorSetLayoutBinding>&		bindings,
   4632 								  const vk::VkPrimitiveTopology							topology,
   4633 								  deUint32												pushConstantRangeCount,
   4634 								  const vk::VkPushConstantRange*						pushConstantRanges,
   4635 								  PipelineResources&									resources)
   4636 {
   4637 	if (!bindings.empty())
   4638 	{
   4639 		const vk::VkDescriptorSetLayoutCreateInfo createInfo =
   4640 		{
   4641 			vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
   4642 			DE_NULL,
   4643 
   4644 			0u,
   4645 			(deUint32)bindings.size(),
   4646 			bindings.empty() ? DE_NULL : &bindings[0]
   4647 		};
   4648 
   4649 		resources.descriptorSetLayout = vk::createDescriptorSetLayout(vkd, device, &createInfo);
   4650 	}
   4651 
   4652 	{
   4653 		const vk::VkDescriptorSetLayout			descriptorSetLayout_	= *resources.descriptorSetLayout;
   4654 		const vk::VkPipelineLayoutCreateInfo	createInfo				=
   4655 		{
   4656 			vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
   4657 			DE_NULL,
   4658 			0,
   4659 
   4660 			resources.descriptorSetLayout ? 1u : 0u,
   4661 			resources.descriptorSetLayout ? &descriptorSetLayout_ : DE_NULL,
   4662 
   4663 			pushConstantRangeCount,
   4664 			pushConstantRanges
   4665 		};
   4666 
   4667 		resources.pipelineLayout = vk::createPipelineLayout(vkd, device, &createInfo);
   4668 	}
   4669 
   4670 	{
   4671 		const vk::VkPipelineShaderStageCreateInfo			shaderStages[]					=
   4672 		{
   4673 			{
   4674 				vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
   4675 				DE_NULL,
   4676 				0,
   4677 				vk::VK_SHADER_STAGE_VERTEX_BIT,
   4678 				vertexShaderModule,
   4679 				"main",
   4680 				DE_NULL
   4681 			},
   4682 			{
   4683 				vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
   4684 				DE_NULL,
   4685 				0,
   4686 				vk::VK_SHADER_STAGE_FRAGMENT_BIT,
   4687 				fragmentShaderModule,
   4688 				"main",
   4689 				DE_NULL
   4690 			}
   4691 		};
   4692 		const vk::VkPipelineDepthStencilStateCreateInfo		depthStencilState				=
   4693 		{
   4694 			vk::VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
   4695 			DE_NULL,
   4696 			0u,
   4697 			DE_FALSE,
   4698 			DE_FALSE,
   4699 			vk::VK_COMPARE_OP_ALWAYS,
   4700 			DE_FALSE,
   4701 			DE_FALSE,
   4702 			{
   4703 				vk::VK_STENCIL_OP_KEEP,
   4704 				vk::VK_STENCIL_OP_KEEP,
   4705 				vk::VK_STENCIL_OP_KEEP,
   4706 				vk::VK_COMPARE_OP_ALWAYS,
   4707 				0u,
   4708 				0u,
   4709 				0u,
   4710 			},
   4711 			{
   4712 				vk::VK_STENCIL_OP_KEEP,
   4713 				vk::VK_STENCIL_OP_KEEP,
   4714 				vk::VK_STENCIL_OP_KEEP,
   4715 				vk::VK_COMPARE_OP_ALWAYS,
   4716 				0u,
   4717 				0u,
   4718 				0u,
   4719 			},
   4720 			-1.0f,
   4721 			+1.0f
   4722 		};
   4723 		const vk::VkPipelineVertexInputStateCreateInfo		vertexInputState				=
   4724 		{
   4725 			vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
   4726 			DE_NULL,
   4727 			0u,
   4728 
   4729 			(deUint32)vertexBindingDescriptions.size(),
   4730 			vertexBindingDescriptions.empty() ? DE_NULL : &vertexBindingDescriptions[0],
   4731 
   4732 			(deUint32)vertexAttributeDescriptions.size(),
   4733 			vertexAttributeDescriptions.empty() ? DE_NULL : &vertexAttributeDescriptions[0]
   4734 		};
   4735 		const vk::VkPipelineInputAssemblyStateCreateInfo	inputAssemblyState				=
   4736 		{
   4737 			vk::VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
   4738 			DE_NULL,
   4739 			0,
   4740 			topology,
   4741 			VK_FALSE
   4742 		};
   4743 		const vk::VkViewport								viewports[]						=
   4744 		{
   4745 			{ 0.0f, 0.0f, (float)viewPortWidth, (float)viewPortHeight, 0.0f, 1.0f }
   4746 		};
   4747 		const vk::VkRect2D									scissors[]						=
   4748 		{
   4749 			{ { 0, 0 }, { (deUint32)viewPortWidth, (deUint32)viewPortHeight } }
   4750 		};
   4751 		const vk::VkPipelineViewportStateCreateInfo			viewportState					=
   4752 		{
   4753 			vk::VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
   4754 			DE_NULL,
   4755 			0,
   4756 			DE_LENGTH_OF_ARRAY(viewports),
   4757 			viewports,
   4758 			DE_LENGTH_OF_ARRAY(scissors),
   4759 			scissors
   4760 		};
   4761 		const vk::VkPipelineRasterizationStateCreateInfo	rasterState						=
   4762 		{
   4763 			vk::VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
   4764 			DE_NULL,
   4765 			0,
   4766 
   4767 			VK_TRUE,
   4768 			VK_FALSE,
   4769 			vk::VK_POLYGON_MODE_FILL,
   4770 			vk::VK_CULL_MODE_NONE,
   4771 			vk::VK_FRONT_FACE_COUNTER_CLOCKWISE,
   4772 			VK_FALSE,
   4773 			0.0f,
   4774 			0.0f,
   4775 			0.0f,
   4776 			1.0f
   4777 		};
   4778 		const vk::VkSampleMask								sampleMask						= ~0u;
   4779 		const vk::VkPipelineMultisampleStateCreateInfo		multisampleState				=
   4780 		{
   4781 			vk::VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
   4782 			DE_NULL,
   4783 			0,
   4784 
   4785 			vk::VK_SAMPLE_COUNT_1_BIT,
   4786 			VK_FALSE,
   4787 			0.0f,
   4788 			&sampleMask,
   4789 			VK_FALSE,
   4790 			VK_FALSE
   4791 		};
   4792 		const vk::VkPipelineColorBlendAttachmentState		attachments[]					=
   4793 		{
   4794 			{
   4795 				VK_FALSE,
   4796 				vk::VK_BLEND_FACTOR_ONE,
   4797 				vk::VK_BLEND_FACTOR_ZERO,
   4798 				vk::VK_BLEND_OP_ADD,
   4799 				vk::VK_BLEND_FACTOR_ONE,
   4800 				vk::VK_BLEND_FACTOR_ZERO,
   4801 				vk::VK_BLEND_OP_ADD,
   4802 				(vk::VK_COLOR_COMPONENT_R_BIT|
   4803 				 vk::VK_COLOR_COMPONENT_G_BIT|
   4804 				 vk::VK_COLOR_COMPONENT_B_BIT|
   4805 				 vk::VK_COLOR_COMPONENT_A_BIT)
   4806 			}
   4807 		};
   4808 		const vk::VkPipelineColorBlendStateCreateInfo		colorBlendState					=
   4809 		{
   4810 			vk::VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
   4811 			DE_NULL,
   4812 			0,
   4813 
   4814 			VK_FALSE,
   4815 			vk::VK_LOGIC_OP_COPY,
   4816 			DE_LENGTH_OF_ARRAY(attachments),
   4817 			attachments,
   4818 			{ 0.0f, 0.0f, 0.0f, 0.0f }
   4819 		};
   4820 		const vk::VkGraphicsPipelineCreateInfo				createInfo						=
   4821 		{
   4822 			vk::VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
   4823 			DE_NULL,
   4824 			0u,
   4825 
   4826 			DE_LENGTH_OF_ARRAY(shaderStages),
   4827 			shaderStages,
   4828 
   4829 			&vertexInputState,
   4830 			&inputAssemblyState,
   4831 			DE_NULL,
   4832 			&viewportState,
   4833 			&rasterState,
   4834 			&multisampleState,
   4835 			&depthStencilState,
   4836 			&colorBlendState,
   4837 			DE_NULL,
   4838 			*resources.pipelineLayout,
   4839 			renderPass,
   4840 			subpass,
   4841 			0,
   4842 			0
   4843 		};
   4844 
   4845 		resources.pipeline = vk::createGraphicsPipeline(vkd, device, 0, &createInfo);
   4846 	}
   4847 }
   4848 
   4849 class RenderIndexBuffer : public RenderPassCommand
   4850 {
   4851 public:
   4852 				RenderIndexBuffer	(void) {}
   4853 				~RenderIndexBuffer	(void) {}
   4854 
   4855 	const char*	getName				(void) const { return "RenderIndexBuffer"; }
   4856 	void		logPrepare			(TestLog&, size_t) const;
   4857 	void		logSubmit			(TestLog&, size_t) const;
   4858 	void		prepare				(PrepareRenderPassContext&);
   4859 	void		submit				(SubmitContext& context);
   4860 	void		verify				(VerifyRenderPassContext&, size_t);
   4861 
   4862 private:
   4863 	PipelineResources				m_resources;
   4864 	vk::VkDeviceSize				m_bufferSize;
   4865 };
   4866 
   4867 void RenderIndexBuffer::logPrepare (TestLog& log, size_t commandIndex) const
   4868 {
   4869 	log << TestLog::Message << commandIndex << ":" << getName() << " Create pipeline for render buffer as index buffer." << TestLog::EndMessage;
   4870 }
   4871 
   4872 void RenderIndexBuffer::logSubmit (TestLog& log, size_t commandIndex) const
   4873 {
   4874 	log << TestLog::Message << commandIndex << ":" << getName() << " Render using buffer as index buffer." << TestLog::EndMessage;
   4875 }
   4876 
   4877 void RenderIndexBuffer::prepare (PrepareRenderPassContext& context)
   4878 {
   4879 	const vk::DeviceInterface&				vkd						= context.getContext().getDeviceInterface();
   4880 	const vk::VkDevice						device					= context.getContext().getDevice();
   4881 	const vk::VkRenderPass					renderPass				= context.getRenderPass();
   4882 	const deUint32							subpass					= 0;
   4883 	const vk::Unique<vk::VkShaderModule>	vertexShaderModule		(vk::createShaderModule(vkd, device, context.getBinaryCollection().get("index-buffer.vert"), 0));
   4884 	const vk::Unique<vk::VkShaderModule>	fragmentShaderModule	(vk::createShaderModule(vkd, device, context.getBinaryCollection().get("render-white.frag"), 0));
   4885 
   4886 	createPipelineWithResources(vkd, device, renderPass, subpass, *vertexShaderModule, *fragmentShaderModule, context.getTargetWidth(), context.getTargetHeight(),
   4887 								vector<vk::VkVertexInputBindingDescription>(), vector<vk::VkVertexInputAttributeDescription>(), vector<vk::VkDescriptorSetLayoutBinding>(), vk::VK_PRIMITIVE_TOPOLOGY_POINT_LIST, 0u, DE_NULL, m_resources);
   4888 	m_bufferSize = context.getBufferSize();
   4889 }
   4890 
   4891 void RenderIndexBuffer::submit (SubmitContext& context)
   4892 {
   4893 	const vk::DeviceInterface&	vkd				= context.getContext().getDeviceInterface();
   4894 	const vk::VkCommandBuffer	commandBuffer	= context.getCommandBuffer();
   4895 
   4896 	vkd.cmdBindPipeline(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_resources.pipeline);
   4897 	vkd.cmdBindIndexBuffer(commandBuffer, context.getBuffer(), 0, vk::VK_INDEX_TYPE_UINT16);
   4898 	vkd.cmdDrawIndexed(commandBuffer, (deUint32)(context.getBufferSize() / 2), 1, 0, 0, 0);
   4899 }
   4900 
   4901 void RenderIndexBuffer::verify (VerifyRenderPassContext& context, size_t)
   4902 {
   4903 	for (size_t pos = 0; pos < (size_t)m_bufferSize / 2; pos++)
   4904 	{
   4905 		const deUint8 x  = context.getReference().get(pos * 2);
   4906 		const deUint8 y  = context.getReference().get((pos * 2) + 1);
   4907 
   4908 		context.getReferenceTarget().getAccess().setPixel(Vec4(1.0f, 1.0f, 1.0f, 1.0f), x, y);
   4909 	}
   4910 }
   4911 
   4912 class RenderVertexBuffer : public RenderPassCommand
   4913 {
   4914 public:
   4915 				RenderVertexBuffer	(void) {}
   4916 				~RenderVertexBuffer	(void) {}
   4917 
   4918 	const char*	getName				(void) const { return "RenderVertexBuffer"; }
   4919 	void		logPrepare			(TestLog&, size_t) const;
   4920 	void		logSubmit			(TestLog&, size_t) const;
   4921 	void		prepare				(PrepareRenderPassContext&);
   4922 	void		submit				(SubmitContext& context);
   4923 	void		verify				(VerifyRenderPassContext&, size_t);
   4924 
   4925 private:
   4926 	PipelineResources	m_resources;
   4927 	vk::VkDeviceSize	m_bufferSize;
   4928 };
   4929 
   4930 void RenderVertexBuffer::logPrepare (TestLog& log, size_t commandIndex) const
   4931 {
   4932 	log << TestLog::Message << commandIndex << ":" << getName() << " Create pipeline for render buffer as vertex buffer." << TestLog::EndMessage;
   4933 }
   4934 
   4935 void RenderVertexBuffer::logSubmit (TestLog& log, size_t commandIndex) const
   4936 {
   4937 	log << TestLog::Message << commandIndex << ":" << getName() << " Render using buffer as vertex buffer." << TestLog::EndMessage;
   4938 }
   4939 
   4940 void RenderVertexBuffer::prepare (PrepareRenderPassContext& context)
   4941 {
   4942 	const vk::DeviceInterface&						vkd						= context.getContext().getDeviceInterface();
   4943 	const vk::VkDevice								device					= context.getContext().getDevice();
   4944 	const vk::VkRenderPass							renderPass				= context.getRenderPass();
   4945 	const deUint32									subpass					= 0;
   4946 	const vk::Unique<vk::VkShaderModule>			vertexShaderModule		(vk::createShaderModule(vkd, device, context.getBinaryCollection().get("vertex-buffer.vert"), 0));
   4947 	const vk::Unique<vk::VkShaderModule>			fragmentShaderModule	(vk::createShaderModule(vkd, device, context.getBinaryCollection().get("render-white.frag"), 0));
   4948 
   4949 	vector<vk::VkVertexInputAttributeDescription>	vertexAttributeDescriptions;
   4950 	vector<vk::VkVertexInputBindingDescription>		vertexBindingDescriptions;
   4951 
   4952 	{
   4953 		const vk::VkVertexInputBindingDescription vertexBindingDescription =
   4954 			{
   4955 				0,
   4956 				2,
   4957 				vk::VK_VERTEX_INPUT_RATE_VERTEX
   4958 			};
   4959 
   4960 		vertexBindingDescriptions.push_back(vertexBindingDescription);
   4961 	}
   4962 	{
   4963 		const vk::VkVertexInputAttributeDescription vertexAttributeDescription =
   4964 		{
   4965 			0,
   4966 			0,
   4967 			vk::VK_FORMAT_R8G8_UNORM,
   4968 			0
   4969 		};
   4970 
   4971 		vertexAttributeDescriptions.push_back(vertexAttributeDescription);
   4972 	}
   4973 	createPipelineWithResources(vkd, device, renderPass, subpass, *vertexShaderModule, *fragmentShaderModule, context.getTargetWidth(), context.getTargetHeight(),
   4974 								vertexBindingDescriptions, vertexAttributeDescriptions, vector<vk::VkDescriptorSetLayoutBinding>(), vk::VK_PRIMITIVE_TOPOLOGY_POINT_LIST, 0u, DE_NULL, m_resources);
   4975 
   4976 	m_bufferSize = context.getBufferSize();
   4977 }
   4978 
   4979 void RenderVertexBuffer::submit (SubmitContext& context)
   4980 {
   4981 	const vk::DeviceInterface&	vkd				= context.getContext().getDeviceInterface();
   4982 	const vk::VkCommandBuffer	commandBuffer	= context.getCommandBuffer();
   4983 	const vk::VkDeviceSize		offset			= 0;
   4984 	const vk::VkBuffer			buffer			= context.getBuffer();
   4985 
   4986 	vkd.cmdBindPipeline(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_resources.pipeline);
   4987 	vkd.cmdBindVertexBuffers(commandBuffer, 0, 1, &buffer, &offset);
   4988 	vkd.cmdDraw(commandBuffer, (deUint32)(context.getBufferSize() / 2), 1, 0, 0);
   4989 }
   4990 
   4991 void RenderVertexBuffer::verify (VerifyRenderPassContext& context, size_t)
   4992 {
   4993 	for (size_t pos = 0; pos < (size_t)m_bufferSize / 2; pos++)
   4994 	{
   4995 		const deUint8 x  = context.getReference().get(pos * 2);
   4996 		const deUint8 y  = context.getReference().get((pos * 2) + 1);
   4997 
   4998 		context.getReferenceTarget().getAccess().setPixel(Vec4(1.0f, 1.0f, 1.0f, 1.0f), x, y);
   4999 	}
   5000 }
   5001 
   5002 class RenderVertexUniformBuffer : public RenderPassCommand
   5003 {
   5004 public:
   5005 									RenderVertexUniformBuffer	(void) {}
   5006 									~RenderVertexUniformBuffer	(void);
   5007 
   5008 	const char*						getName						(void) const { return "RenderVertexUniformBuffer"; }
   5009 	void							logPrepare					(TestLog&, size_t) const;
   5010 	void							logSubmit					(TestLog&, size_t) const;
   5011 	void							prepare						(PrepareRenderPassContext&);
   5012 	void							submit						(SubmitContext& context);
   5013 	void							verify						(VerifyRenderPassContext&, size_t);
   5014 
   5015 private:
   5016 	PipelineResources				m_resources;
   5017 	vk::Move<vk::VkDescriptorPool>	m_descriptorPool;
   5018 	vector<vk::VkDescriptorSet>		m_descriptorSets;
   5019 
   5020 	vk::VkDeviceSize				m_bufferSize;
   5021 };
   5022 
   5023 RenderVertexUniformBuffer::~RenderVertexUniformBuffer (void)
   5024 {
   5025 }
   5026 
   5027 void RenderVertexUniformBuffer::logPrepare (TestLog& log, size_t commandIndex) const
   5028 {
   5029 	log << TestLog::Message << commandIndex << ":" << getName() << " Create pipeline for render buffer as uniform buffer." << TestLog::EndMessage;
   5030 }
   5031 
   5032 void RenderVertexUniformBuffer::logSubmit (TestLog& log, size_t commandIndex) const
   5033 {
   5034 	log << TestLog::Message << commandIndex << ":" << getName() << " Render using buffer as uniform buffer." << TestLog::EndMessage;
   5035 }
   5036 
   5037 void RenderVertexUniformBuffer::prepare (PrepareRenderPassContext& context)
   5038 {
   5039 	const vk::DeviceInterface&					vkd						= context.getContext().getDeviceInterface();
   5040 	const vk::VkDevice							device					= context.getContext().getDevice();
   5041 	const vk::VkRenderPass						renderPass				= context.getRenderPass();
   5042 	const deUint32								subpass					= 0;
   5043 	const vk::Unique<vk::VkShaderModule>		vertexShaderModule		(vk::createShaderModule(vkd, device, context.getBinaryCollection().get("uniform-buffer.vert"), 0));
   5044 	const vk::Unique<vk::VkShaderModule>		fragmentShaderModule	(vk::createShaderModule(vkd, device, context.getBinaryCollection().get("render-white.frag"), 0));
   5045 	vector<vk::VkDescriptorSetLayoutBinding>	bindings;
   5046 
   5047 	m_bufferSize = context.getBufferSize();
   5048 
   5049 	{
   5050 		const vk::VkDescriptorSetLayoutBinding binding =
   5051 		{
   5052 			0u,
   5053 			vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
   5054 			1,
   5055 			vk::VK_SHADER_STAGE_VERTEX_BIT,
   5056 			DE_NULL
   5057 		};
   5058 
   5059 		bindings.push_back(binding);
   5060 	}
   5061 
   5062 	createPipelineWithResources(vkd, device, renderPass, subpass, *vertexShaderModule, *fragmentShaderModule, context.getTargetWidth(), context.getTargetHeight(),
   5063 								vector<vk::VkVertexInputBindingDescription>(), vector<vk::VkVertexInputAttributeDescription>(), bindings, vk::VK_PRIMITIVE_TOPOLOGY_POINT_LIST, 0u, DE_NULL, m_resources);
   5064 
   5065 	{
   5066 		const deUint32							descriptorCount	= (deUint32)(divRoundUp(m_bufferSize, (vk::VkDeviceSize)MAX_UNIFORM_BUFFER_SIZE));
   5067 		const vk::VkDescriptorPoolSize			poolSizes		=
   5068 		{
   5069 			vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
   5070 			descriptorCount
   5071 		};
   5072 		const vk::VkDescriptorPoolCreateInfo	createInfo		=
   5073 		{
   5074 			vk::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
   5075 			DE_NULL,
   5076 			vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
   5077 
   5078 			descriptorCount,
   5079 			1u,
   5080 			&poolSizes,
   5081 		};
   5082 
   5083 		m_descriptorPool = vk::createDescriptorPool(vkd, device, &createInfo);
   5084 		m_descriptorSets.resize(descriptorCount);
   5085 	}
   5086 
   5087 	for (size_t descriptorSetNdx = 0; descriptorSetNdx < m_descriptorSets.size(); descriptorSetNdx++)
   5088 	{
   5089 		const vk::VkDescriptorSetLayout			layout			= *m_resources.descriptorSetLayout;
   5090 		const vk::VkDescriptorSetAllocateInfo	allocateInfo	=
   5091 		{
   5092 			vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
   5093 			DE_NULL,
   5094 
   5095 			*m_descriptorPool,
   5096 			1,
   5097 			&layout
   5098 		};
   5099 
   5100 		m_descriptorSets[descriptorSetNdx] = vk::allocateDescriptorSet(vkd, device, &allocateInfo).disown();
   5101 
   5102 		{
   5103 			const vk::VkDescriptorBufferInfo		bufferInfo	=
   5104 			{
   5105 				context.getBuffer(),
   5106 				(vk::VkDeviceSize)(descriptorSetNdx * (size_t)MAX_UNIFORM_BUFFER_SIZE),
   5107 				m_bufferSize < (descriptorSetNdx + 1) * (vk::VkDeviceSize)MAX_UNIFORM_BUFFER_SIZE
   5108 					? m_bufferSize - descriptorSetNdx * (vk::VkDeviceSize)MAX_UNIFORM_BUFFER_SIZE
   5109 					: (vk::VkDeviceSize)MAX_UNIFORM_BUFFER_SIZE
   5110 			};
   5111 			const vk::VkWriteDescriptorSet			write		=
   5112 			{
   5113 				vk::VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
   5114 				DE_NULL,
   5115 				m_descriptorSets[descriptorSetNdx],
   5116 				0u,
   5117 				0u,
   5118 				1u,
   5119 				vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
   5120 				DE_NULL,
   5121 				&bufferInfo,
   5122 				DE_NULL,
   5123 			};
   5124 
   5125 			vkd.updateDescriptorSets(device, 1u, &write, 0u, DE_NULL);
   5126 		}
   5127 	}
   5128 }
   5129 
   5130 void RenderVertexUniformBuffer::submit (SubmitContext& context)
   5131 {
   5132 	const vk::DeviceInterface&	vkd				= context.getContext().getDeviceInterface();
   5133 	const vk::VkCommandBuffer	commandBuffer	= context.getCommandBuffer();
   5134 
   5135 	vkd.cmdBindPipeline(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_resources.pipeline);
   5136 
   5137 	for (size_t descriptorSetNdx = 0; descriptorSetNdx < m_descriptorSets.size(); descriptorSetNdx++)
   5138 	{
   5139 		const size_t	size	= (size_t)(m_bufferSize < (descriptorSetNdx + 1) * (vk::VkDeviceSize)MAX_UNIFORM_BUFFER_SIZE
   5140 								? m_bufferSize - descriptorSetNdx * (vk::VkDeviceSize)MAX_UNIFORM_BUFFER_SIZE
   5141 								: (size_t)MAX_UNIFORM_BUFFER_SIZE);
   5142 		const deUint32	count	= (deUint32)(size / 2);
   5143 
   5144 		vkd.cmdBindDescriptorSets(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_resources.pipelineLayout, 0u, 1u, &m_descriptorSets[descriptorSetNdx], 0u, DE_NULL);
   5145 		vkd.cmdDraw(commandBuffer, count, 1, 0, 0);
   5146 	}
   5147 }
   5148 
   5149 void RenderVertexUniformBuffer::verify (VerifyRenderPassContext& context, size_t)
   5150 {
   5151 	for (size_t descriptorSetNdx = 0; descriptorSetNdx < m_descriptorSets.size(); descriptorSetNdx++)
   5152 	{
   5153 		const size_t	offset	= descriptorSetNdx * MAX_UNIFORM_BUFFER_SIZE;
   5154 		const size_t	size	= (size_t)(m_bufferSize < (descriptorSetNdx + 1) * (vk::VkDeviceSize)MAX_UNIFORM_BUFFER_SIZE
   5155 								? m_bufferSize - descriptorSetNdx * (vk::VkDeviceSize)MAX_UNIFORM_BUFFER_SIZE
   5156 								: (size_t)MAX_UNIFORM_BUFFER_SIZE);
   5157 		const size_t	count	= size / 2;
   5158 
   5159 		for (size_t pos = 0; pos < count; pos++)
   5160 		{
   5161 			const deUint8 x  = context.getReference().get(offset + pos * 2);
   5162 			const deUint8 y  = context.getReference().get(offset + (pos * 2) + 1);
   5163 
   5164 			context.getReferenceTarget().getAccess().setPixel(Vec4(1.0f, 1.0f, 1.0f, 1.0f), x, y);
   5165 		}
   5166 	}
   5167 }
   5168 
   5169 class RenderVertexUniformTexelBuffer : public RenderPassCommand
   5170 {
   5171 public:
   5172 				RenderVertexUniformTexelBuffer	(void) {}
   5173 				~RenderVertexUniformTexelBuffer	(void);
   5174 
   5175 	const char*	getName							(void) const { return "RenderVertexUniformTexelBuffer"; }
   5176 	void		logPrepare						(TestLog&, size_t) const;
   5177 	void		logSubmit						(TestLog&, size_t) const;
   5178 	void		prepare							(PrepareRenderPassContext&);
   5179 	void		submit							(SubmitContext& context);
   5180 	void		verify							(VerifyRenderPassContext&, size_t);
   5181 
   5182 private:
   5183 	PipelineResources				m_resources;
   5184 	vk::Move<vk::VkDescriptorPool>	m_descriptorPool;
   5185 	vector<vk::VkDescriptorSet>		m_descriptorSets;
   5186 	vector<vk::VkBufferView>		m_bufferViews;
   5187 
   5188 	const vk::DeviceInterface*		m_vkd;
   5189 	vk::VkDevice					m_device;
   5190 	vk::VkDeviceSize				m_bufferSize;
   5191 	deUint32						m_maxUniformTexelCount;
   5192 };
   5193 
   5194 RenderVertexUniformTexelBuffer::~RenderVertexUniformTexelBuffer (void)
   5195 {
   5196 	for (size_t bufferViewNdx = 0; bufferViewNdx < m_bufferViews.size(); bufferViewNdx++)
   5197 	{
   5198 		if (!!m_bufferViews[bufferViewNdx])
   5199 		{
   5200 			m_vkd->destroyBufferView(m_device, m_bufferViews[bufferViewNdx], DE_NULL);
   5201 			m_bufferViews[bufferViewNdx] = (vk::VkBufferView)0;
   5202 		}
   5203 	}
   5204 }
   5205 
   5206 void RenderVertexUniformTexelBuffer::logPrepare (TestLog& log, size_t commandIndex) const
   5207 {
   5208 	log << TestLog::Message << commandIndex << ":" << getName() << " Create pipeline for render buffer as uniform buffer." << TestLog::EndMessage;
   5209 }
   5210 
   5211 void RenderVertexUniformTexelBuffer::logSubmit (TestLog& log, size_t commandIndex) const
   5212 {
   5213 	log << TestLog::Message << commandIndex << ":" << getName() << " Render using buffer as uniform buffer." << TestLog::EndMessage;
   5214 }
   5215 
   5216 void RenderVertexUniformTexelBuffer::prepare (PrepareRenderPassContext& context)
   5217 {
   5218 	const vk::InstanceInterface&				vki						= context.getContext().getInstanceInterface();
   5219 	const vk::VkPhysicalDevice					physicalDevice			= context.getContext().getPhysicalDevice();
   5220 	const vk::DeviceInterface&					vkd						= context.getContext().getDeviceInterface();
   5221 	const vk::VkDevice							device					= context.getContext().getDevice();
   5222 	const vk::VkRenderPass						renderPass				= context.getRenderPass();
   5223 	const deUint32								subpass					= 0;
   5224 	const vk::Unique<vk::VkShaderModule>		vertexShaderModule		(vk::createShaderModule(vkd, device, context.getBinaryCollection().get("uniform-texel-buffer.vert"), 0));
   5225 	const vk::Unique<vk::VkShaderModule>		fragmentShaderModule	(vk::createShaderModule(vkd, device, context.getBinaryCollection().get("render-white.frag"), 0));
   5226 	vector<vk::VkDescriptorSetLayoutBinding>	bindings;
   5227 
   5228 	m_device				= device;
   5229 	m_vkd					= &vkd;
   5230 	m_bufferSize			= context.getBufferSize();
   5231 	m_maxUniformTexelCount	= vk::getPhysicalDeviceProperties(vki, physicalDevice).limits.maxTexelBufferElements;
   5232 
   5233 	{
   5234 		const vk::VkDescriptorSetLayoutBinding binding =
   5235 		{
   5236 			0u,
   5237 			vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
   5238 			1,
   5239 			vk::VK_SHADER_STAGE_VERTEX_BIT,
   5240 			DE_NULL
   5241 		};
   5242 
   5243 		bindings.push_back(binding);
   5244 	}
   5245 
   5246 	createPipelineWithResources(vkd, device, renderPass, subpass, *vertexShaderModule, *fragmentShaderModule, context.getTargetWidth(), context.getTargetHeight(),
   5247 								vector<vk::VkVertexInputBindingDescription>(), vector<vk::VkVertexInputAttributeDescription>(), bindings, vk::VK_PRIMITIVE_TOPOLOGY_POINT_LIST, 0u, DE_NULL, m_resources);
   5248 
   5249 	{
   5250 		const deUint32							descriptorCount	= (deUint32)(divRoundUp(m_bufferSize, (vk::VkDeviceSize)m_maxUniformTexelCount * 2));
   5251 		const vk::VkDescriptorPoolSize			poolSizes		=
   5252 		{
   5253 			vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
   5254 			descriptorCount
   5255 		};
   5256 		const vk::VkDescriptorPoolCreateInfo	createInfo		=
   5257 		{
   5258 			vk::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
   5259 			DE_NULL,
   5260 			vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
   5261 
   5262 			descriptorCount,
   5263 			1u,
   5264 			&poolSizes,
   5265 		};
   5266 
   5267 		m_descriptorPool = vk::createDescriptorPool(vkd, device, &createInfo);
   5268 		m_descriptorSets.resize(descriptorCount, (vk::VkDescriptorSet)0);
   5269 		m_bufferViews.resize(descriptorCount, (vk::VkBufferView)0);
   5270 	}
   5271 
   5272 	for (size_t descriptorSetNdx = 0; descriptorSetNdx < m_descriptorSets.size(); descriptorSetNdx++)
   5273 	{
   5274 		const deUint32							count			= (deUint32)(m_bufferSize < (descriptorSetNdx + 1) * m_maxUniformTexelCount * 2
   5275 																? m_bufferSize - descriptorSetNdx * m_maxUniformTexelCount * 2
   5276 																: m_maxUniformTexelCount * 2) / 2;
   5277 		const vk::VkDescriptorSetLayout			layout			= *m_resources.descriptorSetLayout;
   5278 		const vk::VkDescriptorSetAllocateInfo	allocateInfo	=
   5279 		{
   5280 			vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
   5281 			DE_NULL,
   5282 
   5283 			*m_descriptorPool,
   5284 			1,
   5285 			&layout
   5286 		};
   5287 
   5288 		m_descriptorSets[descriptorSetNdx] = vk::allocateDescriptorSet(vkd, device, &allocateInfo).disown();
   5289 
   5290 		{
   5291 			const vk::VkBufferViewCreateInfo createInfo =
   5292 			{
   5293 				vk::VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
   5294 				DE_NULL,
   5295 				0u,
   5296 
   5297 				context.getBuffer(),
   5298 				vk::VK_FORMAT_R16_UINT,
   5299 				descriptorSetNdx * m_maxUniformTexelCount * 2,
   5300 				count * 2
   5301 			};
   5302 
   5303 			VK_CHECK(vkd.createBufferView(device, &createInfo, DE_NULL, &m_bufferViews[descriptorSetNdx]));
   5304 		}
   5305 
   5306 		{
   5307 			const vk::VkWriteDescriptorSet			write		=
   5308 			{
   5309 				vk::VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
   5310 				DE_NULL,
   5311 				m_descriptorSets[descriptorSetNdx],
   5312 				0u,
   5313 				0u,
   5314 				1u,
   5315 				vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
   5316 				DE_NULL,
   5317 				DE_NULL,
   5318 				&m_bufferViews[descriptorSetNdx]
   5319 			};
   5320 
   5321 			vkd.updateDescriptorSets(device, 1u, &write, 0u, DE_NULL);
   5322 		}
   5323 	}
   5324 }
   5325 
   5326 void RenderVertexUniformTexelBuffer::submit (SubmitContext& context)
   5327 {
   5328 	const vk::DeviceInterface&	vkd				= context.getContext().getDeviceInterface();
   5329 	const vk::VkCommandBuffer	commandBuffer	= context.getCommandBuffer();
   5330 
   5331 	vkd.cmdBindPipeline(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_resources.pipeline);
   5332 
   5333 	for (size_t descriptorSetNdx = 0; descriptorSetNdx < m_descriptorSets.size(); descriptorSetNdx++)
   5334 	{
   5335 		const deUint32 count	= (deUint32)(m_bufferSize < (descriptorSetNdx + 1) * m_maxUniformTexelCount * 2
   5336 								? m_bufferSize - descriptorSetNdx * m_maxUniformTexelCount * 2
   5337 								: m_maxUniformTexelCount * 2) / 2;
   5338 
   5339 		vkd.cmdBindDescriptorSets(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_resources.pipelineLayout, 0u, 1u, &m_descriptorSets[descriptorSetNdx], 0u, DE_NULL);
   5340 		vkd.cmdDraw(commandBuffer, count, 1, 0, 0);
   5341 	}
   5342 }
   5343 
   5344 void RenderVertexUniformTexelBuffer::verify (VerifyRenderPassContext& context, size_t)
   5345 {
   5346 	for (size_t descriptorSetNdx = 0; descriptorSetNdx < m_descriptorSets.size(); descriptorSetNdx++)
   5347 	{
   5348 		const size_t	offset	= descriptorSetNdx * m_maxUniformTexelCount * 2;
   5349 		const deUint32	count	= (deUint32)(m_bufferSize < (descriptorSetNdx + 1) * m_maxUniformTexelCount * 2
   5350 								? m_bufferSize - descriptorSetNdx * m_maxUniformTexelCount * 2
   5351 								: m_maxUniformTexelCount * 2) / 2;
   5352 
   5353 		for (size_t pos = 0; pos < (size_t)count; pos++)
   5354 		{
   5355 			const deUint8 x  = context.getReference().get(offset + pos * 2);
   5356 			const deUint8 y  = context.getReference().get(offset + (pos * 2) + 1);
   5357 
   5358 			context.getReferenceTarget().getAccess().setPixel(Vec4(1.0f, 1.0f, 1.0f, 1.0f), x, y);
   5359 		}
   5360 	}
   5361 }
   5362 
   5363 class RenderVertexStorageBuffer : public RenderPassCommand
   5364 {
   5365 public:
   5366 				RenderVertexStorageBuffer	(void) {}
   5367 				~RenderVertexStorageBuffer	(void);
   5368 
   5369 	const char*	getName						(void) const { return "RenderVertexStorageBuffer"; }
   5370 	void		logPrepare					(TestLog&, size_t) const;
   5371 	void		logSubmit					(TestLog&, size_t) const;
   5372 	void		prepare						(PrepareRenderPassContext&);
   5373 	void		submit						(SubmitContext& context);
   5374 	void		verify						(VerifyRenderPassContext&, size_t);
   5375 
   5376 private:
   5377 	PipelineResources				m_resources;
   5378 	vk::Move<vk::VkDescriptorPool>	m_descriptorPool;
   5379 	vector<vk::VkDescriptorSet>		m_descriptorSets;
   5380 
   5381 	vk::VkDeviceSize				m_bufferSize;
   5382 };
   5383 
   5384 RenderVertexStorageBuffer::~RenderVertexStorageBuffer (void)
   5385 {
   5386 }
   5387 
   5388 void RenderVertexStorageBuffer::logPrepare (TestLog& log, size_t commandIndex) const
   5389 {
   5390 	log << TestLog::Message << commandIndex << ":" << getName() << " Create pipeline for render buffer as storage buffer." << TestLog::EndMessage;
   5391 }
   5392 
   5393 void RenderVertexStorageBuffer::logSubmit (TestLog& log, size_t commandIndex) const
   5394 {
   5395 	log << TestLog::Message << commandIndex << ":" << getName() << " Render using buffer as storage buffer." << TestLog::EndMessage;
   5396 }
   5397 
   5398 void RenderVertexStorageBuffer::prepare (PrepareRenderPassContext& context)
   5399 {
   5400 	const vk::DeviceInterface&					vkd						= context.getContext().getDeviceInterface();
   5401 	const vk::VkDevice							device					= context.getContext().getDevice();
   5402 	const vk::VkRenderPass						renderPass				= context.getRenderPass();
   5403 	const deUint32								subpass					= 0;
   5404 	const vk::Unique<vk::VkShaderModule>		vertexShaderModule		(vk::createShaderModule(vkd, device, context.getBinaryCollection().get("storage-buffer.vert"), 0));
   5405 	const vk::Unique<vk::VkShaderModule>		fragmentShaderModule	(vk::createShaderModule(vkd, device, context.getBinaryCollection().get("render-white.frag"), 0));
   5406 	vector<vk::VkDescriptorSetLayoutBinding>	bindings;
   5407 
   5408 	m_bufferSize = context.getBufferSize();
   5409 
   5410 	{
   5411 		const vk::VkDescriptorSetLayoutBinding binding =
   5412 		{
   5413 			0u,
   5414 			vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
   5415 			1,
   5416 			vk::VK_SHADER_STAGE_VERTEX_BIT,
   5417 			DE_NULL
   5418 		};
   5419 
   5420 		bindings.push_back(binding);
   5421 	}
   5422 
   5423 	createPipelineWithResources(vkd, device, renderPass, subpass, *vertexShaderModule, *fragmentShaderModule, context.getTargetWidth(), context.getTargetHeight(),
   5424 								vector<vk::VkVertexInputBindingDescription>(), vector<vk::VkVertexInputAttributeDescription>(), bindings, vk::VK_PRIMITIVE_TOPOLOGY_POINT_LIST, 0u, DE_NULL, m_resources);
   5425 
   5426 	{
   5427 		const deUint32							descriptorCount	= (deUint32)(divRoundUp(m_bufferSize, (vk::VkDeviceSize)MAX_STORAGE_BUFFER_SIZE));
   5428 		const vk::VkDescriptorPoolSize			poolSizes		=
   5429 		{
   5430 			vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
   5431 			descriptorCount
   5432 		};
   5433 		const vk::VkDescriptorPoolCreateInfo	createInfo		=
   5434 		{
   5435 			vk::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
   5436 			DE_NULL,
   5437 			vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
   5438 
   5439 			descriptorCount,
   5440 			1u,
   5441 			&poolSizes,
   5442 		};
   5443 
   5444 		m_descriptorPool = vk::createDescriptorPool(vkd, device, &createInfo);
   5445 		m_descriptorSets.resize(descriptorCount);
   5446 	}
   5447 
   5448 	for (size_t descriptorSetNdx = 0; descriptorSetNdx < m_descriptorSets.size(); descriptorSetNdx++)
   5449 	{
   5450 		const vk::VkDescriptorSetLayout			layout			= *m_resources.descriptorSetLayout;
   5451 		const vk::VkDescriptorSetAllocateInfo	allocateInfo	=
   5452 		{
   5453 			vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
   5454 			DE_NULL,
   5455 
   5456 			*m_descriptorPool,
   5457 			1,
   5458 			&layout
   5459 		};
   5460 
   5461 		m_descriptorSets[descriptorSetNdx] = vk::allocateDescriptorSet(vkd, device, &allocateInfo).disown();
   5462 
   5463 		{
   5464 			const vk::VkDescriptorBufferInfo		bufferInfo	=
   5465 			{
   5466 				context.getBuffer(),
   5467 				descriptorSetNdx * MAX_STORAGE_BUFFER_SIZE,
   5468 				de::min(m_bufferSize - descriptorSetNdx * MAX_STORAGE_BUFFER_SIZE,  (vk::VkDeviceSize)MAX_STORAGE_BUFFER_SIZE)
   5469 			};
   5470 			const vk::VkWriteDescriptorSet			write		=
   5471 			{
   5472 				vk::VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
   5473 				DE_NULL,
   5474 				m_descriptorSets[descriptorSetNdx],
   5475 				0u,
   5476 				0u,
   5477 				1u,
   5478 				vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
   5479 				DE_NULL,
   5480 				&bufferInfo,
   5481 				DE_NULL,
   5482 			};
   5483 
   5484 			vkd.updateDescriptorSets(device, 1u, &write, 0u, DE_NULL);
   5485 		}
   5486 	}
   5487 }
   5488 
   5489 void RenderVertexStorageBuffer::submit (SubmitContext& context)
   5490 {
   5491 	const vk::DeviceInterface&	vkd				= context.getContext().getDeviceInterface();
   5492 	const vk::VkCommandBuffer	commandBuffer	= context.getCommandBuffer();
   5493 
   5494 	vkd.cmdBindPipeline(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_resources.pipeline);
   5495 
   5496 	for (size_t descriptorSetNdx = 0; descriptorSetNdx < m_descriptorSets.size(); descriptorSetNdx++)
   5497 	{
   5498 		const size_t size	= m_bufferSize < (descriptorSetNdx + 1) * MAX_STORAGE_BUFFER_SIZE
   5499 							? (size_t)(m_bufferSize - descriptorSetNdx * MAX_STORAGE_BUFFER_SIZE)
   5500 							: (size_t)(MAX_STORAGE_BUFFER_SIZE);
   5501 
   5502 		vkd.cmdBindDescriptorSets(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_resources.pipelineLayout, 0u, 1u, &m_descriptorSets[descriptorSetNdx], 0u, DE_NULL);
   5503 		vkd.cmdDraw(commandBuffer, (deUint32)(size / 2), 1, 0, 0);
   5504 	}
   5505 }
   5506 
   5507 void RenderVertexStorageBuffer::verify (VerifyRenderPassContext& context, size_t)
   5508 {
   5509 	for (size_t descriptorSetNdx = 0; descriptorSetNdx < m_descriptorSets.size(); descriptorSetNdx++)
   5510 	{
   5511 		const size_t offset	= descriptorSetNdx * MAX_STORAGE_BUFFER_SIZE;
   5512 		const size_t size	= m_bufferSize < (descriptorSetNdx + 1) * MAX_STORAGE_BUFFER_SIZE
   5513 							? (size_t)(m_bufferSize - descriptorSetNdx * MAX_STORAGE_BUFFER_SIZE)
   5514 							: (size_t)(MAX_STORAGE_BUFFER_SIZE);
   5515 
   5516 		for (size_t pos = 0; pos < size / 2; pos++)
   5517 		{
   5518 			const deUint8 x  = context.getReference().get(offset + pos * 2);
   5519 			const deUint8 y  = context.getReference().get(offset + (pos * 2) + 1);
   5520 
   5521 			context.getReferenceTarget().getAccess().setPixel(Vec4(1.0f, 1.0f, 1.0f, 1.0f), x, y);
   5522 		}
   5523 	}
   5524 }
   5525 
   5526 class RenderVertexStorageTexelBuffer : public RenderPassCommand
   5527 {
   5528 public:
   5529 				RenderVertexStorageTexelBuffer	(void) {}
   5530 				~RenderVertexStorageTexelBuffer	(void);
   5531 
   5532 	const char*	getName							(void) const { return "RenderVertexStorageTexelBuffer"; }
   5533 	void		logPrepare						(TestLog&, size_t) const;
   5534 	void		logSubmit						(TestLog&, size_t) const;
   5535 	void		prepare							(PrepareRenderPassContext&);
   5536 	void		submit							(SubmitContext& context);
   5537 	void		verify							(VerifyRenderPassContext&, size_t);
   5538 
   5539 private:
   5540 	PipelineResources				m_resources;
   5541 	vk::Move<vk::VkDescriptorPool>	m_descriptorPool;
   5542 	vector<vk::VkDescriptorSet>		m_descriptorSets;
   5543 	vector<vk::VkBufferView>		m_bufferViews;
   5544 
   5545 	const vk::DeviceInterface*		m_vkd;
   5546 	vk::VkDevice					m_device;
   5547 	vk::VkDeviceSize				m_bufferSize;
   5548 	deUint32						m_maxStorageTexelCount;
   5549 };
   5550 
   5551 RenderVertexStorageTexelBuffer::~RenderVertexStorageTexelBuffer (void)
   5552 {
   5553 	for (size_t bufferViewNdx = 0; bufferViewNdx < m_bufferViews.size(); bufferViewNdx++)
   5554 	{
   5555 		if (!!m_bufferViews[bufferViewNdx])
   5556 		{
   5557 			m_vkd->destroyBufferView(m_device, m_bufferViews[bufferViewNdx], DE_NULL);
   5558 			m_bufferViews[bufferViewNdx] = (vk::VkBufferView)0;
   5559 		}
   5560 	}
   5561 }
   5562 
   5563 void RenderVertexStorageTexelBuffer::logPrepare (TestLog& log, size_t commandIndex) const
   5564 {
   5565 	log << TestLog::Message << commandIndex << ":" << getName() << " Create pipeline for render buffer as storage buffer." << TestLog::EndMessage;
   5566 }
   5567 
   5568 void RenderVertexStorageTexelBuffer::logSubmit (TestLog& log, size_t commandIndex) const
   5569 {
   5570 	log << TestLog::Message << commandIndex << ":" << getName() << " Render using buffer as storage buffer." << TestLog::EndMessage;
   5571 }
   5572 
   5573 void RenderVertexStorageTexelBuffer::prepare (PrepareRenderPassContext& context)
   5574 {
   5575 	const vk::InstanceInterface&				vki						= context.getContext().getInstanceInterface();
   5576 	const vk::VkPhysicalDevice					physicalDevice			= context.getContext().getPhysicalDevice();
   5577 	const vk::DeviceInterface&					vkd						= context.getContext().getDeviceInterface();
   5578 	const vk::VkDevice							device					= context.getContext().getDevice();
   5579 	const vk::VkRenderPass						renderPass				= context.getRenderPass();
   5580 	const deUint32								subpass					= 0;
   5581 	const vk::Unique<vk::VkShaderModule>		vertexShaderModule		(vk::createShaderModule(vkd, device, context.getBinaryCollection().get("storage-texel-buffer.vert"), 0));
   5582 	const vk::Unique<vk::VkShaderModule>		fragmentShaderModule	(vk::createShaderModule(vkd, device, context.getBinaryCollection().get("render-white.frag"), 0));
   5583 	vector<vk::VkDescriptorSetLayoutBinding>	bindings;
   5584 
   5585 	m_device				= device;
   5586 	m_vkd					= &vkd;
   5587 	m_bufferSize			= context.getBufferSize();
   5588 	m_maxStorageTexelCount	= vk::getPhysicalDeviceProperties(vki, physicalDevice).limits.maxTexelBufferElements;
   5589 
   5590 	{
   5591 		const vk::VkDescriptorSetLayoutBinding binding =
   5592 		{
   5593 			0u,
   5594 			vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
   5595 			1,
   5596 			vk::VK_SHADER_STAGE_VERTEX_BIT,
   5597 			DE_NULL
   5598 		};
   5599 
   5600 		bindings.push_back(binding);
   5601 	}
   5602 
   5603 	createPipelineWithResources(vkd, device, renderPass, subpass, *vertexShaderModule, *fragmentShaderModule, context.getTargetWidth(), context.getTargetHeight(),
   5604 								vector<vk::VkVertexInputBindingDescription>(), vector<vk::VkVertexInputAttributeDescription>(), bindings, vk::VK_PRIMITIVE_TOPOLOGY_POINT_LIST, 0u, DE_NULL, m_resources);
   5605 
   5606 	{
   5607 		const deUint32							descriptorCount	= (deUint32)(divRoundUp(m_bufferSize, (vk::VkDeviceSize)m_maxStorageTexelCount * 4));
   5608 		const vk::VkDescriptorPoolSize			poolSizes		=
   5609 		{
   5610 			vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
   5611 			descriptorCount
   5612 		};
   5613 		const vk::VkDescriptorPoolCreateInfo	createInfo		=
   5614 		{
   5615 			vk::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
   5616 			DE_NULL,
   5617 			vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
   5618 
   5619 			descriptorCount,
   5620 			1u,
   5621 			&poolSizes,
   5622 		};
   5623 
   5624 		m_descriptorPool = vk::createDescriptorPool(vkd, device, &createInfo);
   5625 		m_descriptorSets.resize(descriptorCount, (vk::VkDescriptorSet)0);
   5626 		m_bufferViews.resize(descriptorCount, (vk::VkBufferView)0);
   5627 	}
   5628 
   5629 	for (size_t descriptorSetNdx = 0; descriptorSetNdx < m_descriptorSets.size(); descriptorSetNdx++)
   5630 	{
   5631 		const vk::VkDescriptorSetLayout			layout			= *m_resources.descriptorSetLayout;
   5632 		const vk::VkDescriptorSetAllocateInfo	allocateInfo	=
   5633 		{
   5634 			vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
   5635 			DE_NULL,
   5636 
   5637 			*m_descriptorPool,
   5638 			1,
   5639 			&layout
   5640 		};
   5641 
   5642 		m_descriptorSets[descriptorSetNdx] = vk::allocateDescriptorSet(vkd, device, &allocateInfo).disown();
   5643 
   5644 		{
   5645 			const vk::VkBufferViewCreateInfo createInfo =
   5646 			{
   5647 				vk::VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
   5648 				DE_NULL,
   5649 				0u,
   5650 
   5651 				context.getBuffer(),
   5652 				vk::VK_FORMAT_R32_UINT,
   5653 				descriptorSetNdx * m_maxStorageTexelCount * 4,
   5654 				(deUint32)de::min<vk::VkDeviceSize>(m_maxStorageTexelCount * 4, m_bufferSize - descriptorSetNdx * m_maxStorageTexelCount * 4)
   5655 			};
   5656 
   5657 			VK_CHECK(vkd.createBufferView(device, &createInfo, DE_NULL, &m_bufferViews[descriptorSetNdx]));
   5658 		}
   5659 
   5660 		{
   5661 			const vk::VkWriteDescriptorSet			write		=
   5662 			{
   5663 				vk::VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
   5664 				DE_NULL,
   5665 				m_descriptorSets[descriptorSetNdx],
   5666 				0u,
   5667 				0u,
   5668 				1u,
   5669 				vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
   5670 				DE_NULL,
   5671 				DE_NULL,
   5672 				&m_bufferViews[descriptorSetNdx]
   5673 			};
   5674 
   5675 			vkd.updateDescriptorSets(device, 1u, &write, 0u, DE_NULL);
   5676 		}
   5677 	}
   5678 }
   5679 
   5680 void RenderVertexStorageTexelBuffer::submit (SubmitContext& context)
   5681 {
   5682 	const vk::DeviceInterface&	vkd				= context.getContext().getDeviceInterface();
   5683 	const vk::VkCommandBuffer	commandBuffer	= context.getCommandBuffer();
   5684 
   5685 	vkd.cmdBindPipeline(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_resources.pipeline);
   5686 
   5687 	for (size_t descriptorSetNdx = 0; descriptorSetNdx < m_descriptorSets.size(); descriptorSetNdx++)
   5688 	{
   5689 		const deUint32 count	= (deUint32)(m_bufferSize < (descriptorSetNdx + 1) * m_maxStorageTexelCount * 4
   5690 								? m_bufferSize - descriptorSetNdx * m_maxStorageTexelCount * 4
   5691 								: m_maxStorageTexelCount * 4) / 2;
   5692 
   5693 		vkd.cmdBindDescriptorSets(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_resources.pipelineLayout, 0u, 1u, &m_descriptorSets[descriptorSetNdx], 0u, DE_NULL);
   5694 		vkd.cmdDraw(commandBuffer, count, 1, 0, 0);
   5695 	}
   5696 }
   5697 
   5698 void RenderVertexStorageTexelBuffer::verify (VerifyRenderPassContext& context, size_t)
   5699 {
   5700 	for (size_t descriptorSetNdx = 0; descriptorSetNdx < m_descriptorSets.size(); descriptorSetNdx++)
   5701 	{
   5702 		const size_t	offset	= descriptorSetNdx * m_maxStorageTexelCount * 4;
   5703 		const deUint32	count	= (deUint32)(m_bufferSize < (descriptorSetNdx + 1) * m_maxStorageTexelCount * 4
   5704 								? m_bufferSize - descriptorSetNdx * m_maxStorageTexelCount * 4
   5705 								: m_maxStorageTexelCount * 4) / 2;
   5706 
   5707 		DE_ASSERT(context.getReference().getSize() <= 4 * m_maxStorageTexelCount * m_descriptorSets.size());
   5708 		DE_ASSERT(context.getReference().getSize() > offset);
   5709 		DE_ASSERT(offset + count * 2 <= context.getReference().getSize());
   5710 
   5711 		for (size_t pos = 0; pos < (size_t)count; pos++)
   5712 		{
   5713 			const deUint8 x = context.getReference().get(offset + pos * 2);
   5714 			const deUint8 y = context.getReference().get(offset + (pos * 2) + 1);
   5715 
   5716 			context.getReferenceTarget().getAccess().setPixel(Vec4(1.0f, 1.0f, 1.0f, 1.0f), x, y);
   5717 		}
   5718 	}
   5719 }
   5720 
   5721 class RenderVertexStorageImage : public RenderPassCommand
   5722 {
   5723 public:
   5724 				RenderVertexStorageImage	(void) {}
   5725 				~RenderVertexStorageImage	(void);
   5726 
   5727 	const char*	getName						(void) const { return "RenderVertexStorageImage"; }
   5728 	void		logPrepare					(TestLog&, size_t) const;
   5729 	void		logSubmit					(TestLog&, size_t) const;
   5730 	void		prepare						(PrepareRenderPassContext&);
   5731 	void		submit						(SubmitContext& context);
   5732 	void		verify						(VerifyRenderPassContext&, size_t);
   5733 
   5734 private:
   5735 	PipelineResources				m_resources;
   5736 	vk::Move<vk::VkDescriptorPool>	m_descriptorPool;
   5737 	vk::Move<vk::VkDescriptorSet>	m_descriptorSet;
   5738 	vk::Move<vk::VkImageView>		m_imageView;
   5739 };
   5740 
   5741 RenderVertexStorageImage::~RenderVertexStorageImage (void)
   5742 {
   5743 }
   5744 
   5745 void RenderVertexStorageImage::logPrepare (TestLog& log, size_t commandIndex) const
   5746 {
   5747 	log << TestLog::Message << commandIndex << ":" << getName() << " Create pipeline for render storage image." << TestLog::EndMessage;
   5748 }
   5749 
   5750 void RenderVertexStorageImage::logSubmit (TestLog& log, size_t commandIndex) const
   5751 {
   5752 	log << TestLog::Message << commandIndex << ":" << getName() << " Render using storage image." << TestLog::EndMessage;
   5753 }
   5754 
   5755 void RenderVertexStorageImage::prepare (PrepareRenderPassContext& context)
   5756 {
   5757 	const vk::DeviceInterface&					vkd						= context.getContext().getDeviceInterface();
   5758 	const vk::VkDevice							device					= context.getContext().getDevice();
   5759 	const vk::VkRenderPass						renderPass				= context.getRenderPass();
   5760 	const deUint32								subpass					= 0;
   5761 	const vk::Unique<vk::VkShaderModule>		vertexShaderModule		(vk::createShaderModule(vkd, device, context.getBinaryCollection().get("storage-image.vert"), 0));
   5762 	const vk::Unique<vk::VkShaderModule>		fragmentShaderModule	(vk::createShaderModule(vkd, device, context.getBinaryCollection().get("render-white.frag"), 0));
   5763 	vector<vk::VkDescriptorSetLayoutBinding>	bindings;
   5764 
   5765 	{
   5766 		const vk::VkDescriptorSetLayoutBinding binding =
   5767 		{
   5768 			0u,
   5769 			vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
   5770 			1,
   5771 			vk::VK_SHADER_STAGE_VERTEX_BIT,
   5772 			DE_NULL
   5773 		};
   5774 
   5775 		bindings.push_back(binding);
   5776 	}
   5777 
   5778 	createPipelineWithResources(vkd, device, renderPass, subpass, *vertexShaderModule, *fragmentShaderModule, context.getTargetWidth(), context.getTargetHeight(),
   5779 								vector<vk::VkVertexInputBindingDescription>(), vector<vk::VkVertexInputAttributeDescription>(), bindings, vk::VK_PRIMITIVE_TOPOLOGY_POINT_LIST, 0u, DE_NULL, m_resources);
   5780 
   5781 	{
   5782 		const vk::VkDescriptorPoolSize			poolSizes		=
   5783 		{
   5784 			vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
   5785 			1
   5786 		};
   5787 		const vk::VkDescriptorPoolCreateInfo	createInfo		=
   5788 		{
   5789 			vk::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
   5790 			DE_NULL,
   5791 			vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
   5792 
   5793 			1u,
   5794 			1u,
   5795 			&poolSizes,
   5796 		};
   5797 
   5798 		m_descriptorPool = vk::createDescriptorPool(vkd, device, &createInfo);
   5799 	}
   5800 
   5801 	{
   5802 		const vk::VkDescriptorSetLayout			layout			= *m_resources.descriptorSetLayout;
   5803 		const vk::VkDescriptorSetAllocateInfo	allocateInfo	=
   5804 		{
   5805 			vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
   5806 			DE_NULL,
   5807 
   5808 			*m_descriptorPool,
   5809 			1,
   5810 			&layout
   5811 		};
   5812 
   5813 		m_descriptorSet = vk::allocateDescriptorSet(vkd, device, &allocateInfo);
   5814 
   5815 		{
   5816 			const vk::VkImageViewCreateInfo createInfo =
   5817 			{
   5818 				vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
   5819 				DE_NULL,
   5820 				0u,
   5821 
   5822 				context.getImage(),
   5823 				vk::VK_IMAGE_VIEW_TYPE_2D,
   5824 				vk::VK_FORMAT_R8G8B8A8_UNORM,
   5825 				vk::makeComponentMappingRGBA(),
   5826 				{
   5827 					vk::VK_IMAGE_ASPECT_COLOR_BIT,
   5828 					0u,
   5829 					1u,
   5830 					0u,
   5831 					1u
   5832 				}
   5833 			};
   5834 
   5835 			m_imageView = vk::createImageView(vkd, device, &createInfo);
   5836 		}
   5837 
   5838 		{
   5839 			const vk::VkDescriptorImageInfo			imageInfo	=
   5840 			{
   5841 				0,
   5842 				*m_imageView,
   5843 				context.getImageLayout()
   5844 			};
   5845 			const vk::VkWriteDescriptorSet			write		=
   5846 			{
   5847 				vk::VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
   5848 				DE_NULL,
   5849 				*m_descriptorSet,
   5850 				0u,
   5851 				0u,
   5852 				1u,
   5853 				vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
   5854 				&imageInfo,
   5855 				DE_NULL,
   5856 				DE_NULL,
   5857 			};
   5858 
   5859 			vkd.updateDescriptorSets(device, 1u, &write, 0u, DE_NULL);
   5860 		}
   5861 	}
   5862 }
   5863 
   5864 void RenderVertexStorageImage::submit (SubmitContext& context)
   5865 {
   5866 	const vk::DeviceInterface&	vkd				= context.getContext().getDeviceInterface();
   5867 	const vk::VkCommandBuffer	commandBuffer	= context.getCommandBuffer();
   5868 
   5869 	vkd.cmdBindPipeline(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_resources.pipeline);
   5870 
   5871 	vkd.cmdBindDescriptorSets(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_resources.pipelineLayout, 0u, 1u, &(*m_descriptorSet), 0u, DE_NULL);
   5872 	vkd.cmdDraw(commandBuffer, context.getImageWidth() * context.getImageHeight() * 2, 1, 0, 0);
   5873 }
   5874 
   5875 void RenderVertexStorageImage::verify (VerifyRenderPassContext& context, size_t)
   5876 {
   5877 	for (int pos = 0; pos < (int)(context.getReferenceImage().getWidth() * context.getReferenceImage().getHeight() * 2); pos++)
   5878 	{
   5879 		const tcu::IVec3		size	= context.getReferenceImage().getAccess().getSize();
   5880 		const tcu::UVec4		pixel	= context.getReferenceImage().getAccess().getPixelUint((pos / 2) / size.x(), (pos / 2) % size.x());
   5881 
   5882 		if (pos % 2 == 0)
   5883 			context.getReferenceTarget().getAccess().setPixel(Vec4(1.0f, 1.0f, 1.0f, 1.0f), pixel.x(), pixel.y());
   5884 		else
   5885 			context.getReferenceTarget().getAccess().setPixel(Vec4(1.0f, 1.0f, 1.0f, 1.0f), pixel.z(), pixel.w());
   5886 	}
   5887 }
   5888 
   5889 class RenderVertexSampledImage : public RenderPassCommand
   5890 {
   5891 public:
   5892 				RenderVertexSampledImage	(void) {}
   5893 				~RenderVertexSampledImage	(void);
   5894 
   5895 	const char*	getName						(void) const { return "RenderVertexSampledImage"; }
   5896 	void		logPrepare					(TestLog&, size_t) const;
   5897 	void		logSubmit					(TestLog&, size_t) const;
   5898 	void		prepare						(PrepareRenderPassContext&);
   5899 	void		submit						(SubmitContext& context);
   5900 	void		verify						(VerifyRenderPassContext&, size_t);
   5901 
   5902 private:
   5903 	PipelineResources				m_resources;
   5904 	vk::Move<vk::VkDescriptorPool>	m_descriptorPool;
   5905 	vk::Move<vk::VkDescriptorSet>	m_descriptorSet;
   5906 	vk::Move<vk::VkImageView>		m_imageView;
   5907 	vk::Move<vk::VkSampler>			m_sampler;
   5908 };
   5909 
   5910 RenderVertexSampledImage::~RenderVertexSampledImage (void)
   5911 {
   5912 }
   5913 
   5914 void RenderVertexSampledImage::logPrepare (TestLog& log, size_t commandIndex) const
   5915 {
   5916 	log << TestLog::Message << commandIndex << ":" << getName() << " Create pipeline for render sampled image." << TestLog::EndMessage;
   5917 }
   5918 
   5919 void RenderVertexSampledImage::logSubmit (TestLog& log, size_t commandIndex) const
   5920 {
   5921 	log << TestLog::Message << commandIndex << ":" << getName() << " Render using sampled image." << TestLog::EndMessage;
   5922 }
   5923 
   5924 void RenderVertexSampledImage::prepare (PrepareRenderPassContext& context)
   5925 {
   5926 	const vk::DeviceInterface&					vkd						= context.getContext().getDeviceInterface();
   5927 	const vk::VkDevice							device					= context.getContext().getDevice();
   5928 	const vk::VkRenderPass						renderPass				= context.getRenderPass();
   5929 	const deUint32								subpass					= 0;
   5930 	const vk::Unique<vk::VkShaderModule>		vertexShaderModule		(vk::createShaderModule(vkd, device, context.getBinaryCollection().get("sampled-image.vert"), 0));
   5931 	const vk::Unique<vk::VkShaderModule>		fragmentShaderModule	(vk::createShaderModule(vkd, device, context.getBinaryCollection().get("render-white.frag"), 0));
   5932 	vector<vk::VkDescriptorSetLayoutBinding>	bindings;
   5933 
   5934 	{
   5935 		const vk::VkDescriptorSetLayoutBinding binding =
   5936 		{
   5937 			0u,
   5938 			vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
   5939 			1,
   5940 			vk::VK_SHADER_STAGE_VERTEX_BIT,
   5941 			DE_NULL
   5942 		};
   5943 
   5944 		bindings.push_back(binding);
   5945 	}
   5946 
   5947 	createPipelineWithResources(vkd, device, renderPass, subpass, *vertexShaderModule, *fragmentShaderModule, context.getTargetWidth(), context.getTargetHeight(),
   5948 								vector<vk::VkVertexInputBindingDescription>(), vector<vk::VkVertexInputAttributeDescription>(), bindings, vk::VK_PRIMITIVE_TOPOLOGY_POINT_LIST, 0u, DE_NULL, m_resources);
   5949 
   5950 	{
   5951 		const vk::VkDescriptorPoolSize			poolSizes		=
   5952 		{
   5953 			vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
   5954 			1
   5955 		};
   5956 		const vk::VkDescriptorPoolCreateInfo	createInfo		=
   5957 		{
   5958 			vk::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
   5959 			DE_NULL,
   5960 			vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
   5961 
   5962 			1u,
   5963 			1u,
   5964 			&poolSizes,
   5965 		};
   5966 
   5967 		m_descriptorPool = vk::createDescriptorPool(vkd, device, &createInfo);
   5968 	}
   5969 
   5970 	{
   5971 		const vk::VkDescriptorSetLayout			layout			= *m_resources.descriptorSetLayout;
   5972 		const vk::VkDescriptorSetAllocateInfo	allocateInfo	=
   5973 		{
   5974 			vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
   5975 			DE_NULL,
   5976 
   5977 			*m_descriptorPool,
   5978 			1,
   5979 			&layout
   5980 		};
   5981 
   5982 		m_descriptorSet = vk::allocateDescriptorSet(vkd, device, &allocateInfo);
   5983 
   5984 		{
   5985 			const vk::VkImageViewCreateInfo createInfo =
   5986 			{
   5987 				vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
   5988 				DE_NULL,
   5989 				0u,
   5990 
   5991 				context.getImage(),
   5992 				vk::VK_IMAGE_VIEW_TYPE_2D,
   5993 				vk::VK_FORMAT_R8G8B8A8_UNORM,
   5994 				vk::makeComponentMappingRGBA(),
   5995 				{
   5996 					vk::VK_IMAGE_ASPECT_COLOR_BIT,
   5997 					0u,
   5998 					1u,
   5999 					0u,
   6000 					1u
   6001 				}
   6002 			};
   6003 
   6004 			m_imageView = vk::createImageView(vkd, device, &createInfo);
   6005 		}
   6006 
   6007 		{
   6008 			const vk::VkSamplerCreateInfo createInfo =
   6009 			{
   6010 				vk::VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
   6011 				DE_NULL,
   6012 				0u,
   6013 
   6014 				vk::VK_FILTER_NEAREST,
   6015 				vk::VK_FILTER_NEAREST,
   6016 
   6017 				vk::VK_SAMPLER_MIPMAP_MODE_LINEAR,
   6018 				vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
   6019 				vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
   6020 				vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
   6021 				0.0f,
   6022 				VK_FALSE,
   6023 				1.0f,
   6024 				VK_FALSE,
   6025 				vk::VK_COMPARE_OP_ALWAYS,
   6026 				0.0f,
   6027 				0.0f,
   6028 				vk::VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,
   6029 				VK_FALSE
   6030 			};
   6031 
   6032 			m_sampler = vk::createSampler(vkd, device, &createInfo);
   6033 		}
   6034 
   6035 		{
   6036 			const vk::VkDescriptorImageInfo			imageInfo	=
   6037 			{
   6038 				*m_sampler,
   6039 				*m_imageView,
   6040 				context.getImageLayout()
   6041 			};
   6042 			const vk::VkWriteDescriptorSet			write		=
   6043 			{
   6044 				vk::VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
   6045 				DE_NULL,
   6046 				*m_descriptorSet,
   6047 				0u,
   6048 				0u,
   6049 				1u,
   6050 				vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
   6051 				&imageInfo,
   6052 				DE_NULL,
   6053 				DE_NULL,
   6054 			};
   6055 
   6056 			vkd.updateDescriptorSets(device, 1u, &write, 0u, DE_NULL);
   6057 		}
   6058 	}
   6059 }
   6060 
   6061 void RenderVertexSampledImage::submit (SubmitContext& context)
   6062 {
   6063 	const vk::DeviceInterface&	vkd				= context.getContext().getDeviceInterface();
   6064 	const vk::VkCommandBuffer	commandBuffer	= context.getCommandBuffer();
   6065 
   6066 	vkd.cmdBindPipeline(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_resources.pipeline);
   6067 
   6068 	vkd.cmdBindDescriptorSets(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_resources.pipelineLayout, 0u, 1u, &(*m_descriptorSet), 0u, DE_NULL);
   6069 	vkd.cmdDraw(commandBuffer, context.getImageWidth() * context.getImageHeight() * 2, 1, 0, 0);
   6070 }
   6071 
   6072 void RenderVertexSampledImage::verify (VerifyRenderPassContext& context, size_t)
   6073 {
   6074 	for (int pos = 0; pos < (int)(context.getReferenceImage().getWidth() * context.getReferenceImage().getHeight() * 2); pos++)
   6075 	{
   6076 		const tcu::IVec3	size	= context.getReferenceImage().getAccess().getSize();
   6077 		const tcu::UVec4	pixel	= context.getReferenceImage().getAccess().getPixelUint((pos / 2) / size.x(), (pos / 2) % size.x());
   6078 
   6079 		if (pos % 2 == 0)
   6080 			context.getReferenceTarget().getAccess().setPixel(Vec4(1.0f, 1.0f, 1.0f, 1.0f), pixel.x(), pixel.y());
   6081 		else
   6082 			context.getReferenceTarget().getAccess().setPixel(Vec4(1.0f, 1.0f, 1.0f, 1.0f), pixel.z(), pixel.w());
   6083 	}
   6084 }
   6085 
   6086 class RenderFragmentUniformBuffer : public RenderPassCommand
   6087 {
   6088 public:
   6089 									RenderFragmentUniformBuffer		(void) {}
   6090 									~RenderFragmentUniformBuffer	(void);
   6091 
   6092 	const char*						getName							(void) const { return "RenderFragmentUniformBuffer"; }
   6093 	void							logPrepare						(TestLog&, size_t) const;
   6094 	void							logSubmit						(TestLog&, size_t) const;
   6095 	void							prepare							(PrepareRenderPassContext&);
   6096 	void							submit							(SubmitContext& context);
   6097 	void							verify							(VerifyRenderPassContext&, size_t);
   6098 
   6099 private:
   6100 	PipelineResources				m_resources;
   6101 	vk::Move<vk::VkDescriptorPool>	m_descriptorPool;
   6102 	vector<vk::VkDescriptorSet>		m_descriptorSets;
   6103 
   6104 	vk::VkDeviceSize				m_bufferSize;
   6105 	size_t							m_targetWidth;
   6106 	size_t							m_targetHeight;
   6107 };
   6108 
   6109 RenderFragmentUniformBuffer::~RenderFragmentUniformBuffer (void)
   6110 {
   6111 }
   6112 
   6113 void RenderFragmentUniformBuffer::logPrepare (TestLog& log, size_t commandIndex) const
   6114 {
   6115 	log << TestLog::Message << commandIndex << ":" << getName() << " Create pipeline for render buffer as uniform buffer." << TestLog::EndMessage;
   6116 }
   6117 
   6118 void RenderFragmentUniformBuffer::logSubmit (TestLog& log, size_t commandIndex) const
   6119 {
   6120 	log << TestLog::Message << commandIndex << ":" << getName() << " Render using buffer as uniform buffer." << TestLog::EndMessage;
   6121 }
   6122 
   6123 void RenderFragmentUniformBuffer::prepare (PrepareRenderPassContext& context)
   6124 {
   6125 	const vk::DeviceInterface&					vkd						= context.getContext().getDeviceInterface();
   6126 	const vk::VkDevice							device					= context.getContext().getDevice();
   6127 	const vk::VkRenderPass						renderPass				= context.getRenderPass();
   6128 	const deUint32								subpass					= 0;
   6129 	const vk::Unique<vk::VkShaderModule>		vertexShaderModule		(vk::createShaderModule(vkd, device, context.getBinaryCollection().get("render-quad.vert"), 0));
   6130 	const vk::Unique<vk::VkShaderModule>		fragmentShaderModule	(vk::createShaderModule(vkd, device, context.getBinaryCollection().get("uniform-buffer.frag"), 0));
   6131 	vector<vk::VkDescriptorSetLayoutBinding>	bindings;
   6132 
   6133 	m_bufferSize	= de::min(context.getBufferSize(), (vk::VkDeviceSize)MAX_SIZE);
   6134 	m_targetWidth	= context.getTargetWidth();
   6135 	m_targetHeight	= context.getTargetHeight();
   6136 
   6137 	{
   6138 		const vk::VkDescriptorSetLayoutBinding binding =
   6139 		{
   6140 			0u,
   6141 			vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
   6142 			1,
   6143 			vk::VK_SHADER_STAGE_FRAGMENT_BIT,
   6144 			DE_NULL
   6145 		};
   6146 
   6147 		bindings.push_back(binding);
   6148 	}
   6149 	const vk::VkPushConstantRange pushConstantRange =
   6150 	{
   6151 		vk::VK_SHADER_STAGE_FRAGMENT_BIT,
   6152 		0u,
   6153 		8u
   6154 	};
   6155 
   6156 	createPipelineWithResources(vkd, device, renderPass, subpass, *vertexShaderModule, *fragmentShaderModule, context.getTargetWidth(), context.getTargetHeight(),
   6157 								vector<vk::VkVertexInputBindingDescription>(), vector<vk::VkVertexInputAttributeDescription>(), bindings, vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 1u, &pushConstantRange, m_resources);
   6158 
   6159 	{
   6160 		const deUint32							descriptorCount	= (deUint32)(divRoundUp(m_bufferSize, (vk::VkDeviceSize)MAX_UNIFORM_BUFFER_SIZE));
   6161 		const vk::VkDescriptorPoolSize			poolSizes		=
   6162 		{
   6163 			vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
   6164 			descriptorCount
   6165 		};
   6166 		const vk::VkDescriptorPoolCreateInfo	createInfo		=
   6167 		{
   6168 			vk::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
   6169 			DE_NULL,
   6170 			vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
   6171 
   6172 			descriptorCount,
   6173 			1u,
   6174 			&poolSizes,
   6175 		};
   6176 
   6177 		m_descriptorPool = vk::createDescriptorPool(vkd, device, &createInfo);
   6178 		m_descriptorSets.resize(descriptorCount);
   6179 	}
   6180 
   6181 	for (size_t descriptorSetNdx = 0; descriptorSetNdx < m_descriptorSets.size(); descriptorSetNdx++)
   6182 	{
   6183 		const vk::VkDescriptorSetLayout			layout			= *m_resources.descriptorSetLayout;
   6184 		const vk::VkDescriptorSetAllocateInfo	allocateInfo	=
   6185 		{
   6186 			vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
   6187 			DE_NULL,
   6188 
   6189 			*m_descriptorPool,
   6190 			1,
   6191 			&layout
   6192 		};
   6193 
   6194 		m_descriptorSets[descriptorSetNdx] = vk::allocateDescriptorSet(vkd, device, &allocateInfo).disown();
   6195 
   6196 		{
   6197 			const vk::VkDescriptorBufferInfo		bufferInfo	=
   6198 			{
   6199 				context.getBuffer(),
   6200 				(vk::VkDeviceSize)(descriptorSetNdx * (size_t)MAX_UNIFORM_BUFFER_SIZE),
   6201 				m_bufferSize < (descriptorSetNdx + 1) * (vk::VkDeviceSize)MAX_UNIFORM_BUFFER_SIZE
   6202 					? m_bufferSize - descriptorSetNdx * (vk::VkDeviceSize)MAX_UNIFORM_BUFFER_SIZE
   6203 					: (vk::VkDeviceSize)MAX_UNIFORM_BUFFER_SIZE
   6204 			};
   6205 			const vk::VkWriteDescriptorSet			write		=
   6206 			{
   6207 				vk::VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
   6208 				DE_NULL,
   6209 				m_descriptorSets[descriptorSetNdx],
   6210 				0u,
   6211 				0u,
   6212 				1u,
   6213 				vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
   6214 				DE_NULL,
   6215 				&bufferInfo,
   6216 				DE_NULL,
   6217 			};
   6218 
   6219 			vkd.updateDescriptorSets(device, 1u, &write, 0u, DE_NULL);
   6220 		}
   6221 	}
   6222 }
   6223 
   6224 void RenderFragmentUniformBuffer::submit (SubmitContext& context)
   6225 {
   6226 	const vk::DeviceInterface&	vkd				= context.getContext().getDeviceInterface();
   6227 	const vk::VkCommandBuffer	commandBuffer	= context.getCommandBuffer();
   6228 
   6229 	vkd.cmdBindPipeline(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_resources.pipeline);
   6230 
   6231 	for (size_t descriptorSetNdx = 0; descriptorSetNdx < m_descriptorSets.size(); descriptorSetNdx++)
   6232 	{
   6233 		const struct
   6234 		{
   6235 			const deUint32	callId;
   6236 			const deUint32	valuesPerPixel;
   6237 		} callParams =
   6238 		{
   6239 			(deUint32)descriptorSetNdx,
   6240 			(deUint32)divRoundUp<size_t>(m_descriptorSets.size() * (MAX_UNIFORM_BUFFER_SIZE / 4), m_targetWidth * m_targetHeight)
   6241 		};
   6242 
   6243 		vkd.cmdBindDescriptorSets(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_resources.pipelineLayout, 0u, 1u, &m_descriptorSets[descriptorSetNdx], 0u, DE_NULL);
   6244 		vkd.cmdPushConstants(commandBuffer, *m_resources.pipelineLayout, vk::VK_SHADER_STAGE_FRAGMENT_BIT, 0u, (deUint32)sizeof(callParams), &callParams);
   6245 		vkd.cmdDraw(commandBuffer, 6, 1, 0, 0);
   6246 	}
   6247 }
   6248 
   6249 void RenderFragmentUniformBuffer::verify (VerifyRenderPassContext& context, size_t)
   6250 {
   6251 	const deUint32	valuesPerPixel	= (deUint32)divRoundUp<size_t>(m_descriptorSets.size() * (MAX_UNIFORM_BUFFER_SIZE / 4), m_targetWidth * m_targetHeight);
   6252 	const size_t	arraySize		= MAX_UNIFORM_BUFFER_SIZE / (sizeof(deUint32) * 4);
   6253 	const size_t	arrayIntSize	= arraySize * 4;
   6254 
   6255 	for (int y = 0; y < context.getReferenceTarget().getSize().y(); y++)
   6256 	for (int x = 0; x < context.getReferenceTarget().getSize().x(); x++)
   6257 	{
   6258 		const size_t firstDescriptorSetNdx = de::min<size_t>((y * 256u + x) / (arrayIntSize / valuesPerPixel), m_descriptorSets.size() - 1);
   6259 
   6260 		for (size_t descriptorSetNdx = firstDescriptorSetNdx; descriptorSetNdx < m_descriptorSets.size(); descriptorSetNdx++)
   6261 		{
   6262 			const size_t	offset	= descriptorSetNdx * MAX_UNIFORM_BUFFER_SIZE;
   6263 			const deUint32	callId	= (deUint32)descriptorSetNdx;
   6264 
   6265 			const deUint32	id		= callId * ((deUint32)arrayIntSize / valuesPerPixel) + (deUint32)y * 256u + (deUint32)x;
   6266 
   6267 			if (y * 256u + x < callId * (arrayIntSize / valuesPerPixel))
   6268 				continue;
   6269 			else
   6270 			{
   6271 				deUint32 value = id;
   6272 
   6273 				for (deUint32 i = 0; i < valuesPerPixel; i++)
   6274 				{
   6275 					value	= ((deUint32)context.getReference().get(offset + (value % (MAX_UNIFORM_BUFFER_SIZE / sizeof(deUint32))) * 4 + 0))
   6276 							| (((deUint32)context.getReference().get(offset + (value % (MAX_UNIFORM_BUFFER_SIZE / sizeof(deUint32))) * 4 + 1)) << 8u)
   6277 							| (((deUint32)context.getReference().get(offset + (value % (MAX_UNIFORM_BUFFER_SIZE / sizeof(deUint32))) * 4 + 2)) << 16u)
   6278 							| (((deUint32)context.getReference().get(offset + (value % (MAX_UNIFORM_BUFFER_SIZE / sizeof(deUint32))) * 4 + 3)) << 24u);
   6279 
   6280 				}
   6281 				const UVec4	vec	((value >>  0u) & 0xFFu,
   6282 								 (value >>  8u) & 0xFFu,
   6283 								 (value >> 16u) & 0xFFu,
   6284 								 (value >> 24u) & 0xFFu);
   6285 
   6286 				context.getReferenceTarget().getAccess().setPixel(vec.asFloat() / Vec4(255.0f), x, y);
   6287 			}
   6288 		}
   6289 	}
   6290 }
   6291 
   6292 class RenderFragmentStorageBuffer : public RenderPassCommand
   6293 {
   6294 public:
   6295 									RenderFragmentStorageBuffer		(void) {}
   6296 									~RenderFragmentStorageBuffer	(void);
   6297 
   6298 	const char*						getName							(void) const { return "RenderFragmentStorageBuffer"; }
   6299 	void							logPrepare						(TestLog&, size_t) const;
   6300 	void							logSubmit						(TestLog&, size_t) const;
   6301 	void							prepare							(PrepareRenderPassContext&);
   6302 	void							submit							(SubmitContext& context);
   6303 	void							verify							(VerifyRenderPassContext&, size_t);
   6304 
   6305 private:
   6306 	PipelineResources				m_resources;
   6307 	vk::Move<vk::VkDescriptorPool>	m_descriptorPool;
   6308 	vk::Move<vk::VkDescriptorSet>	m_descriptorSet;
   6309 
   6310 	vk::VkDeviceSize				m_bufferSize;
   6311 	size_t							m_targetWidth;
   6312 	size_t							m_targetHeight;
   6313 };
   6314 
   6315 RenderFragmentStorageBuffer::~RenderFragmentStorageBuffer (void)
   6316 {
   6317 }
   6318 
   6319 void RenderFragmentStorageBuffer::logPrepare (TestLog& log, size_t commandIndex) const
   6320 {
   6321 	log << TestLog::Message << commandIndex << ":" << getName() << " Create pipeline to render buffer as storage buffer." << TestLog::EndMessage;
   6322 }
   6323 
   6324 void RenderFragmentStorageBuffer::logSubmit (TestLog& log, size_t commandIndex) const
   6325 {
   6326 	log << TestLog::Message << commandIndex << ":" << getName() << " Render using buffer as storage buffer." << TestLog::EndMessage;
   6327 }
   6328 
   6329 void RenderFragmentStorageBuffer::prepare (PrepareRenderPassContext& context)
   6330 {
   6331 	const vk::DeviceInterface&					vkd						= context.getContext().getDeviceInterface();
   6332 	const vk::VkDevice							device					= context.getContext().getDevice();
   6333 	const vk::VkRenderPass						renderPass				= context.getRenderPass();
   6334 	const deUint32								subpass					= 0;
   6335 	const vk::Unique<vk::VkShaderModule>		vertexShaderModule		(vk::createShaderModule(vkd, device, context.getBinaryCollection().get("render-quad.vert"), 0));
   6336 	const vk::Unique<vk::VkShaderModule>		fragmentShaderModule	(vk::createShaderModule(vkd, device, context.getBinaryCollection().get("storage-buffer.frag"), 0));
   6337 	vector<vk::VkDescriptorSetLayoutBinding>	bindings;
   6338 
   6339 	m_bufferSize	= context.getBufferSize();
   6340 	m_targetWidth	= context.getTargetWidth();
   6341 	m_targetHeight	= context.getTargetHeight();
   6342 
   6343 	{
   6344 		const vk::VkDescriptorSetLayoutBinding binding =
   6345 		{
   6346 			0u,
   6347 			vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
   6348 			1,
   6349 			vk::VK_SHADER_STAGE_FRAGMENT_BIT,
   6350 			DE_NULL
   6351 		};
   6352 
   6353 		bindings.push_back(binding);
   6354 	}
   6355 	const vk::VkPushConstantRange pushConstantRange =
   6356 	{
   6357 		vk::VK_SHADER_STAGE_FRAGMENT_BIT,
   6358 		0u,
   6359 		12u
   6360 	};
   6361 
   6362 	createPipelineWithResources(vkd, device, renderPass, subpass, *vertexShaderModule, *fragmentShaderModule, context.getTargetWidth(), context.getTargetHeight(),
   6363 								vector<vk::VkVertexInputBindingDescription>(), vector<vk::VkVertexInputAttributeDescription>(), bindings, vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 1u, &pushConstantRange, m_resources);
   6364 
   6365 	{
   6366 		const deUint32							descriptorCount	= 1;
   6367 		const vk::VkDescriptorPoolSize			poolSizes		=
   6368 		{
   6369 			vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
   6370 			descriptorCount
   6371 		};
   6372 		const vk::VkDescriptorPoolCreateInfo	createInfo		=
   6373 		{
   6374 			vk::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
   6375 			DE_NULL,
   6376 			vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
   6377 
   6378 			descriptorCount,
   6379 			1u,
   6380 			&poolSizes,
   6381 		};
   6382 
   6383 		m_descriptorPool = vk::createDescriptorPool(vkd, device, &createInfo);
   6384 	}
   6385 
   6386 	{
   6387 		const vk::VkDescriptorSetLayout			layout			= *m_resources.descriptorSetLayout;
   6388 		const vk::VkDescriptorSetAllocateInfo	allocateInfo	=
   6389 		{
   6390 			vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
   6391 			DE_NULL,
   6392 
   6393 			*m_descriptorPool,
   6394 			1,
   6395 			&layout
   6396 		};
   6397 
   6398 		m_descriptorSet = vk::allocateDescriptorSet(vkd, device, &allocateInfo);
   6399 
   6400 		{
   6401 			const vk::VkDescriptorBufferInfo	bufferInfo	=
   6402 			{
   6403 				context.getBuffer(),
   6404 				0u,
   6405 				m_bufferSize
   6406 			};
   6407 			const vk::VkWriteDescriptorSet		write		=
   6408 			{
   6409 				vk::VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
   6410 				DE_NULL,
   6411 				m_descriptorSet.get(),
   6412 				0u,
   6413 				0u,
   6414 				1u,
   6415 				vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
   6416 				DE_NULL,
   6417 				&bufferInfo,
   6418 				DE_NULL,
   6419 			};
   6420 
   6421 			vkd.updateDescriptorSets(device, 1u, &write, 0u, DE_NULL);
   6422 		}
   6423 	}
   6424 }
   6425 
   6426 void RenderFragmentStorageBuffer::submit (SubmitContext& context)
   6427 {
   6428 	const vk::DeviceInterface&	vkd				= context.getContext().getDeviceInterface();
   6429 	const vk::VkCommandBuffer	commandBuffer	= context.getCommandBuffer();
   6430 
   6431 	vkd.cmdBindPipeline(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_resources.pipeline);
   6432 
   6433 	const struct
   6434 	{
   6435 		const deUint32	valuesPerPixel;
   6436 		const deUint32	bufferSize;
   6437 	} callParams =
   6438 	{
   6439 		(deUint32)divRoundUp<vk::VkDeviceSize>(m_bufferSize / 4, m_targetWidth * m_targetHeight),
   6440 		(deUint32)m_bufferSize
   6441 	};
   6442 
   6443 	vkd.cmdBindDescriptorSets(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_resources.pipelineLayout, 0u, 1u, &m_descriptorSet.get(), 0u, DE_NULL);
   6444 	vkd.cmdPushConstants(commandBuffer, *m_resources.pipelineLayout, vk::VK_SHADER_STAGE_FRAGMENT_BIT, 0u, (deUint32)sizeof(callParams), &callParams);
   6445 	vkd.cmdDraw(commandBuffer, 6, 1, 0, 0);
   6446 }
   6447 
   6448 void RenderFragmentStorageBuffer::verify (VerifyRenderPassContext& context, size_t)
   6449 {
   6450 	const deUint32	valuesPerPixel	= (deUint32)divRoundUp<vk::VkDeviceSize>(m_bufferSize / 4, m_targetWidth * m_targetHeight);
   6451 
   6452 	for (int y = 0; y < context.getReferenceTarget().getSize().y(); y++)
   6453 	for (int x = 0; x < context.getReferenceTarget().getSize().x(); x++)
   6454 	{
   6455 		const deUint32	id		= (deUint32)y * 256u + (deUint32)x;
   6456 
   6457 		deUint32 value = id;
   6458 
   6459 		for (deUint32 i = 0; i < valuesPerPixel; i++)
   6460 		{
   6461 			value	= (((deUint32)context.getReference().get((size_t)(value % (m_bufferSize / sizeof(deUint32))) * 4 + 0)) << 0u)
   6462 					| (((deUint32)context.getReference().get((size_t)(value % (m_bufferSize / sizeof(deUint32))) * 4 + 1)) << 8u)
   6463 					| (((deUint32)context.getReference().get((size_t)(value % (m_bufferSize / sizeof(deUint32))) * 4 + 2)) << 16u)
   6464 					| (((deUint32)context.getReference().get((size_t)(value % (m_bufferSize / sizeof(deUint32))) * 4 + 3)) << 24u);
   6465 
   6466 		}
   6467 		const UVec4	vec	((value >>  0u) & 0xFFu,
   6468 						 (value >>  8u) & 0xFFu,
   6469 						 (value >> 16u) & 0xFFu,
   6470 						 (value >> 24u) & 0xFFu);
   6471 
   6472 		context.getReferenceTarget().getAccess().setPixel(vec.asFloat() / Vec4(255.0f), x, y);
   6473 	}
   6474 }
   6475 
   6476 class RenderFragmentUniformTexelBuffer : public RenderPassCommand
   6477 {
   6478 public:
   6479 									RenderFragmentUniformTexelBuffer	(void) {}
   6480 									~RenderFragmentUniformTexelBuffer	(void);
   6481 
   6482 	const char*						getName								(void) const { return "RenderFragmentUniformTexelBuffer"; }
   6483 	void							logPrepare							(TestLog&, size_t) const;
   6484 	void							logSubmit							(TestLog&, size_t) const;
   6485 	void							prepare								(PrepareRenderPassContext&);
   6486 	void							submit								(SubmitContext& context);
   6487 	void							verify								(VerifyRenderPassContext&, size_t);
   6488 
   6489 private:
   6490 	PipelineResources				m_resources;
   6491 	vk::Move<vk::VkDescriptorPool>	m_descriptorPool;
   6492 	vector<vk::VkDescriptorSet>		m_descriptorSets;
   6493 	vector<vk::VkBufferView>		m_bufferViews;
   6494 
   6495 	const vk::DeviceInterface*		m_vkd;
   6496 	vk::VkDevice					m_device;
   6497 	vk::VkDeviceSize				m_bufferSize;
   6498 	deUint32						m_maxUniformTexelCount;
   6499 	size_t							m_targetWidth;
   6500 	size_t							m_targetHeight;
   6501 };
   6502 
   6503 RenderFragmentUniformTexelBuffer::~RenderFragmentUniformTexelBuffer (void)
   6504 {
   6505 	for (size_t bufferViewNdx = 0; bufferViewNdx < m_bufferViews.size(); bufferViewNdx++)
   6506 	{
   6507 		if (!!m_bufferViews[bufferViewNdx])
   6508 		{
   6509 			m_vkd->destroyBufferView(m_device, m_bufferViews[bufferViewNdx], DE_NULL);
   6510 			m_bufferViews[bufferViewNdx] = (vk::VkBufferView)0;
   6511 		}
   6512 	}
   6513 }
   6514 
   6515 void RenderFragmentUniformTexelBuffer::logPrepare (TestLog& log, size_t commandIndex) const
   6516 {
   6517 	log << TestLog::Message << commandIndex << ":" << getName() << " Create pipeline for render buffer as uniform buffer." << TestLog::EndMessage;
   6518 }
   6519 
   6520 void RenderFragmentUniformTexelBuffer::logSubmit (TestLog& log, size_t commandIndex) const
   6521 {
   6522 	log << TestLog::Message << commandIndex << ":" << getName() << " Render using buffer as uniform buffer." << TestLog::EndMessage;
   6523 }
   6524 
   6525 void RenderFragmentUniformTexelBuffer::prepare (PrepareRenderPassContext& context)
   6526 {
   6527 	const vk::InstanceInterface&				vki						= context.getContext().getInstanceInterface();
   6528 	const vk::VkPhysicalDevice					physicalDevice			= context.getContext().getPhysicalDevice();
   6529 	const vk::DeviceInterface&					vkd						= context.getContext().getDeviceInterface();
   6530 	const vk::VkDevice							device					= context.getContext().getDevice();
   6531 	const vk::VkRenderPass						renderPass				= context.getRenderPass();
   6532 	const deUint32								subpass					= 0;
   6533 	const vk::Unique<vk::VkShaderModule>		vertexShaderModule		(vk::createShaderModule(vkd, device, context.getBinaryCollection().get("render-quad.vert"), 0));
   6534 	const vk::Unique<vk::VkShaderModule>		fragmentShaderModule	(vk::createShaderModule(vkd, device, context.getBinaryCollection().get("uniform-texel-buffer.frag"), 0));
   6535 	vector<vk::VkDescriptorSetLayoutBinding>	bindings;
   6536 
   6537 	m_device				= device;
   6538 	m_vkd					= &vkd;
   6539 	m_bufferSize			= context.getBufferSize();
   6540 	m_maxUniformTexelCount	= vk::getPhysicalDeviceProperties(vki, physicalDevice).limits.maxTexelBufferElements;
   6541 	m_targetWidth			= context.getTargetWidth();
   6542 	m_targetHeight			= context.getTargetHeight();
   6543 
   6544 	{
   6545 		const vk::VkDescriptorSetLayoutBinding binding =
   6546 		{
   6547 			0u,
   6548 			vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
   6549 			1,
   6550 			vk::VK_SHADER_STAGE_FRAGMENT_BIT,
   6551 			DE_NULL
   6552 		};
   6553 
   6554 		bindings.push_back(binding);
   6555 	}
   6556 	const vk::VkPushConstantRange pushConstantRange =
   6557 	{
   6558 		vk::VK_SHADER_STAGE_FRAGMENT_BIT,
   6559 		0u,
   6560 		12u
   6561 	};
   6562 
   6563 	createPipelineWithResources(vkd, device, renderPass, subpass, *vertexShaderModule, *fragmentShaderModule, context.getTargetWidth(), context.getTargetHeight(),
   6564 								vector<vk::VkVertexInputBindingDescription>(), vector<vk::VkVertexInputAttributeDescription>(), bindings, vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 1u, &pushConstantRange, m_resources);
   6565 
   6566 	{
   6567 		const deUint32							descriptorCount	= (deUint32)(divRoundUp(m_bufferSize, (vk::VkDeviceSize)m_maxUniformTexelCount * 4));
   6568 		const vk::VkDescriptorPoolSize			poolSizes		=
   6569 		{
   6570 			vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
   6571 			descriptorCount
   6572 		};
   6573 		const vk::VkDescriptorPoolCreateInfo	createInfo		=
   6574 		{
   6575 			vk::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
   6576 			DE_NULL,
   6577 			vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
   6578 
   6579 			descriptorCount,
   6580 			1u,
   6581 			&poolSizes,
   6582 		};
   6583 
   6584 		m_descriptorPool = vk::createDescriptorPool(vkd, device, &createInfo);
   6585 		m_descriptorSets.resize(descriptorCount, (vk::VkDescriptorSet)0);
   6586 		m_bufferViews.resize(descriptorCount, (vk::VkBufferView)0);
   6587 	}
   6588 
   6589 	for (size_t descriptorSetNdx = 0; descriptorSetNdx < m_descriptorSets.size(); descriptorSetNdx++)
   6590 	{
   6591 		const deUint32							count			= (deUint32)(m_bufferSize < (descriptorSetNdx + 1) * m_maxUniformTexelCount * 4
   6592 																? m_bufferSize - descriptorSetNdx * m_maxUniformTexelCount * 4
   6593 																: m_maxUniformTexelCount * 4) / 4;
   6594 		const vk::VkDescriptorSetLayout			layout			= *m_resources.descriptorSetLayout;
   6595 		const vk::VkDescriptorSetAllocateInfo	allocateInfo	=
   6596 		{
   6597 			vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
   6598 			DE_NULL,
   6599 
   6600 			*m_descriptorPool,
   6601 			1,
   6602 			&layout
   6603 		};
   6604 
   6605 		m_descriptorSets[descriptorSetNdx] = vk::allocateDescriptorSet(vkd, device, &allocateInfo).disown();
   6606 
   6607 		{
   6608 			const vk::VkBufferViewCreateInfo createInfo =
   6609 			{
   6610 				vk::VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
   6611 				DE_NULL,
   6612 				0u,
   6613 
   6614 				context.getBuffer(),
   6615 				vk::VK_FORMAT_R32_UINT,
   6616 				descriptorSetNdx * m_maxUniformTexelCount * 4,
   6617 				count * 4
   6618 			};
   6619 
   6620 			VK_CHECK(vkd.createBufferView(device, &createInfo, DE_NULL, &m_bufferViews[descriptorSetNdx]));
   6621 		}
   6622 
   6623 		{
   6624 			const vk::VkWriteDescriptorSet			write		=
   6625 			{
   6626 				vk::VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
   6627 				DE_NULL,
   6628 				m_descriptorSets[descriptorSetNdx],
   6629 				0u,
   6630 				0u,
   6631 				1u,
   6632 				vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
   6633 				DE_NULL,
   6634 				DE_NULL,
   6635 				&m_bufferViews[descriptorSetNdx]
   6636 			};
   6637 
   6638 			vkd.updateDescriptorSets(device, 1u, &write, 0u, DE_NULL);
   6639 		}
   6640 	}
   6641 }
   6642 
   6643 void RenderFragmentUniformTexelBuffer::submit (SubmitContext& context)
   6644 {
   6645 	const vk::DeviceInterface&	vkd				= context.getContext().getDeviceInterface();
   6646 	const vk::VkCommandBuffer	commandBuffer	= context.getCommandBuffer();
   6647 
   6648 	vkd.cmdBindPipeline(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_resources.pipeline);
   6649 
   6650 	for (size_t descriptorSetNdx = 0; descriptorSetNdx < m_descriptorSets.size(); descriptorSetNdx++)
   6651 	{
   6652 		const struct
   6653 		{
   6654 			const deUint32	callId;
   6655 			const deUint32	valuesPerPixel;
   6656 			const deUint32	maxUniformTexelCount;
   6657 		} callParams =
   6658 		{
   6659 			(deUint32)descriptorSetNdx,
   6660 			(deUint32)divRoundUp<size_t>(m_descriptorSets.size() * de::min<size_t>((size_t)m_bufferSize / 4, m_maxUniformTexelCount), m_targetWidth * m_targetHeight),
   6661 			m_maxUniformTexelCount
   6662 		};
   6663 
   6664 		vkd.cmdBindDescriptorSets(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_resources.pipelineLayout, 0u, 1u, &m_descriptorSets[descriptorSetNdx], 0u, DE_NULL);
   6665 		vkd.cmdPushConstants(commandBuffer, *m_resources.pipelineLayout, vk::VK_SHADER_STAGE_FRAGMENT_BIT, 0u, (deUint32)sizeof(callParams), &callParams);
   6666 		vkd.cmdDraw(commandBuffer, 6, 1, 0, 0);
   6667 	}
   6668 }
   6669 
   6670 void RenderFragmentUniformTexelBuffer::verify (VerifyRenderPassContext& context, size_t)
   6671 {
   6672 	const deUint32	valuesPerPixel	= (deUint32)divRoundUp<size_t>(m_descriptorSets.size() * de::min<size_t>((size_t)m_bufferSize / 4, m_maxUniformTexelCount), m_targetWidth * m_targetHeight);
   6673 
   6674 	for (int y = 0; y < context.getReferenceTarget().getSize().y(); y++)
   6675 	for (int x = 0; x < context.getReferenceTarget().getSize().x(); x++)
   6676 	{
   6677 		const size_t firstDescriptorSetNdx = de::min<size_t>((y * 256u + x) / (m_maxUniformTexelCount / valuesPerPixel), m_descriptorSets.size() - 1);
   6678 
   6679 		for (size_t descriptorSetNdx = firstDescriptorSetNdx; descriptorSetNdx < m_descriptorSets.size(); descriptorSetNdx++)
   6680 		{
   6681 			const size_t	offset	= descriptorSetNdx * m_maxUniformTexelCount * 4;
   6682 			const deUint32	callId	= (deUint32)descriptorSetNdx;
   6683 
   6684 			const deUint32	id		= (deUint32)y * 256u + (deUint32)x;
   6685 			const deUint32	count	= (deUint32)(m_bufferSize < (descriptorSetNdx + 1) * m_maxUniformTexelCount * 4
   6686 									? m_bufferSize - descriptorSetNdx * m_maxUniformTexelCount * 4
   6687 									: m_maxUniformTexelCount * 4) / 4;
   6688 
   6689 			if (y * 256u + x < callId * (m_maxUniformTexelCount / valuesPerPixel))
   6690 				continue;
   6691 			else
   6692 			{
   6693 				deUint32 value = id;
   6694 
   6695 				for (deUint32 i = 0; i < valuesPerPixel; i++)
   6696 				{
   6697 					value	= ((deUint32)context.getReference().get( offset + (value % count) * 4 + 0))
   6698 							| (((deUint32)context.getReference().get(offset + (value % count) * 4 + 1)) << 8u)
   6699 							| (((deUint32)context.getReference().get(offset + (value % count) * 4 + 2)) << 16u)
   6700 							| (((deUint32)context.getReference().get(offset + (value % count) * 4 + 3)) << 24u);
   6701 
   6702 				}
   6703 				const UVec4	vec	((value >>  0u) & 0xFFu,
   6704 								 (value >>  8u) & 0xFFu,
   6705 								 (value >> 16u) & 0xFFu,
   6706 								 (value >> 24u) & 0xFFu);
   6707 
   6708 				context.getReferenceTarget().getAccess().setPixel(vec.asFloat() / Vec4(255.0f), x, y);
   6709 			}
   6710 		}
   6711 	}
   6712 }
   6713 
   6714 class RenderFragmentStorageTexelBuffer : public RenderPassCommand
   6715 {
   6716 public:
   6717 									RenderFragmentStorageTexelBuffer	(void) {}
   6718 									~RenderFragmentStorageTexelBuffer	(void);
   6719 
   6720 	const char*						getName								(void) const { return "RenderFragmentStorageTexelBuffer"; }
   6721 	void							logPrepare							(TestLog&, size_t) const;
   6722 	void							logSubmit							(TestLog&, size_t) const;
   6723 	void							prepare								(PrepareRenderPassContext&);
   6724 	void							submit								(SubmitContext& context);
   6725 	void							verify								(VerifyRenderPassContext&, size_t);
   6726 
   6727 private:
   6728 	PipelineResources				m_resources;
   6729 	vk::Move<vk::VkDescriptorPool>	m_descriptorPool;
   6730 	vector<vk::VkDescriptorSet>		m_descriptorSets;
   6731 	vector<vk::VkBufferView>		m_bufferViews;
   6732 
   6733 	const vk::DeviceInterface*		m_vkd;
   6734 	vk::VkDevice					m_device;
   6735 	vk::VkDeviceSize				m_bufferSize;
   6736 	deUint32						m_maxStorageTexelCount;
   6737 	size_t							m_targetWidth;
   6738 	size_t							m_targetHeight;
   6739 };
   6740 
   6741 RenderFragmentStorageTexelBuffer::~RenderFragmentStorageTexelBuffer (void)
   6742 {
   6743 	for (size_t bufferViewNdx = 0; bufferViewNdx < m_bufferViews.size(); bufferViewNdx++)
   6744 	{
   6745 		if (!!m_bufferViews[bufferViewNdx])
   6746 		{
   6747 			m_vkd->destroyBufferView(m_device, m_bufferViews[bufferViewNdx], DE_NULL);
   6748 			m_bufferViews[bufferViewNdx] = (vk::VkBufferView)0;
   6749 		}
   6750 	}
   6751 }
   6752 
   6753 void RenderFragmentStorageTexelBuffer::logPrepare (TestLog& log, size_t commandIndex) const
   6754 {
   6755 	log << TestLog::Message << commandIndex << ":" << getName() << " Create pipeline for render buffer as storage buffer." << TestLog::EndMessage;
   6756 }
   6757 
   6758 void RenderFragmentStorageTexelBuffer::logSubmit (TestLog& log, size_t commandIndex) const
   6759 {
   6760 	log << TestLog::Message << commandIndex << ":" << getName() << " Render using buffer as storage buffer." << TestLog::EndMessage;
   6761 }
   6762 
   6763 void RenderFragmentStorageTexelBuffer::prepare (PrepareRenderPassContext& context)
   6764 {
   6765 	const vk::InstanceInterface&				vki						= context.getContext().getInstanceInterface();
   6766 	const vk::VkPhysicalDevice					physicalDevice			= context.getContext().getPhysicalDevice();
   6767 	const vk::DeviceInterface&					vkd						= context.getContext().getDeviceInterface();
   6768 	const vk::VkDevice							device					= context.getContext().getDevice();
   6769 	const vk::VkRenderPass						renderPass				= context.getRenderPass();
   6770 	const deUint32								subpass					= 0;
   6771 	const vk::Unique<vk::VkShaderModule>		vertexShaderModule		(vk::createShaderModule(vkd, device, context.getBinaryCollection().get("render-quad.vert"), 0));
   6772 	const vk::Unique<vk::VkShaderModule>		fragmentShaderModule	(vk::createShaderModule(vkd, device, context.getBinaryCollection().get("storage-texel-buffer.frag"), 0));
   6773 	vector<vk::VkDescriptorSetLayoutBinding>	bindings;
   6774 
   6775 	m_device				= device;
   6776 	m_vkd					= &vkd;
   6777 	m_bufferSize			= context.getBufferSize();
   6778 	m_maxStorageTexelCount	= vk::getPhysicalDeviceProperties(vki, physicalDevice).limits.maxTexelBufferElements;
   6779 	m_targetWidth			= context.getTargetWidth();
   6780 	m_targetHeight			= context.getTargetHeight();
   6781 
   6782 	{
   6783 		const vk::VkDescriptorSetLayoutBinding binding =
   6784 		{
   6785 			0u,
   6786 			vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
   6787 			1,
   6788 			vk::VK_SHADER_STAGE_FRAGMENT_BIT,
   6789 			DE_NULL
   6790 		};
   6791 
   6792 		bindings.push_back(binding);
   6793 	}
   6794 	const vk::VkPushConstantRange pushConstantRange =
   6795 	{
   6796 		vk::VK_SHADER_STAGE_FRAGMENT_BIT,
   6797 		0u,
   6798 		16u
   6799 	};
   6800 
   6801 	createPipelineWithResources(vkd, device, renderPass, subpass, *vertexShaderModule, *fragmentShaderModule, context.getTargetWidth(), context.getTargetHeight(),
   6802 								vector<vk::VkVertexInputBindingDescription>(), vector<vk::VkVertexInputAttributeDescription>(), bindings, vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 1u, &pushConstantRange, m_resources);
   6803 
   6804 	{
   6805 		const deUint32							descriptorCount	= (deUint32)(divRoundUp(m_bufferSize, (vk::VkDeviceSize)m_maxStorageTexelCount * 4));
   6806 		const vk::VkDescriptorPoolSize			poolSizes		=
   6807 		{
   6808 			vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
   6809 			descriptorCount
   6810 		};
   6811 		const vk::VkDescriptorPoolCreateInfo	createInfo		=
   6812 		{
   6813 			vk::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
   6814 			DE_NULL,
   6815 			vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
   6816 
   6817 			descriptorCount,
   6818 			1u,
   6819 			&poolSizes,
   6820 		};
   6821 
   6822 		m_descriptorPool = vk::createDescriptorPool(vkd, device, &createInfo);
   6823 		m_descriptorSets.resize(descriptorCount, (vk::VkDescriptorSet)0);
   6824 		m_bufferViews.resize(descriptorCount, (vk::VkBufferView)0);
   6825 	}
   6826 
   6827 	for (size_t descriptorSetNdx = 0; descriptorSetNdx < m_descriptorSets.size(); descriptorSetNdx++)
   6828 	{
   6829 		const deUint32							count			= (deUint32)(m_bufferSize < (descriptorSetNdx + 1) * m_maxStorageTexelCount * 4
   6830 																? m_bufferSize - descriptorSetNdx * m_maxStorageTexelCount * 4
   6831 																: m_maxStorageTexelCount * 4) / 4;
   6832 		const vk::VkDescriptorSetLayout			layout			= *m_resources.descriptorSetLayout;
   6833 		const vk::VkDescriptorSetAllocateInfo	allocateInfo	=
   6834 		{
   6835 			vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
   6836 			DE_NULL,
   6837 
   6838 			*m_descriptorPool,
   6839 			1,
   6840 			&layout
   6841 		};
   6842 
   6843 		m_descriptorSets[descriptorSetNdx] = vk::allocateDescriptorSet(vkd, device, &allocateInfo).disown();
   6844 
   6845 		{
   6846 			const vk::VkBufferViewCreateInfo createInfo =
   6847 			{
   6848 				vk::VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
   6849 				DE_NULL,
   6850 				0u,
   6851 
   6852 				context.getBuffer(),
   6853 				vk::VK_FORMAT_R32_UINT,
   6854 				descriptorSetNdx * m_maxStorageTexelCount * 4,
   6855 				count * 4
   6856 			};
   6857 
   6858 			VK_CHECK(vkd.createBufferView(device, &createInfo, DE_NULL, &m_bufferViews[descriptorSetNdx]));
   6859 		}
   6860 
   6861 		{
   6862 			const vk::VkWriteDescriptorSet			write		=
   6863 			{
   6864 				vk::VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
   6865 				DE_NULL,
   6866 				m_descriptorSets[descriptorSetNdx],
   6867 				0u,
   6868 				0u,
   6869 				1u,
   6870 				vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
   6871 				DE_NULL,
   6872 				DE_NULL,
   6873 				&m_bufferViews[descriptorSetNdx]
   6874 			};
   6875 
   6876 			vkd.updateDescriptorSets(device, 1u, &write, 0u, DE_NULL);
   6877 		}
   6878 	}
   6879 }
   6880 
   6881 void RenderFragmentStorageTexelBuffer::submit (SubmitContext& context)
   6882 {
   6883 	const vk::DeviceInterface&	vkd				= context.getContext().getDeviceInterface();
   6884 	const vk::VkCommandBuffer	commandBuffer	= context.getCommandBuffer();
   6885 
   6886 	vkd.cmdBindPipeline(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_resources.pipeline);
   6887 
   6888 	for (size_t descriptorSetNdx = 0; descriptorSetNdx < m_descriptorSets.size(); descriptorSetNdx++)
   6889 	{
   6890 		const struct
   6891 		{
   6892 			const deUint32	callId;
   6893 			const deUint32	valuesPerPixel;
   6894 			const deUint32	maxStorageTexelCount;
   6895 			const deUint32	width;
   6896 		} callParams =
   6897 		{
   6898 			(deUint32)descriptorSetNdx,
   6899 			(deUint32)divRoundUp<size_t>(m_descriptorSets.size() * de::min<size_t>(m_maxStorageTexelCount, (size_t)m_bufferSize / 4), m_targetWidth * m_targetHeight),
   6900 			m_maxStorageTexelCount,
   6901 			(deUint32)(m_bufferSize < (descriptorSetNdx + 1u) * m_maxStorageTexelCount * 4u
   6902 								? m_bufferSize - descriptorSetNdx * m_maxStorageTexelCount * 4u
   6903 								: m_maxStorageTexelCount * 4u) / 4u
   6904 		};
   6905 
   6906 		vkd.cmdBindDescriptorSets(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_resources.pipelineLayout, 0u, 1u, &m_descriptorSets[descriptorSetNdx], 0u, DE_NULL);
   6907 		vkd.cmdPushConstants(commandBuffer, *m_resources.pipelineLayout, vk::VK_SHADER_STAGE_FRAGMENT_BIT, 0u, (deUint32)sizeof(callParams), &callParams);
   6908 		vkd.cmdDraw(commandBuffer, 6, 1, 0, 0);
   6909 	}
   6910 }
   6911 
   6912 void RenderFragmentStorageTexelBuffer::verify (VerifyRenderPassContext& context, size_t)
   6913 {
   6914 	const deUint32	valuesPerPixel	= (deUint32)divRoundUp<size_t>(m_descriptorSets.size() * de::min<size_t>(m_maxStorageTexelCount, (size_t)m_bufferSize / 4), m_targetWidth * m_targetHeight);
   6915 
   6916 	for (int y = 0; y < context.getReferenceTarget().getSize().y(); y++)
   6917 	for (int x = 0; x < context.getReferenceTarget().getSize().x(); x++)
   6918 	{
   6919 		const size_t firstDescriptorSetNdx = de::min<size_t>((y * 256u + x) / (m_maxStorageTexelCount / valuesPerPixel), m_descriptorSets.size() - 1);
   6920 
   6921 		for (size_t descriptorSetNdx = firstDescriptorSetNdx; descriptorSetNdx < m_descriptorSets.size(); descriptorSetNdx++)
   6922 		{
   6923 			const size_t	offset	= descriptorSetNdx * m_maxStorageTexelCount * 4;
   6924 			const deUint32	callId	= (deUint32)descriptorSetNdx;
   6925 
   6926 			const deUint32	id		= (deUint32)y * 256u + (deUint32)x;
   6927 			const deUint32	count	= (deUint32)(m_bufferSize < (descriptorSetNdx + 1) * m_maxStorageTexelCount * 4
   6928 									? m_bufferSize - descriptorSetNdx * m_maxStorageTexelCount * 4
   6929 									: m_maxStorageTexelCount * 4) / 4;
   6930 
   6931 			if (y * 256u + x < callId * (m_maxStorageTexelCount / valuesPerPixel))
   6932 				continue;
   6933 			else
   6934 			{
   6935 				deUint32 value = id;
   6936 
   6937 				for (deUint32 i = 0; i < valuesPerPixel; i++)
   6938 				{
   6939 					value	= ((deUint32)context.getReference().get( offset + (value % count) * 4 + 0))
   6940 							| (((deUint32)context.getReference().get(offset + (value % count) * 4 + 1)) << 8u)
   6941 							| (((deUint32)context.getReference().get(offset + (value % count) * 4 + 2)) << 16u)
   6942 							| (((deUint32)context.getReference().get(offset + (value % count) * 4 + 3)) << 24u);
   6943 
   6944 				}
   6945 				const UVec4	vec	((value >>  0u) & 0xFFu,
   6946 								 (value >>  8u) & 0xFFu,
   6947 								 (value >> 16u) & 0xFFu,
   6948 								 (value >> 24u) & 0xFFu);
   6949 
   6950 				context.getReferenceTarget().getAccess().setPixel(vec.asFloat() / Vec4(255.0f), x, y);
   6951 			}
   6952 		}
   6953 	}
   6954 }
   6955 
   6956 class RenderFragmentStorageImage : public RenderPassCommand
   6957 {
   6958 public:
   6959 									RenderFragmentStorageImage	(void) {}
   6960 									~RenderFragmentStorageImage	(void);
   6961 
   6962 	const char*						getName						(void) const { return "RenderFragmentStorageImage"; }
   6963 	void							logPrepare					(TestLog&, size_t) const;
   6964 	void							logSubmit					(TestLog&, size_t) const;
   6965 	void							prepare						(PrepareRenderPassContext&);
   6966 	void							submit						(SubmitContext& context);
   6967 	void							verify						(VerifyRenderPassContext&, size_t);
   6968 
   6969 private:
   6970 	PipelineResources				m_resources;
   6971 	vk::Move<vk::VkDescriptorPool>	m_descriptorPool;
   6972 	vk::Move<vk::VkDescriptorSet>	m_descriptorSet;
   6973 	vk::Move<vk::VkImageView>		m_imageView;
   6974 };
   6975 
   6976 RenderFragmentStorageImage::~RenderFragmentStorageImage (void)
   6977 {
   6978 }
   6979 
   6980 void RenderFragmentStorageImage::logPrepare (TestLog& log, size_t commandIndex) const
   6981 {
   6982 	log << TestLog::Message << commandIndex << ":" << getName() << " Create pipeline for render storage image." << TestLog::EndMessage;
   6983 }
   6984 
   6985 void RenderFragmentStorageImage::logSubmit (TestLog& log, size_t commandIndex) const
   6986 {
   6987 	log << TestLog::Message << commandIndex << ":" << getName() << " Render using storage image." << TestLog::EndMessage;
   6988 }
   6989 
   6990 void RenderFragmentStorageImage::prepare (PrepareRenderPassContext& context)
   6991 {
   6992 	const vk::DeviceInterface&					vkd						= context.getContext().getDeviceInterface();
   6993 	const vk::VkDevice							device					= context.getContext().getDevice();
   6994 	const vk::VkRenderPass						renderPass				= context.getRenderPass();
   6995 	const deUint32								subpass					= 0;
   6996 	const vk::Unique<vk::VkShaderModule>		vertexShaderModule		(vk::createShaderModule(vkd, device, context.getBinaryCollection().get("render-quad.vert"), 0));
   6997 	const vk::Unique<vk::VkShaderModule>		fragmentShaderModule	(vk::createShaderModule(vkd, device, context.getBinaryCollection().get("storage-image.frag"), 0));
   6998 	vector<vk::VkDescriptorSetLayoutBinding>	bindings;
   6999 
   7000 	{
   7001 		const vk::VkDescriptorSetLayoutBinding binding =
   7002 		{
   7003 			0u,
   7004 			vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
   7005 			1,
   7006 			vk::VK_SHADER_STAGE_FRAGMENT_BIT,
   7007 			DE_NULL
   7008 		};
   7009 
   7010 		bindings.push_back(binding);
   7011 	}
   7012 
   7013 	createPipelineWithResources(vkd, device, renderPass, subpass, *vertexShaderModule, *fragmentShaderModule, context.getTargetWidth(), context.getTargetHeight(),
   7014 								vector<vk::VkVertexInputBindingDescription>(), vector<vk::VkVertexInputAttributeDescription>(), bindings, vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0u, DE_NULL, m_resources);
   7015 
   7016 	{
   7017 		const vk::VkDescriptorPoolSize			poolSizes		=
   7018 		{
   7019 			vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
   7020 			1
   7021 		};
   7022 		const vk::VkDescriptorPoolCreateInfo	createInfo		=
   7023 		{
   7024 			vk::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
   7025 			DE_NULL,
   7026 			vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
   7027 
   7028 			1u,
   7029 			1u,
   7030 			&poolSizes,
   7031 		};
   7032 
   7033 		m_descriptorPool = vk::createDescriptorPool(vkd, device, &createInfo);
   7034 	}
   7035 
   7036 	{
   7037 		const vk::VkDescriptorSetLayout			layout			= *m_resources.descriptorSetLayout;
   7038 		const vk::VkDescriptorSetAllocateInfo	allocateInfo	=
   7039 		{
   7040 			vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
   7041 			DE_NULL,
   7042 
   7043 			*m_descriptorPool,
   7044 			1,
   7045 			&layout
   7046 		};
   7047 
   7048 		m_descriptorSet = vk::allocateDescriptorSet(vkd, device, &allocateInfo);
   7049 
   7050 		{
   7051 			const vk::VkImageViewCreateInfo createInfo =
   7052 			{
   7053 				vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
   7054 				DE_NULL,
   7055 				0u,
   7056 
   7057 				context.getImage(),
   7058 				vk::VK_IMAGE_VIEW_TYPE_2D,
   7059 				vk::VK_FORMAT_R8G8B8A8_UNORM,
   7060 				vk::makeComponentMappingRGBA(),
   7061 				{
   7062 					vk::VK_IMAGE_ASPECT_COLOR_BIT,
   7063 					0u,
   7064 					1u,
   7065 					0u,
   7066 					1u
   7067 				}
   7068 			};
   7069 
   7070 			m_imageView = vk::createImageView(vkd, device, &createInfo);
   7071 		}
   7072 
   7073 		{
   7074 			const vk::VkDescriptorImageInfo			imageInfo	=
   7075 			{
   7076 				0,
   7077 				*m_imageView,
   7078 				context.getImageLayout()
   7079 			};
   7080 			const vk::VkWriteDescriptorSet			write		=
   7081 			{
   7082 				vk::VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
   7083 				DE_NULL,
   7084 				*m_descriptorSet,
   7085 				0u,
   7086 				0u,
   7087 				1u,
   7088 				vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
   7089 				&imageInfo,
   7090 				DE_NULL,
   7091 				DE_NULL,
   7092 			};
   7093 
   7094 			vkd.updateDescriptorSets(device, 1u, &write, 0u, DE_NULL);
   7095 		}
   7096 	}
   7097 }
   7098 
   7099 void RenderFragmentStorageImage::submit (SubmitContext& context)
   7100 {
   7101 	const vk::DeviceInterface&	vkd				= context.getContext().getDeviceInterface();
   7102 	const vk::VkCommandBuffer	commandBuffer	= context.getCommandBuffer();
   7103 
   7104 	vkd.cmdBindPipeline(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_resources.pipeline);
   7105 
   7106 	vkd.cmdBindDescriptorSets(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_resources.pipelineLayout, 0u, 1u, &(*m_descriptorSet), 0u, DE_NULL);
   7107 	vkd.cmdDraw(commandBuffer, 6, 1, 0, 0);
   7108 }
   7109 
   7110 void RenderFragmentStorageImage::verify (VerifyRenderPassContext& context, size_t)
   7111 {
   7112 	const UVec2		size			= UVec2(context.getReferenceImage().getWidth(), context.getReferenceImage().getHeight());
   7113 	const deUint32	valuesPerPixel	= de::max<deUint32>(1u, (size.x() * size.y()) / (256u * 256u));
   7114 
   7115 	for (int y = 0; y < context.getReferenceTarget().getSize().y(); y++)
   7116 	for (int x = 0; x < context.getReferenceTarget().getSize().x(); x++)
   7117 	{
   7118 		UVec4	value	= UVec4(x, y, 0u, 0u);
   7119 
   7120 		for (deUint32 i = 0; i < valuesPerPixel; i++)
   7121 		{
   7122 			const UVec2	pos			= UVec2(value.z() * 256u + (value.x() ^ value.z()), value.w() * 256u + (value.y() ^ value.w()));
   7123 			const Vec4	floatValue	= context.getReferenceImage().getAccess().getPixel(pos.x() % size.x(), pos.y() % size.y());
   7124 
   7125 			value = UVec4((deUint32)(floatValue.x() * 255.0f),
   7126 						  (deUint32)(floatValue.y() * 255.0f),
   7127 						  (deUint32)(floatValue.z() * 255.0f),
   7128 						  (deUint32)(floatValue.w() * 255.0f));
   7129 
   7130 		}
   7131 		context.getReferenceTarget().getAccess().setPixel(value.asFloat() / Vec4(255.0f), x, y);
   7132 	}
   7133 }
   7134 
   7135 class RenderFragmentSampledImage : public RenderPassCommand
   7136 {
   7137 public:
   7138 				RenderFragmentSampledImage	(void) {}
   7139 				~RenderFragmentSampledImage	(void);
   7140 
   7141 	const char*	getName						(void) const { return "RenderFragmentSampledImage"; }
   7142 	void		logPrepare					(TestLog&, size_t) const;
   7143 	void		logSubmit					(TestLog&, size_t) const;
   7144 	void		prepare						(PrepareRenderPassContext&);
   7145 	void		submit						(SubmitContext& context);
   7146 	void		verify						(VerifyRenderPassContext&, size_t);
   7147 
   7148 private:
   7149 	PipelineResources				m_resources;
   7150 	vk::Move<vk::VkDescriptorPool>	m_descriptorPool;
   7151 	vk::Move<vk::VkDescriptorSet>	m_descriptorSet;
   7152 	vk::Move<vk::VkImageView>		m_imageView;
   7153 	vk::Move<vk::VkSampler>			m_sampler;
   7154 };
   7155 
   7156 RenderFragmentSampledImage::~RenderFragmentSampledImage (void)
   7157 {
   7158 }
   7159 
   7160 void RenderFragmentSampledImage::logPrepare (TestLog& log, size_t commandIndex) const
   7161 {
   7162 	log << TestLog::Message << commandIndex << ":" << getName() << " Create pipeline for render storage image." << TestLog::EndMessage;
   7163 }
   7164 
   7165 void RenderFragmentSampledImage::logSubmit (TestLog& log, size_t commandIndex) const
   7166 {
   7167 	log << TestLog::Message << commandIndex << ":" << getName() << " Render using storage image." << TestLog::EndMessage;
   7168 }
   7169 
   7170 void RenderFragmentSampledImage::prepare (PrepareRenderPassContext& context)
   7171 {
   7172 	const vk::DeviceInterface&					vkd						= context.getContext().getDeviceInterface();
   7173 	const vk::VkDevice							device					= context.getContext().getDevice();
   7174 	const vk::VkRenderPass						renderPass				= context.getRenderPass();
   7175 	const deUint32								subpass					= 0;
   7176 	const vk::Unique<vk::VkShaderModule>		vertexShaderModule		(vk::createShaderModule(vkd, device, context.getBinaryCollection().get("render-quad.vert"), 0));
   7177 	const vk::Unique<vk::VkShaderModule>		fragmentShaderModule	(vk::createShaderModule(vkd, device, context.getBinaryCollection().get("sampled-image.frag"), 0));
   7178 	vector<vk::VkDescriptorSetLayoutBinding>	bindings;
   7179 
   7180 	{
   7181 		const vk::VkDescriptorSetLayoutBinding binding =
   7182 		{
   7183 			0u,
   7184 			vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
   7185 			1,
   7186 			vk::VK_SHADER_STAGE_FRAGMENT_BIT,
   7187 			DE_NULL
   7188 		};
   7189 
   7190 		bindings.push_back(binding);
   7191 	}
   7192 
   7193 	createPipelineWithResources(vkd, device, renderPass, subpass, *vertexShaderModule, *fragmentShaderModule, context.getTargetWidth(), context.getTargetHeight(),
   7194 								vector<vk::VkVertexInputBindingDescription>(), vector<vk::VkVertexInputAttributeDescription>(), bindings, vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0u, DE_NULL, m_resources);
   7195 
   7196 	{
   7197 		const vk::VkDescriptorPoolSize			poolSizes		=
   7198 		{
   7199 			vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
   7200 			1
   7201 		};
   7202 		const vk::VkDescriptorPoolCreateInfo	createInfo		=
   7203 		{
   7204 			vk::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
   7205 			DE_NULL,
   7206 			vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
   7207 
   7208 			1u,
   7209 			1u,
   7210 			&poolSizes,
   7211 		};
   7212 
   7213 		m_descriptorPool = vk::createDescriptorPool(vkd, device, &createInfo);
   7214 	}
   7215 
   7216 	{
   7217 		const vk::VkDescriptorSetLayout			layout			= *m_resources.descriptorSetLayout;
   7218 		const vk::VkDescriptorSetAllocateInfo	allocateInfo	=
   7219 		{
   7220 			vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
   7221 			DE_NULL,
   7222 
   7223 			*m_descriptorPool,
   7224 			1,
   7225 			&layout
   7226 		};
   7227 
   7228 		m_descriptorSet = vk::allocateDescriptorSet(vkd, device, &allocateInfo);
   7229 
   7230 		{
   7231 			const vk::VkImageViewCreateInfo createInfo =
   7232 			{
   7233 				vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
   7234 				DE_NULL,
   7235 				0u,
   7236 
   7237 				context.getImage(),
   7238 				vk::VK_IMAGE_VIEW_TYPE_2D,
   7239 				vk::VK_FORMAT_R8G8B8A8_UNORM,
   7240 				vk::makeComponentMappingRGBA(),
   7241 				{
   7242 					vk::VK_IMAGE_ASPECT_COLOR_BIT,
   7243 					0u,
   7244 					1u,
   7245 					0u,
   7246 					1u
   7247 				}
   7248 			};
   7249 
   7250 			m_imageView = vk::createImageView(vkd, device, &createInfo);
   7251 		}
   7252 
   7253 		{
   7254 			const vk::VkSamplerCreateInfo createInfo =
   7255 			{
   7256 				vk::VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
   7257 				DE_NULL,
   7258 				0u,
   7259 
   7260 				vk::VK_FILTER_NEAREST,
   7261 				vk::VK_FILTER_NEAREST,
   7262 
   7263 				vk::VK_SAMPLER_MIPMAP_MODE_LINEAR,
   7264 				vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
   7265 				vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
   7266 				vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
   7267 				0.0f,
   7268 				VK_FALSE,
   7269 				1.0f,
   7270 				VK_FALSE,
   7271 				vk::VK_COMPARE_OP_ALWAYS,
   7272 				0.0f,
   7273 				0.0f,
   7274 				vk::VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,
   7275 				VK_FALSE
   7276 			};
   7277 
   7278 			m_sampler = vk::createSampler(vkd, device, &createInfo);
   7279 		}
   7280 
   7281 		{
   7282 			const vk::VkDescriptorImageInfo			imageInfo	=
   7283 			{
   7284 				*m_sampler,
   7285 				*m_imageView,
   7286 				context.getImageLayout()
   7287 			};
   7288 			const vk::VkWriteDescriptorSet			write		=
   7289 			{
   7290 				vk::VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
   7291 				DE_NULL,
   7292 				*m_descriptorSet,
   7293 				0u,
   7294 				0u,
   7295 				1u,
   7296 				vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
   7297 				&imageInfo,
   7298 				DE_NULL,
   7299 				DE_NULL,
   7300 			};
   7301 
   7302 			vkd.updateDescriptorSets(device, 1u, &write, 0u, DE_NULL);
   7303 		}
   7304 	}
   7305 }
   7306 
   7307 void RenderFragmentSampledImage::submit (SubmitContext& context)
   7308 {
   7309 	const vk::DeviceInterface&	vkd				= context.getContext().getDeviceInterface();
   7310 	const vk::VkCommandBuffer	commandBuffer	= context.getCommandBuffer();
   7311 
   7312 	vkd.cmdBindPipeline(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_resources.pipeline);
   7313 
   7314 	vkd.cmdBindDescriptorSets(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_resources.pipelineLayout, 0u, 1u, &(*m_descriptorSet), 0u, DE_NULL);
   7315 	vkd.cmdDraw(commandBuffer, 6u, 1u, 0u, 0u);
   7316 }
   7317 
   7318 void RenderFragmentSampledImage::verify (VerifyRenderPassContext& context, size_t)
   7319 {
   7320 	const UVec2		size			= UVec2(context.getReferenceImage().getWidth(), context.getReferenceImage().getHeight());
   7321 	const deUint32	valuesPerPixel	= de::max<deUint32>(1u, (size.x() * size.y()) / (256u * 256u));
   7322 
   7323 	for (int y = 0; y < context.getReferenceTarget().getSize().y(); y++)
   7324 	for (int x = 0; x < context.getReferenceTarget().getSize().x(); x++)
   7325 	{
   7326 		UVec4	value	= UVec4(x, y, 0u, 0u);
   7327 
   7328 		for (deUint32 i = 0; i < valuesPerPixel; i++)
   7329 		{
   7330 			const UVec2	pos			= UVec2(value.z() * 256u + (value.x() ^ value.z()), value.w() * 256u + (value.y() ^ value.w()));
   7331 			const Vec4	floatValue	= context.getReferenceImage().getAccess().getPixel(pos.x() % size.x(), pos.y() % size.y());
   7332 
   7333 			value = UVec4((deUint32)(floatValue.x() * 255.0f),
   7334 						  (deUint32)(floatValue.y() * 255.0f),
   7335 						  (deUint32)(floatValue.z() * 255.0f),
   7336 						  (deUint32)(floatValue.w() * 255.0f));
   7337 
   7338 		}
   7339 
   7340 		context.getReferenceTarget().getAccess().setPixel(value.asFloat() / Vec4(255.0f), x, y);
   7341 	}
   7342 }
   7343 
   7344 enum Op
   7345 {
   7346 	OP_MAP,
   7347 	OP_UNMAP,
   7348 
   7349 	OP_MAP_FLUSH,
   7350 	OP_MAP_INVALIDATE,
   7351 
   7352 	OP_MAP_READ,
   7353 	OP_MAP_WRITE,
   7354 	OP_MAP_MODIFY,
   7355 
   7356 	OP_BUFFER_CREATE,
   7357 	OP_BUFFER_DESTROY,
   7358 	OP_BUFFER_BINDMEMORY,
   7359 
   7360 	OP_QUEUE_WAIT_FOR_IDLE,
   7361 	OP_DEVICE_WAIT_FOR_IDLE,
   7362 
   7363 	OP_COMMAND_BUFFER_BEGIN,
   7364 	OP_COMMAND_BUFFER_END,
   7365 
   7366 	// Buffer transfer operations
   7367 	OP_BUFFER_FILL,
   7368 	OP_BUFFER_UPDATE,
   7369 
   7370 	OP_BUFFER_COPY_TO_BUFFER,
   7371 	OP_BUFFER_COPY_FROM_BUFFER,
   7372 
   7373 	OP_BUFFER_COPY_TO_IMAGE,
   7374 	OP_BUFFER_COPY_FROM_IMAGE,
   7375 
   7376 	OP_IMAGE_CREATE,
   7377 	OP_IMAGE_DESTROY,
   7378 	OP_IMAGE_BINDMEMORY,
   7379 
   7380 	OP_IMAGE_TRANSITION_LAYOUT,
   7381 
   7382 	OP_IMAGE_COPY_TO_BUFFER,
   7383 	OP_IMAGE_COPY_FROM_BUFFER,
   7384 
   7385 	OP_IMAGE_COPY_TO_IMAGE,
   7386 	OP_IMAGE_COPY_FROM_IMAGE,
   7387 
   7388 	OP_IMAGE_BLIT_TO_IMAGE,
   7389 	OP_IMAGE_BLIT_FROM_IMAGE,
   7390 
   7391 	OP_IMAGE_RESOLVE,
   7392 
   7393 	OP_PIPELINE_BARRIER_GLOBAL,
   7394 	OP_PIPELINE_BARRIER_BUFFER,
   7395 	OP_PIPELINE_BARRIER_IMAGE,
   7396 
   7397 	// Renderpass operations
   7398 	OP_RENDERPASS_BEGIN,
   7399 	OP_RENDERPASS_END,
   7400 
   7401 	// Commands inside render pass
   7402 	OP_RENDER_VERTEX_BUFFER,
   7403 	OP_RENDER_INDEX_BUFFER,
   7404 
   7405 	OP_RENDER_VERTEX_UNIFORM_BUFFER,
   7406 	OP_RENDER_FRAGMENT_UNIFORM_BUFFER,
   7407 
   7408 	OP_RENDER_VERTEX_UNIFORM_TEXEL_BUFFER,
   7409 	OP_RENDER_FRAGMENT_UNIFORM_TEXEL_BUFFER,
   7410 
   7411 	OP_RENDER_VERTEX_STORAGE_BUFFER,
   7412 	OP_RENDER_FRAGMENT_STORAGE_BUFFER,
   7413 
   7414 	OP_RENDER_VERTEX_STORAGE_TEXEL_BUFFER,
   7415 	OP_RENDER_FRAGMENT_STORAGE_TEXEL_BUFFER,
   7416 
   7417 	OP_RENDER_VERTEX_STORAGE_IMAGE,
   7418 	OP_RENDER_FRAGMENT_STORAGE_IMAGE,
   7419 
   7420 	OP_RENDER_VERTEX_SAMPLED_IMAGE,
   7421 	OP_RENDER_FRAGMENT_SAMPLED_IMAGE,
   7422 };
   7423 
   7424 enum Stage
   7425 {
   7426 	STAGE_HOST,
   7427 	STAGE_COMMAND_BUFFER,
   7428 
   7429 	STAGE_RENDER_PASS
   7430 };
   7431 
   7432 vk::VkAccessFlags getWriteAccessFlags (void)
   7433 {
   7434 	return vk::VK_ACCESS_SHADER_WRITE_BIT
   7435 		| vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
   7436 		| vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
   7437 		| vk::VK_ACCESS_TRANSFER_WRITE_BIT
   7438 		| vk::VK_ACCESS_HOST_WRITE_BIT
   7439 		| vk::VK_ACCESS_MEMORY_WRITE_BIT;
   7440 }
   7441 
   7442 bool isWriteAccess (vk::VkAccessFlagBits access)
   7443 {
   7444 	return (getWriteAccessFlags() & access) != 0;
   7445 }
   7446 
   7447 class CacheState
   7448 {
   7449 public:
   7450 									CacheState				(vk::VkPipelineStageFlags allowedStages, vk::VkAccessFlags allowedAccesses);
   7451 
   7452 	bool							isValid					(vk::VkPipelineStageFlagBits	stage,
   7453 															 vk::VkAccessFlagBits			access) const;
   7454 
   7455 	void							perform					(vk::VkPipelineStageFlagBits	stage,
   7456 															 vk::VkAccessFlagBits			access);
   7457 
   7458 	void							submitCommandBuffer		(void);
   7459 	void							waitForIdle				(void);
   7460 
   7461 	void							getFullBarrier			(vk::VkPipelineStageFlags&	srcStages,
   7462 															 vk::VkAccessFlags&			srcAccesses,
   7463 															 vk::VkPipelineStageFlags&	dstStages,
   7464 															 vk::VkAccessFlags&			dstAccesses) const;
   7465 
   7466 	void							barrier					(vk::VkPipelineStageFlags	srcStages,
   7467 															 vk::VkAccessFlags			srcAccesses,
   7468 															 vk::VkPipelineStageFlags	dstStages,
   7469 															 vk::VkAccessFlags			dstAccesses);
   7470 
   7471 	void							imageLayoutBarrier		(vk::VkPipelineStageFlags	srcStages,
   7472 															 vk::VkAccessFlags			srcAccesses,
   7473 															 vk::VkPipelineStageFlags	dstStages,
   7474 															 vk::VkAccessFlags			dstAccesses);
   7475 
   7476 	void							checkImageLayoutBarrier	(vk::VkPipelineStageFlags	srcStages,
   7477 															 vk::VkAccessFlags			srcAccesses,
   7478 															 vk::VkPipelineStageFlags	dstStages,
   7479 															 vk::VkAccessFlags			dstAccesses);
   7480 
   7481 	// Everything is clean and there is no need for barriers
   7482 	bool							isClean					(void) const;
   7483 
   7484 	vk::VkPipelineStageFlags		getAllowedStages		(void) const { return m_allowedStages; }
   7485 	vk::VkAccessFlags				getAllowedAcceses		(void) const { return m_allowedAccesses; }
   7486 private:
   7487 	// Limit which stages and accesses are used by the CacheState tracker
   7488 	const vk::VkPipelineStageFlags	m_allowedStages;
   7489 	const vk::VkAccessFlags			m_allowedAccesses;
   7490 
   7491 	// [dstStage][srcStage] = srcAccesses
   7492 	// In stage dstStage write srcAccesses from srcStage are not yet available
   7493 	vk::VkAccessFlags				m_unavailableWriteOperations[PIPELINESTAGE_LAST][PIPELINESTAGE_LAST];
   7494 	// Latest pipeline transition is not available in stage
   7495 	bool							m_unavailableLayoutTransition[PIPELINESTAGE_LAST];
   7496 	// [dstStage] = dstAccesses
   7497 	// In stage dstStage ops with dstAccesses are not yet visible
   7498 	vk::VkAccessFlags				m_invisibleOperations[PIPELINESTAGE_LAST];
   7499 
   7500 	// [dstStage] = srcStage
   7501 	// Memory operation in srcStage have not completed before dstStage
   7502 	vk::VkPipelineStageFlags		m_incompleteOperations[PIPELINESTAGE_LAST];
   7503 };
   7504 
   7505 CacheState::CacheState (vk::VkPipelineStageFlags allowedStages, vk::VkAccessFlags allowedAccesses)
   7506 	: m_allowedStages	(allowedStages)
   7507 	, m_allowedAccesses	(allowedAccesses)
   7508 {
   7509 	for (vk::VkPipelineStageFlags dstStage_ = 1; dstStage_ <= m_allowedStages; dstStage_ <<= 1)
   7510 	{
   7511 		const PipelineStage dstStage = pipelineStageFlagToPipelineStage((vk::VkPipelineStageFlagBits)dstStage_);
   7512 
   7513 		if ((dstStage_ & m_allowedStages) == 0)
   7514 			continue;
   7515 
   7516 		// All operations are initially visible
   7517 		m_invisibleOperations[dstStage] = 0;
   7518 
   7519 		// There are no incomplete read operations initially
   7520 		m_incompleteOperations[dstStage] = 0;
   7521 
   7522 		// There are no incomplete layout transitions
   7523 		m_unavailableLayoutTransition[dstStage] = false;
   7524 
   7525 		for (vk::VkPipelineStageFlags srcStage_ = 1; srcStage_ <= m_allowedStages; srcStage_ <<= 1)
   7526 		{
   7527 			const PipelineStage srcStage = pipelineStageFlagToPipelineStage((vk::VkPipelineStageFlagBits)srcStage_);
   7528 
   7529 			if ((srcStage_ & m_allowedStages) == 0)
   7530 				continue;
   7531 
   7532 			// There are no write operations that are not yet available
   7533 			// initially.
   7534 			m_unavailableWriteOperations[dstStage][srcStage] = 0;
   7535 		}
   7536 	}
   7537 }
   7538 
   7539 bool CacheState::isValid (vk::VkPipelineStageFlagBits	stage,
   7540 						  vk::VkAccessFlagBits			access) const
   7541 {
   7542 	DE_ASSERT((access & (~m_allowedAccesses)) == 0);
   7543 	DE_ASSERT((stage & (~m_allowedStages)) == 0);
   7544 
   7545 	const PipelineStage	dstStage	= pipelineStageFlagToPipelineStage(stage);
   7546 
   7547 	// Previous operations are not visible to access on stage
   7548 	if (m_unavailableLayoutTransition[dstStage] || (m_invisibleOperations[dstStage] & access) != 0)
   7549 		return false;
   7550 
   7551 	if (isWriteAccess(access))
   7552 	{
   7553 		// Memory operations from other stages have not completed before
   7554 		// dstStage
   7555 		if (m_incompleteOperations[dstStage] != 0)
   7556 			return false;
   7557 	}
   7558 
   7559 	return true;
   7560 }
   7561 
   7562 void CacheState::perform (vk::VkPipelineStageFlagBits	stage,
   7563 						  vk::VkAccessFlagBits			access)
   7564 {
   7565 	DE_ASSERT((access & (~m_allowedAccesses)) == 0);
   7566 	DE_ASSERT((stage & (~m_allowedStages)) == 0);
   7567 
   7568 	const PipelineStage srcStage = pipelineStageFlagToPipelineStage(stage);
   7569 
   7570 	for (vk::VkPipelineStageFlags dstStage_ = 1; dstStage_ <= m_allowedStages; dstStage_ <<= 1)
   7571 	{
   7572 		const PipelineStage dstStage = pipelineStageFlagToPipelineStage((vk::VkPipelineStageFlagBits)dstStage_);
   7573 
   7574 		if ((dstStage_ & m_allowedStages) == 0)
   7575 			continue;
   7576 
   7577 		// Mark stage as incomplete for all stages
   7578 		m_incompleteOperations[dstStage] |= stage;
   7579 
   7580 		if (isWriteAccess(access))
   7581 		{
   7582 			// Mark all accesses from all stages invisible
   7583 			m_invisibleOperations[dstStage] |= m_allowedAccesses;
   7584 
   7585 			// Mark write access from srcStage unavailable to all stages
   7586 			m_unavailableWriteOperations[dstStage][srcStage] |= access;
   7587 		}
   7588 	}
   7589 }
   7590 
   7591 void CacheState::submitCommandBuffer (void)
   7592 {
   7593 	// Flush all host writes and reads
   7594 	barrier(m_allowedStages & vk::VK_PIPELINE_STAGE_HOST_BIT,
   7595 			m_allowedAccesses & (vk::VK_ACCESS_HOST_READ_BIT | vk::VK_ACCESS_HOST_WRITE_BIT),
   7596 			m_allowedStages,
   7597 			m_allowedAccesses);
   7598 }
   7599 
   7600 void CacheState::waitForIdle (void)
   7601 {
   7602 	// Make all writes available
   7603 	barrier(m_allowedStages,
   7604 			m_allowedAccesses & getWriteAccessFlags(),
   7605 			m_allowedStages,
   7606 			0);
   7607 
   7608 	// Make all writes visible on device side
   7609 	barrier(m_allowedStages,
   7610 			0,
   7611 			m_allowedStages & (~vk::VK_PIPELINE_STAGE_HOST_BIT),
   7612 			m_allowedAccesses);
   7613 }
   7614 
   7615 void CacheState::getFullBarrier (vk::VkPipelineStageFlags&	srcStages,
   7616 								 vk::VkAccessFlags&			srcAccesses,
   7617 								 vk::VkPipelineStageFlags&	dstStages,
   7618 								 vk::VkAccessFlags&			dstAccesses) const
   7619 {
   7620 	srcStages	= 0;
   7621 	srcAccesses	= 0;
   7622 	dstStages	= 0;
   7623 	dstAccesses	= 0;
   7624 
   7625 	for (vk::VkPipelineStageFlags dstStage_ = 1; dstStage_ <= m_allowedStages; dstStage_ <<= 1)
   7626 	{
   7627 		const PipelineStage dstStage = pipelineStageFlagToPipelineStage((vk::VkPipelineStageFlagBits)dstStage_);
   7628 
   7629 		if ((dstStage_ & m_allowedStages) == 0)
   7630 			continue;
   7631 
   7632 		// Make sure all previous operation are complete in all stages
   7633 		if (m_incompleteOperations[dstStage])
   7634 		{
   7635 			dstStages |= dstStage_;
   7636 			srcStages |= m_incompleteOperations[dstStage];
   7637 		}
   7638 
   7639 		// Make sure all read operations are visible in dstStage
   7640 		if (m_invisibleOperations[dstStage])
   7641 		{
   7642 			dstStages |= dstStage_;
   7643 			dstAccesses |= m_invisibleOperations[dstStage];
   7644 		}
   7645 
   7646 		// Make sure all write operations fro mall stages are available
   7647 		for (vk::VkPipelineStageFlags srcStage_ = 1; srcStage_ <= m_allowedStages; srcStage_ <<= 1)
   7648 		{
   7649 			const PipelineStage srcStage = pipelineStageFlagToPipelineStage((vk::VkPipelineStageFlagBits)srcStage_);
   7650 
   7651 			if ((srcStage_ & m_allowedStages) == 0)
   7652 				continue;
   7653 
   7654 			if (m_unavailableWriteOperations[dstStage][srcStage])
   7655 			{
   7656 				dstStages |= dstStage_;
   7657 				srcStages |= dstStage_;
   7658 				srcAccesses |= m_unavailableWriteOperations[dstStage][srcStage];
   7659 			}
   7660 
   7661 			if (m_unavailableLayoutTransition[dstStage] && !m_unavailableLayoutTransition[srcStage])
   7662 			{
   7663 				// Add dependency between srcStage and dstStage if layout transition has not completed in dstStage,
   7664 				// but has completed in srcStage.
   7665 				dstStages |= dstStage_;
   7666 				srcStages |= dstStage_;
   7667 			}
   7668 		}
   7669 	}
   7670 
   7671 	DE_ASSERT((srcStages & (~m_allowedStages)) == 0);
   7672 	DE_ASSERT((srcAccesses & (~m_allowedAccesses)) == 0);
   7673 	DE_ASSERT((dstStages & (~m_allowedStages)) == 0);
   7674 	DE_ASSERT((dstAccesses & (~m_allowedAccesses)) == 0);
   7675 }
   7676 
   7677 void CacheState::checkImageLayoutBarrier (vk::VkPipelineStageFlags	srcStages,
   7678 										 vk::VkAccessFlags			srcAccesses,
   7679 										 vk::VkPipelineStageFlags	dstStages,
   7680 										 vk::VkAccessFlags			dstAccesses)
   7681 {
   7682 	DE_ASSERT((srcStages & (~m_allowedStages)) == 0);
   7683 	DE_ASSERT((srcAccesses & (~m_allowedAccesses)) == 0);
   7684 	DE_ASSERT((dstStages & (~m_allowedStages)) == 0);
   7685 	DE_ASSERT((dstAccesses & (~m_allowedAccesses)) == 0);
   7686 
   7687 	DE_UNREF(srcStages);
   7688 	DE_UNREF(srcAccesses);
   7689 
   7690 	DE_UNREF(dstStages);
   7691 	DE_UNREF(dstAccesses);
   7692 
   7693 #if defined(DE_DEBUG)
   7694 	// Check that all stages have completed before srcStages or are in srcStages.
   7695 	{
   7696 		vk::VkPipelineStageFlags completedStages = srcStages;
   7697 
   7698 		for (vk::VkPipelineStageFlags srcStage_ = 1; srcStage_ <= srcStages; srcStage_ <<= 1)
   7699 		{
   7700 			const PipelineStage srcStage = pipelineStageFlagToPipelineStage((vk::VkPipelineStageFlagBits)srcStage_);
   7701 
   7702 			if ((srcStage_ & srcStages) == 0)
   7703 				continue;
   7704 
   7705 			completedStages |= (~m_incompleteOperations[srcStage]);
   7706 		}
   7707 
   7708 		DE_ASSERT((completedStages & m_allowedStages) == m_allowedStages);
   7709 	}
   7710 
   7711 	// Check that any write is available at least in one stage. Since all stages are complete even single flush is enough.
   7712 	if ((getWriteAccessFlags() & m_allowedAccesses) != 0 && (srcAccesses & getWriteAccessFlags()) == 0)
   7713 	{
   7714 		bool anyWriteAvailable = false;
   7715 
   7716 		for (vk::VkPipelineStageFlags dstStage_ = 1; dstStage_ <= m_allowedStages; dstStage_ <<= 1)
   7717 		{
   7718 			const PipelineStage dstStage = pipelineStageFlagToPipelineStage((vk::VkPipelineStageFlagBits)dstStage_);
   7719 
   7720 			if ((dstStage_ & m_allowedStages) == 0)
   7721 				continue;
   7722 
   7723 			for (vk::VkPipelineStageFlags srcStage_ = 1; srcStage_ <= m_allowedStages; srcStage_ <<= 1)
   7724 			{
   7725 				const PipelineStage srcStage = pipelineStageFlagToPipelineStage((vk::VkPipelineStageFlagBits)srcStage_);
   7726 
   7727 				if ((srcStage_ & m_allowedStages) == 0)
   7728 					continue;
   7729 
   7730 				if (m_unavailableWriteOperations[dstStage][srcStage] != (getWriteAccessFlags() & m_allowedAccesses))
   7731 				{
   7732 					anyWriteAvailable = true;
   7733 					break;
   7734 				}
   7735 			}
   7736 		}
   7737 
   7738 		DE_ASSERT(anyWriteAvailable);
   7739 	}
   7740 #endif
   7741 }
   7742 
   7743 void CacheState::imageLayoutBarrier (vk::VkPipelineStageFlags	srcStages,
   7744 									 vk::VkAccessFlags			srcAccesses,
   7745 									 vk::VkPipelineStageFlags	dstStages,
   7746 									 vk::VkAccessFlags			dstAccesses)
   7747 {
   7748 	checkImageLayoutBarrier(srcStages, srcAccesses, dstStages, dstAccesses);
   7749 
   7750 	for (vk::VkPipelineStageFlags dstStage_ = 1; dstStage_ <= m_allowedStages; dstStage_ <<= 1)
   7751 	{
   7752 		const PipelineStage dstStage = pipelineStageFlagToPipelineStage((vk::VkPipelineStageFlagBits)dstStage_);
   7753 
   7754 		if ((dstStage_ & m_allowedStages) == 0)
   7755 			continue;
   7756 
   7757 		// All stages are incomplete after the barrier except each dstStage in it self.
   7758 		m_incompleteOperations[dstStage] = m_allowedStages & (~dstStage_);
   7759 
   7760 		// All memory operations are invisible unless they are listed in dstAccess
   7761 		m_invisibleOperations[dstStage] = m_allowedAccesses & (~dstAccesses);
   7762 
   7763 		// Layout transition is unavailable in stage unless it was listed in dstStages
   7764 		m_unavailableLayoutTransition[dstStage]= (dstStage_ & dstStages) == 0;
   7765 
   7766 		for (vk::VkPipelineStageFlags srcStage_ = 1; srcStage_ <= m_allowedStages; srcStage_ <<= 1)
   7767 		{
   7768 			const PipelineStage srcStage = pipelineStageFlagToPipelineStage((vk::VkPipelineStageFlagBits)srcStage_);
   7769 
   7770 			if ((srcStage_ & m_allowedStages) == 0)
   7771 				continue;
   7772 
   7773 			// All write operations are available after layout transition
   7774 			m_unavailableWriteOperations[dstStage][srcStage] = 0;
   7775 		}
   7776 	}
   7777 }
   7778 
   7779 void CacheState::barrier (vk::VkPipelineStageFlags	srcStages,
   7780 						  vk::VkAccessFlags			srcAccesses,
   7781 						  vk::VkPipelineStageFlags	dstStages,
   7782 						  vk::VkAccessFlags			dstAccesses)
   7783 {
   7784 	DE_ASSERT((srcStages & (~m_allowedStages)) == 0);
   7785 	DE_ASSERT((srcAccesses & (~m_allowedAccesses)) == 0);
   7786 	DE_ASSERT((dstStages & (~m_allowedStages)) == 0);
   7787 	DE_ASSERT((dstAccesses & (~m_allowedAccesses)) == 0);
   7788 
   7789 	// Transitivity
   7790 	{
   7791 		vk::VkPipelineStageFlags		oldIncompleteOperations[PIPELINESTAGE_LAST];
   7792 		vk::VkAccessFlags				oldUnavailableWriteOperations[PIPELINESTAGE_LAST][PIPELINESTAGE_LAST];
   7793 		bool							oldUnavailableLayoutTransition[PIPELINESTAGE_LAST];
   7794 
   7795 		deMemcpy(oldIncompleteOperations, m_incompleteOperations, sizeof(oldIncompleteOperations));
   7796 		deMemcpy(oldUnavailableWriteOperations, m_unavailableWriteOperations, sizeof(oldUnavailableWriteOperations));
   7797 		deMemcpy(oldUnavailableLayoutTransition, m_unavailableLayoutTransition, sizeof(oldUnavailableLayoutTransition));
   7798 
   7799 		for (vk::VkPipelineStageFlags srcStage_ = 1; srcStage_ <= srcStages; srcStage_ <<= 1)
   7800 		{
   7801 			const PipelineStage srcStage = pipelineStageFlagToPipelineStage((vk::VkPipelineStageFlagBits)srcStage_);
   7802 
   7803 			if ((srcStage_ & srcStages) == 0)
   7804 				continue;
   7805 
   7806 			for (vk::VkPipelineStageFlags dstStage_ = 1; dstStage_ <= dstStages; dstStage_ <<= 1)
   7807 			{
   7808 				const PipelineStage	dstStage			= pipelineStageFlagToPipelineStage((vk::VkPipelineStageFlagBits)dstStage_);
   7809 
   7810 				if ((dstStage_ & dstStages) == 0)
   7811 					continue;
   7812 
   7813 				// Stages that have completed before srcStage have also completed before dstStage
   7814 				m_incompleteOperations[dstStage] &= oldIncompleteOperations[srcStage];
   7815 
   7816 				// Image layout transition in srcStage are now available in dstStage
   7817 				m_unavailableLayoutTransition[dstStage] &= oldUnavailableLayoutTransition[srcStage];
   7818 
   7819 				for (vk::VkPipelineStageFlags sharedStage_ = 1; sharedStage_ <= m_allowedStages; sharedStage_ <<= 1)
   7820 				{
   7821 					const PipelineStage	sharedStage			= pipelineStageFlagToPipelineStage((vk::VkPipelineStageFlagBits)sharedStage_);
   7822 
   7823 					if ((sharedStage_ & m_allowedStages) == 0)
   7824 						continue;
   7825 
   7826 					// Writes that are available in srcStage are also available in dstStage
   7827 					m_unavailableWriteOperations[dstStage][sharedStage] &= oldUnavailableWriteOperations[srcStage][sharedStage];
   7828 				}
   7829 			}
   7830 		}
   7831 	}
   7832 
   7833 	// Barrier
   7834 	for (vk::VkPipelineStageFlags dstStage_ = 1; dstStage_ <= dstStages; dstStage_ <<= 1)
   7835 	{
   7836 		const PipelineStage	dstStage			= pipelineStageFlagToPipelineStage((vk::VkPipelineStageFlagBits)dstStage_);
   7837 		bool				allWritesAvailable	= true;
   7838 
   7839 		if ((dstStage_ & dstStages) == 0)
   7840 			continue;
   7841 
   7842 		// Operations in srcStages have completed before any stage in dstStages
   7843 		m_incompleteOperations[dstStage] &= ~srcStages;
   7844 
   7845 		for (vk::VkPipelineStageFlags srcStage_ = 1; srcStage_ <= m_allowedStages; srcStage_ <<= 1)
   7846 		{
   7847 			const PipelineStage srcStage = pipelineStageFlagToPipelineStage((vk::VkPipelineStageFlagBits)srcStage_);
   7848 
   7849 			if ((srcStage_ & m_allowedStages) == 0)
   7850 				continue;
   7851 
   7852 			// Make srcAccesses from srcStage available in dstStage
   7853 			if ((srcStage_ & srcStages) != 0)
   7854 				m_unavailableWriteOperations[dstStage][srcStage] &= ~srcAccesses;
   7855 
   7856 			if (m_unavailableWriteOperations[dstStage][srcStage] != 0)
   7857 				allWritesAvailable = false;
   7858 		}
   7859 
   7860 		// If all writes are available in dstStage make dstAccesses also visible
   7861 		if (allWritesAvailable)
   7862 			m_invisibleOperations[dstStage] &= ~dstAccesses;
   7863 	}
   7864 }
   7865 
   7866 bool CacheState::isClean (void) const
   7867 {
   7868 	for (vk::VkPipelineStageFlags dstStage_ = 1; dstStage_ <= m_allowedStages; dstStage_ <<= 1)
   7869 	{
   7870 		const PipelineStage dstStage = pipelineStageFlagToPipelineStage((vk::VkPipelineStageFlagBits)dstStage_);
   7871 
   7872 		if ((dstStage_ & m_allowedStages) == 0)
   7873 			continue;
   7874 
   7875 		// Some operations are not visible to some stages
   7876 		if (m_invisibleOperations[dstStage] != 0)
   7877 			return false;
   7878 
   7879 		// There are operation that have not completed yet
   7880 		if (m_incompleteOperations[dstStage] != 0)
   7881 			return false;
   7882 
   7883 		// Layout transition has not completed yet
   7884 		if (m_unavailableLayoutTransition[dstStage])
   7885 			return false;
   7886 
   7887 		for (vk::VkPipelineStageFlags srcStage_ = 1; srcStage_ <= m_allowedStages; srcStage_ <<= 1)
   7888 		{
   7889 			const PipelineStage srcStage = pipelineStageFlagToPipelineStage((vk::VkPipelineStageFlagBits)srcStage_);
   7890 
   7891 			if ((srcStage_ & m_allowedStages) == 0)
   7892 				continue;
   7893 
   7894 			// Some write operations are not available yet
   7895 			if (m_unavailableWriteOperations[dstStage][srcStage] != 0)
   7896 				return false;
   7897 		}
   7898 	}
   7899 
   7900 	return true;
   7901 }
   7902 
   7903 bool layoutSupportedByUsage (Usage usage, vk::VkImageLayout layout)
   7904 {
   7905 	switch (layout)
   7906 	{
   7907 		case vk::VK_IMAGE_LAYOUT_GENERAL:
   7908 			return true;
   7909 
   7910 		case vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
   7911 			return (usage & USAGE_COLOR_ATTACHMENT) != 0;
   7912 
   7913 		case vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
   7914 			return (usage & USAGE_DEPTH_STENCIL_ATTACHMENT) != 0;
   7915 
   7916 		case vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
   7917 			return (usage & USAGE_DEPTH_STENCIL_ATTACHMENT) != 0;
   7918 
   7919 		case vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
   7920 			// \todo [2016-03-09 mika] Should include input attachment
   7921 			return (usage & USAGE_SAMPLED_IMAGE) != 0;
   7922 
   7923 		case vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
   7924 			return (usage & USAGE_TRANSFER_SRC) != 0;
   7925 
   7926 		case vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
   7927 			return (usage & USAGE_TRANSFER_DST) != 0;
   7928 
   7929 		case vk::VK_IMAGE_LAYOUT_PREINITIALIZED:
   7930 			return true;
   7931 
   7932 		default:
   7933 			DE_FATAL("Unknown layout");
   7934 			return false;
   7935 	}
   7936 }
   7937 
   7938 size_t getNumberOfSupportedLayouts (Usage usage)
   7939 {
   7940 	const vk::VkImageLayout layouts[] =
   7941 	{
   7942 		vk::VK_IMAGE_LAYOUT_GENERAL,
   7943 		vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   7944 		vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
   7945 		vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
   7946 		vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
   7947 		vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
   7948 		vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
   7949 	};
   7950 	size_t supportedLayoutCount = 0;
   7951 
   7952 	for (size_t layoutNdx = 0; layoutNdx < DE_LENGTH_OF_ARRAY(layouts); layoutNdx++)
   7953 	{
   7954 		const vk::VkImageLayout layout = layouts[layoutNdx];
   7955 
   7956 		if (layoutSupportedByUsage(usage, layout))
   7957 			supportedLayoutCount++;
   7958 	}
   7959 
   7960 	return supportedLayoutCount;
   7961 }
   7962 
   7963 vk::VkImageLayout getRandomNextLayout (de::Random&			rng,
   7964 									   Usage				usage,
   7965 									   vk::VkImageLayout	previousLayout)
   7966 {
   7967 	const vk::VkImageLayout	layouts[] =
   7968 	{
   7969 		vk::VK_IMAGE_LAYOUT_GENERAL,
   7970 		vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   7971 		vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
   7972 		vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
   7973 		vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
   7974 		vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
   7975 		vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
   7976 	};
   7977 	const size_t			supportedLayoutCount = getNumberOfSupportedLayouts(usage);
   7978 
   7979 	DE_ASSERT(supportedLayoutCount > 0);
   7980 
   7981 	size_t nextLayoutNdx = ((size_t)rng.getUint64()) % (previousLayout == vk::VK_IMAGE_LAYOUT_UNDEFINED
   7982 														? supportedLayoutCount
   7983 														: supportedLayoutCount - 1);
   7984 
   7985 	for (size_t layoutNdx = 0; layoutNdx < DE_LENGTH_OF_ARRAY(layouts); layoutNdx++)
   7986 	{
   7987 		const vk::VkImageLayout layout = layouts[layoutNdx];
   7988 
   7989 		if (layoutSupportedByUsage(usage, layout) && layout != previousLayout)
   7990 		{
   7991 			if (nextLayoutNdx == 0)
   7992 				return layout;
   7993 			else
   7994 				nextLayoutNdx--;
   7995 		}
   7996 	}
   7997 
   7998 	DE_FATAL("Unreachable");
   7999 	return vk::VK_IMAGE_LAYOUT_UNDEFINED;
   8000 }
   8001 
   8002 struct State
   8003 {
   8004 	State (Usage usage, deUint32 seed)
   8005 		: stage					(STAGE_HOST)
   8006 		, cache					(usageToStageFlags(usage), usageToAccessFlags(usage))
   8007 		, rng					(seed)
   8008 		, mapped				(false)
   8009 		, hostInvalidated		(true)
   8010 		, hostFlushed			(true)
   8011 		, memoryDefined			(false)
   8012 		, hasBuffer				(false)
   8013 		, hasBoundBufferMemory	(false)
   8014 		, hasImage				(false)
   8015 		, hasBoundImageMemory	(false)
   8016 		, imageLayout			(vk::VK_IMAGE_LAYOUT_UNDEFINED)
   8017 		, imageDefined			(false)
   8018 		, queueIdle				(true)
   8019 		, deviceIdle			(true)
   8020 		, commandBufferIsEmpty	(true)
   8021 		, renderPassIsEmpty		(true)
   8022 	{
   8023 	}
   8024 
   8025 	Stage				stage;
   8026 	CacheState			cache;
   8027 	de::Random			rng;
   8028 
   8029 	bool				mapped;
   8030 	bool				hostInvalidated;
   8031 	bool				hostFlushed;
   8032 	bool				memoryDefined;
   8033 
   8034 	bool				hasBuffer;
   8035 	bool				hasBoundBufferMemory;
   8036 
   8037 	bool				hasImage;
   8038 	bool				hasBoundImageMemory;
   8039 	vk::VkImageLayout	imageLayout;
   8040 	bool				imageDefined;
   8041 
   8042 	bool				queueIdle;
   8043 	bool				deviceIdle;
   8044 
   8045 	bool				commandBufferIsEmpty;
   8046 	bool				renderPassIsEmpty;
   8047 };
   8048 
   8049 void getAvailableOps (const State& state, bool supportsBuffers, bool supportsImages, Usage usage, vector<Op>& ops)
   8050 {
   8051 	if (state.stage == STAGE_HOST)
   8052 	{
   8053 		if (usage & (USAGE_HOST_READ | USAGE_HOST_WRITE))
   8054 		{
   8055 			// Host memory operations
   8056 			if (state.mapped)
   8057 			{
   8058 				ops.push_back(OP_UNMAP);
   8059 
   8060 				// Avoid flush and finish if they are not needed
   8061 				if (!state.hostFlushed)
   8062 					ops.push_back(OP_MAP_FLUSH);
   8063 
   8064 				if (!state.hostInvalidated
   8065 					&& state.queueIdle
   8066 					&& ((usage & USAGE_HOST_READ) == 0
   8067 						|| state.cache.isValid(vk::VK_PIPELINE_STAGE_HOST_BIT, vk::VK_ACCESS_HOST_READ_BIT))
   8068 					&& ((usage & USAGE_HOST_WRITE) == 0
   8069 						|| state.cache.isValid(vk::VK_PIPELINE_STAGE_HOST_BIT, vk::VK_ACCESS_HOST_WRITE_BIT)))
   8070 				{
   8071 					ops.push_back(OP_MAP_INVALIDATE);
   8072 				}
   8073 
   8074 				if (usage & USAGE_HOST_READ
   8075 					&& usage & USAGE_HOST_WRITE
   8076 					&& state.memoryDefined
   8077 					&& state.hostInvalidated
   8078 					&& state.queueIdle
   8079 					&& state.cache.isValid(vk::VK_PIPELINE_STAGE_HOST_BIT, vk::VK_ACCESS_HOST_WRITE_BIT)
   8080 					&& state.cache.isValid(vk::VK_PIPELINE_STAGE_HOST_BIT, vk::VK_ACCESS_HOST_READ_BIT))
   8081 				{
   8082 					ops.push_back(OP_MAP_MODIFY);
   8083 				}
   8084 
   8085 				if (usage & USAGE_HOST_READ
   8086 					&& state.memoryDefined
   8087 					&& state.hostInvalidated
   8088 					&& state.queueIdle
   8089 					&& state.cache.isValid(vk::VK_PIPELINE_STAGE_HOST_BIT, vk::VK_ACCESS_HOST_READ_BIT))
   8090 				{
   8091 					ops.push_back(OP_MAP_READ);
   8092 				}
   8093 
   8094 				if (usage & USAGE_HOST_WRITE
   8095 					&& state.hostInvalidated
   8096 					&& state.queueIdle
   8097 					&& state.cache.isValid(vk::VK_PIPELINE_STAGE_HOST_BIT, vk::VK_ACCESS_HOST_WRITE_BIT))
   8098 				{
   8099 					ops.push_back(OP_MAP_WRITE);
   8100 				}
   8101 			}
   8102 			else
   8103 				ops.push_back(OP_MAP);
   8104 		}
   8105 
   8106 		if (state.hasBoundBufferMemory && state.queueIdle)
   8107 		{
   8108 			// \note Destroy only buffers after they have been bound
   8109 			ops.push_back(OP_BUFFER_DESTROY);
   8110 		}
   8111 		else
   8112 		{
   8113 			if (state.hasBuffer)
   8114 			{
   8115 				if (!state.hasBoundBufferMemory)
   8116 					ops.push_back(OP_BUFFER_BINDMEMORY);
   8117 			}
   8118 			else if (!state.hasImage && supportsBuffers)	// Avoid creating buffer if there is already image
   8119 				ops.push_back(OP_BUFFER_CREATE);
   8120 		}
   8121 
   8122 		if (state.hasBoundImageMemory && state.queueIdle)
   8123 		{
   8124 			// \note Destroy only image after they have been bound
   8125 			ops.push_back(OP_IMAGE_DESTROY);
   8126 		}
   8127 		else
   8128 		{
   8129 			if (state.hasImage)
   8130 			{
   8131 				if (!state.hasBoundImageMemory)
   8132 					ops.push_back(OP_IMAGE_BINDMEMORY);
   8133 			}
   8134 			else if (!state.hasBuffer && supportsImages)	// Avoid creating image if there is already buffer
   8135 				ops.push_back(OP_IMAGE_CREATE);
   8136 		}
   8137 
   8138 		// Host writes must be flushed before GPU commands and there must be
   8139 		// buffer or image for GPU commands
   8140 		if (state.hostFlushed
   8141 			&& (state.memoryDefined || supportsDeviceBufferWrites(usage) || state.imageDefined || supportsDeviceImageWrites(usage))
   8142 			&& (state.hasBoundBufferMemory || state.hasBoundImageMemory) // Avoid command buffers if there is no object to use
   8143 			&& (usageToStageFlags(usage) & (~vk::VK_PIPELINE_STAGE_HOST_BIT)) != 0) // Don't start command buffer if there are no ways to use memory from gpu
   8144 		{
   8145 			ops.push_back(OP_COMMAND_BUFFER_BEGIN);
   8146 		}
   8147 
   8148 		if (!state.deviceIdle)
   8149 			ops.push_back(OP_DEVICE_WAIT_FOR_IDLE);
   8150 
   8151 		if (!state.queueIdle)
   8152 			ops.push_back(OP_QUEUE_WAIT_FOR_IDLE);
   8153 	}
   8154 	else if (state.stage == STAGE_COMMAND_BUFFER)
   8155 	{
   8156 		if (!state.cache.isClean())
   8157 		{
   8158 			ops.push_back(OP_PIPELINE_BARRIER_GLOBAL);
   8159 
   8160 			if (state.hasImage)
   8161 				ops.push_back(OP_PIPELINE_BARRIER_IMAGE);
   8162 
   8163 			if (state.hasBuffer)
   8164 				ops.push_back(OP_PIPELINE_BARRIER_BUFFER);
   8165 		}
   8166 
   8167 		if (state.hasBoundBufferMemory)
   8168 		{
   8169 			if (usage & USAGE_TRANSFER_DST
   8170 				&& state.cache.isValid(vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_ACCESS_TRANSFER_WRITE_BIT))
   8171 			{
   8172 				ops.push_back(OP_BUFFER_FILL);
   8173 				ops.push_back(OP_BUFFER_UPDATE);
   8174 				ops.push_back(OP_BUFFER_COPY_FROM_BUFFER);
   8175 				ops.push_back(OP_BUFFER_COPY_FROM_IMAGE);
   8176 			}
   8177 
   8178 			if (usage & USAGE_TRANSFER_SRC
   8179 				&& state.memoryDefined
   8180 				&& state.cache.isValid(vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT))
   8181 			{
   8182 				ops.push_back(OP_BUFFER_COPY_TO_BUFFER);
   8183 				ops.push_back(OP_BUFFER_COPY_TO_IMAGE);
   8184 			}
   8185 		}
   8186 
   8187 		if (state.hasBoundImageMemory
   8188 			&& (state.imageLayout == vk::VK_IMAGE_LAYOUT_UNDEFINED
   8189 				|| getNumberOfSupportedLayouts(usage) > 1))
   8190 		{
   8191 			ops.push_back(OP_IMAGE_TRANSITION_LAYOUT);
   8192 
   8193 			{
   8194 				if (usage & USAGE_TRANSFER_DST
   8195 					&& (state.imageLayout == vk::VK_IMAGE_LAYOUT_GENERAL
   8196 						|| state.imageLayout == vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
   8197 					&& state.cache.isValid(vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_ACCESS_TRANSFER_WRITE_BIT))
   8198 				{
   8199 					ops.push_back(OP_IMAGE_COPY_FROM_BUFFER);
   8200 					ops.push_back(OP_IMAGE_COPY_FROM_IMAGE);
   8201 					ops.push_back(OP_IMAGE_BLIT_FROM_IMAGE);
   8202 				}
   8203 
   8204 				if (usage & USAGE_TRANSFER_SRC
   8205 					&& (state.imageLayout == vk::VK_IMAGE_LAYOUT_GENERAL
   8206 						|| state.imageLayout == vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)
   8207 					&& state.imageDefined
   8208 					&& state.cache.isValid(vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT))
   8209 				{
   8210 					ops.push_back(OP_IMAGE_COPY_TO_BUFFER);
   8211 					ops.push_back(OP_IMAGE_COPY_TO_IMAGE);
   8212 					ops.push_back(OP_IMAGE_BLIT_TO_IMAGE);
   8213 				}
   8214 			}
   8215 		}
   8216 
   8217 		// \todo [2016-03-09 mika] Add other usages?
   8218 		if ((state.memoryDefined
   8219 				&& state.hasBoundBufferMemory
   8220 				&& (((usage & USAGE_VERTEX_BUFFER)
   8221 					&& state.cache.isValid(vk::VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, vk::VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT))
   8222 				|| ((usage & USAGE_INDEX_BUFFER)
   8223 					&& state.cache.isValid(vk::VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, vk::VK_ACCESS_INDEX_READ_BIT))
   8224 				|| ((usage & USAGE_UNIFORM_BUFFER)
   8225 					&& (state.cache.isValid(vk::VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, vk::VK_ACCESS_UNIFORM_READ_BIT)
   8226 						|| state.cache.isValid(vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, vk::VK_ACCESS_UNIFORM_READ_BIT)))
   8227 				|| ((usage & USAGE_UNIFORM_TEXEL_BUFFER)
   8228 					&& (state.cache.isValid(vk::VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, vk::VK_ACCESS_UNIFORM_READ_BIT)
   8229 						|| state.cache.isValid(vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, vk::VK_ACCESS_UNIFORM_READ_BIT)))
   8230 				|| ((usage & USAGE_STORAGE_BUFFER)
   8231 					&& (state.cache.isValid(vk::VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, vk::VK_ACCESS_SHADER_READ_BIT)
   8232 						|| state.cache.isValid(vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, vk::VK_ACCESS_SHADER_READ_BIT)))
   8233 				|| ((usage & USAGE_STORAGE_TEXEL_BUFFER)
   8234 					&& state.cache.isValid(vk::VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, vk::VK_ACCESS_SHADER_READ_BIT))))
   8235 			|| (state.imageDefined
   8236 				&& state.hasBoundImageMemory
   8237 				&& (((usage & USAGE_STORAGE_IMAGE)
   8238 						&& state.imageLayout == vk::VK_IMAGE_LAYOUT_GENERAL
   8239 						&& (state.cache.isValid(vk::VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, vk::VK_ACCESS_SHADER_READ_BIT)
   8240 							|| state.cache.isValid(vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, vk::VK_ACCESS_SHADER_READ_BIT)))
   8241 					|| ((usage & USAGE_SAMPLED_IMAGE)
   8242 						&& (state.imageLayout == vk::VK_IMAGE_LAYOUT_GENERAL
   8243 							|| state.imageLayout == vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
   8244 						&& (state.cache.isValid(vk::VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, vk::VK_ACCESS_SHADER_READ_BIT)
   8245 							|| state.cache.isValid(vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, vk::VK_ACCESS_SHADER_READ_BIT))))))
   8246 		{
   8247 			ops.push_back(OP_RENDERPASS_BEGIN);
   8248 		}
   8249 
   8250 		// \note This depends on previous operations and has to be always the
   8251 		// last command buffer operation check
   8252 		if (ops.empty() || !state.commandBufferIsEmpty)
   8253 			ops.push_back(OP_COMMAND_BUFFER_END);
   8254 	}
   8255 	else if (state.stage == STAGE_RENDER_PASS)
   8256 	{
   8257 		if ((usage & USAGE_VERTEX_BUFFER) != 0
   8258 			&& state.memoryDefined
   8259 			&& state.hasBoundBufferMemory
   8260 			&& state.cache.isValid(vk::VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, vk::VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT))
   8261 		{
   8262 			ops.push_back(OP_RENDER_VERTEX_BUFFER);
   8263 		}
   8264 
   8265 		if ((usage & USAGE_INDEX_BUFFER) != 0
   8266 			&& state.memoryDefined
   8267 			&& state.hasBoundBufferMemory
   8268 			&& state.cache.isValid(vk::VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, vk::VK_ACCESS_INDEX_READ_BIT))
   8269 		{
   8270 			ops.push_back(OP_RENDER_INDEX_BUFFER);
   8271 		}
   8272 
   8273 		if ((usage & USAGE_UNIFORM_BUFFER) != 0
   8274 			&& state.memoryDefined
   8275 			&& state.hasBoundBufferMemory)
   8276 		{
   8277 			if (state.cache.isValid(vk::VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, vk::VK_ACCESS_UNIFORM_READ_BIT))
   8278 				ops.push_back(OP_RENDER_VERTEX_UNIFORM_BUFFER);
   8279 
   8280 			if (state.cache.isValid(vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, vk::VK_ACCESS_UNIFORM_READ_BIT))
   8281 				ops.push_back(OP_RENDER_FRAGMENT_UNIFORM_BUFFER);
   8282 		}
   8283 
   8284 		if ((usage & USAGE_UNIFORM_TEXEL_BUFFER) != 0
   8285 			&& state.memoryDefined
   8286 			&& state.hasBoundBufferMemory)
   8287 		{
   8288 			if (state.cache.isValid(vk::VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, vk::VK_ACCESS_UNIFORM_READ_BIT))
   8289 				ops.push_back(OP_RENDER_VERTEX_UNIFORM_TEXEL_BUFFER);
   8290 
   8291 			if (state.cache.isValid(vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, vk::VK_ACCESS_UNIFORM_READ_BIT))
   8292 				ops.push_back(OP_RENDER_FRAGMENT_UNIFORM_TEXEL_BUFFER);
   8293 		}
   8294 
   8295 		if ((usage & USAGE_STORAGE_BUFFER) != 0
   8296 			&& state.memoryDefined
   8297 			&& state.hasBoundBufferMemory)
   8298 		{
   8299 			if (state.cache.isValid(vk::VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, vk::VK_ACCESS_SHADER_READ_BIT))
   8300 				ops.push_back(OP_RENDER_VERTEX_STORAGE_BUFFER);
   8301 
   8302 			if (state.cache.isValid(vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, vk::VK_ACCESS_SHADER_READ_BIT))
   8303 				ops.push_back(OP_RENDER_FRAGMENT_STORAGE_BUFFER);
   8304 		}
   8305 
   8306 		if ((usage & USAGE_STORAGE_TEXEL_BUFFER) != 0
   8307 			&& state.memoryDefined
   8308 			&& state.hasBoundBufferMemory)
   8309 		{
   8310 			if (state.cache.isValid(vk::VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, vk::VK_ACCESS_SHADER_READ_BIT))
   8311 				ops.push_back(OP_RENDER_VERTEX_STORAGE_TEXEL_BUFFER);
   8312 
   8313 			if (state.cache.isValid(vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, vk::VK_ACCESS_SHADER_READ_BIT))
   8314 				ops.push_back(OP_RENDER_FRAGMENT_STORAGE_TEXEL_BUFFER);
   8315 		}
   8316 
   8317 		if ((usage & USAGE_STORAGE_IMAGE) != 0
   8318 			&& state.imageDefined
   8319 			&& state.hasBoundImageMemory
   8320 			&& (state.imageLayout == vk::VK_IMAGE_LAYOUT_GENERAL))
   8321 		{
   8322 			if (state.cache.isValid(vk::VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, vk::VK_ACCESS_SHADER_READ_BIT))
   8323 				ops.push_back(OP_RENDER_VERTEX_STORAGE_IMAGE);
   8324 
   8325 			if (state.cache.isValid(vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, vk::VK_ACCESS_SHADER_READ_BIT))
   8326 				ops.push_back(OP_RENDER_FRAGMENT_STORAGE_IMAGE);
   8327 		}
   8328 
   8329 		if ((usage & USAGE_SAMPLED_IMAGE) != 0
   8330 			&& state.imageDefined
   8331 			&& state.hasBoundImageMemory
   8332 			&& (state.imageLayout == vk::VK_IMAGE_LAYOUT_GENERAL
   8333 				|| state.imageLayout == vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL))
   8334 		{
   8335 			if (state.cache.isValid(vk::VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, vk::VK_ACCESS_SHADER_READ_BIT))
   8336 				ops.push_back(OP_RENDER_VERTEX_SAMPLED_IMAGE);
   8337 
   8338 			if (state.cache.isValid(vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, vk::VK_ACCESS_SHADER_READ_BIT))
   8339 				ops.push_back(OP_RENDER_FRAGMENT_SAMPLED_IMAGE);
   8340 		}
   8341 
   8342 		if (!state.renderPassIsEmpty)
   8343 			ops.push_back(OP_RENDERPASS_END);
   8344 	}
   8345 	else
   8346 		DE_FATAL("Unknown stage");
   8347 }
   8348 
   8349 void removeIllegalAccessFlags (vk::VkAccessFlags& accessflags, vk::VkPipelineStageFlags stageflags)
   8350 {
   8351 	if (!(stageflags & vk::VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT))
   8352 		accessflags &= ~vk::VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
   8353 
   8354 	if (!(stageflags & vk::VK_PIPELINE_STAGE_VERTEX_INPUT_BIT))
   8355 		accessflags &= ~vk::VK_ACCESS_INDEX_READ_BIT;
   8356 
   8357 	if (!(stageflags & vk::VK_PIPELINE_STAGE_VERTEX_INPUT_BIT))
   8358 		accessflags &= ~vk::VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
   8359 
   8360 	if (!(stageflags & (vk::VK_PIPELINE_STAGE_VERTEX_SHADER_BIT |
   8361 						vk::VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT |
   8362 						vk::VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT |
   8363 						vk::VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT |
   8364 						vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
   8365 						vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT)))
   8366 		accessflags &= ~vk::VK_ACCESS_UNIFORM_READ_BIT;
   8367 
   8368 	if (!(stageflags & vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT))
   8369 		accessflags &= ~vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
   8370 
   8371 	if (!(stageflags & (vk::VK_PIPELINE_STAGE_VERTEX_SHADER_BIT |
   8372 						vk::VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT |
   8373 						vk::VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT |
   8374 						vk::VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT |
   8375 						vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
   8376 						vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT)))
   8377 		accessflags &= ~vk::VK_ACCESS_SHADER_READ_BIT;
   8378 
   8379 	if (!(stageflags & (vk::VK_PIPELINE_STAGE_VERTEX_SHADER_BIT |
   8380 						vk::VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT |
   8381 						vk::VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT |
   8382 						vk::VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT |
   8383 						vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
   8384 						vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT)))
   8385 		accessflags &= ~vk::VK_ACCESS_SHADER_WRITE_BIT;
   8386 
   8387 	if (!(stageflags & vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT))
   8388 		accessflags &= ~vk::VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
   8389 
   8390 	if (!(stageflags & vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT))
   8391 		accessflags &= ~vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
   8392 
   8393 	if (!(stageflags & (vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
   8394 						vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT)))
   8395 		accessflags &= ~vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
   8396 
   8397 	if (!(stageflags & (vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
   8398 						vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT)))
   8399 		accessflags &= ~vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
   8400 
   8401 	if (!(stageflags & vk::VK_PIPELINE_STAGE_TRANSFER_BIT))
   8402 		accessflags &= ~vk::VK_ACCESS_TRANSFER_READ_BIT;
   8403 
   8404 	if (!(stageflags & vk::VK_PIPELINE_STAGE_TRANSFER_BIT))
   8405 		accessflags &= ~vk::VK_ACCESS_TRANSFER_WRITE_BIT;
   8406 
   8407 	if (!(stageflags & vk::VK_PIPELINE_STAGE_HOST_BIT))
   8408 		accessflags &= ~vk::VK_ACCESS_HOST_READ_BIT;
   8409 
   8410 	if (!(stageflags & vk::VK_PIPELINE_STAGE_HOST_BIT))
   8411 		accessflags &= ~vk::VK_ACCESS_HOST_WRITE_BIT;
   8412 }
   8413 
   8414 void applyOp (State& state, const Memory& memory, Op op, Usage usage)
   8415 {
   8416 	switch (op)
   8417 	{
   8418 		case OP_MAP:
   8419 			DE_ASSERT(state.stage == STAGE_HOST);
   8420 			DE_ASSERT(!state.mapped);
   8421 			state.mapped = true;
   8422 			break;
   8423 
   8424 		case OP_UNMAP:
   8425 			DE_ASSERT(state.stage == STAGE_HOST);
   8426 			DE_ASSERT(state.mapped);
   8427 			state.mapped = false;
   8428 			break;
   8429 
   8430 		case OP_MAP_FLUSH:
   8431 			DE_ASSERT(state.stage == STAGE_HOST);
   8432 			DE_ASSERT(!state.hostFlushed);
   8433 			state.hostFlushed = true;
   8434 			break;
   8435 
   8436 		case OP_MAP_INVALIDATE:
   8437 			DE_ASSERT(state.stage == STAGE_HOST);
   8438 			DE_ASSERT(!state.hostInvalidated);
   8439 			state.hostInvalidated = true;
   8440 			break;
   8441 
   8442 		case OP_MAP_READ:
   8443 			DE_ASSERT(state.stage == STAGE_HOST);
   8444 			DE_ASSERT(state.hostInvalidated);
   8445 			state.rng.getUint32();
   8446 			break;
   8447 
   8448 		case OP_MAP_WRITE:
   8449 			DE_ASSERT(state.stage == STAGE_HOST);
   8450 			if ((memory.getMemoryType().propertyFlags & vk::VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) == 0)
   8451 				state.hostFlushed = false;
   8452 
   8453 			state.memoryDefined = true;
   8454 			state.imageDefined = false;
   8455 			state.imageLayout = vk::VK_IMAGE_LAYOUT_UNDEFINED;
   8456 			state.rng.getUint32();
   8457 			break;
   8458 
   8459 		case OP_MAP_MODIFY:
   8460 			DE_ASSERT(state.stage == STAGE_HOST);
   8461 			DE_ASSERT(state.hostInvalidated);
   8462 
   8463 			if ((memory.getMemoryType().propertyFlags & vk::VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) == 0)
   8464 				state.hostFlushed = false;
   8465 
   8466 			state.rng.getUint32();
   8467 			break;
   8468 
   8469 		case OP_BUFFER_CREATE:
   8470 			DE_ASSERT(state.stage == STAGE_HOST);
   8471 			DE_ASSERT(!state.hasBuffer);
   8472 
   8473 			state.hasBuffer = true;
   8474 			break;
   8475 
   8476 		case OP_BUFFER_DESTROY:
   8477 			DE_ASSERT(state.stage == STAGE_HOST);
   8478 			DE_ASSERT(state.hasBuffer);
   8479 			DE_ASSERT(state.hasBoundBufferMemory);
   8480 
   8481 			state.hasBuffer = false;
   8482 			state.hasBoundBufferMemory = false;
   8483 			break;
   8484 
   8485 		case OP_BUFFER_BINDMEMORY:
   8486 			DE_ASSERT(state.stage == STAGE_HOST);
   8487 			DE_ASSERT(state.hasBuffer);
   8488 			DE_ASSERT(!state.hasBoundBufferMemory);
   8489 
   8490 			state.hasBoundBufferMemory = true;
   8491 			break;
   8492 
   8493 		case OP_IMAGE_CREATE:
   8494 			DE_ASSERT(state.stage == STAGE_HOST);
   8495 			DE_ASSERT(!state.hasImage);
   8496 			DE_ASSERT(!state.hasBuffer);
   8497 
   8498 			state.hasImage = true;
   8499 			break;
   8500 
   8501 		case OP_IMAGE_DESTROY:
   8502 			DE_ASSERT(state.stage == STAGE_HOST);
   8503 			DE_ASSERT(state.hasImage);
   8504 			DE_ASSERT(state.hasBoundImageMemory);
   8505 
   8506 			state.hasImage = false;
   8507 			state.hasBoundImageMemory = false;
   8508 			state.imageLayout = vk::VK_IMAGE_LAYOUT_UNDEFINED;
   8509 			state.imageDefined = false;
   8510 			break;
   8511 
   8512 		case OP_IMAGE_BINDMEMORY:
   8513 			DE_ASSERT(state.stage == STAGE_HOST);
   8514 			DE_ASSERT(state.hasImage);
   8515 			DE_ASSERT(!state.hasBoundImageMemory);
   8516 
   8517 			state.hasBoundImageMemory = true;
   8518 			break;
   8519 
   8520 		case OP_IMAGE_TRANSITION_LAYOUT:
   8521 		{
   8522 			DE_ASSERT(state.stage == STAGE_COMMAND_BUFFER);
   8523 			DE_ASSERT(state.hasImage);
   8524 			DE_ASSERT(state.hasBoundImageMemory);
   8525 
   8526 			// \todo [2016-03-09 mika] Support linear tiling and predefined data
   8527 			const vk::VkImageLayout		srcLayout	= state.rng.getFloat() < 0.9f ? state.imageLayout : vk::VK_IMAGE_LAYOUT_UNDEFINED;
   8528 			const vk::VkImageLayout		dstLayout	= getRandomNextLayout(state.rng, usage, srcLayout);
   8529 
   8530 			vk::VkPipelineStageFlags	dirtySrcStages;
   8531 			vk::VkAccessFlags			dirtySrcAccesses;
   8532 			vk::VkPipelineStageFlags	dirtyDstStages;
   8533 			vk::VkAccessFlags			dirtyDstAccesses;
   8534 
   8535 			vk::VkPipelineStageFlags	srcStages;
   8536 			vk::VkAccessFlags			srcAccesses;
   8537 			vk::VkPipelineStageFlags	dstStages;
   8538 			vk::VkAccessFlags			dstAccesses;
   8539 
   8540 			state.cache.getFullBarrier(dirtySrcStages, dirtySrcAccesses, dirtyDstStages, dirtyDstAccesses);
   8541 
   8542 			// Try masking some random bits
   8543 			srcStages	= dirtySrcStages;
   8544 			srcAccesses	= dirtySrcAccesses;
   8545 
   8546 			dstStages	= state.cache.getAllowedStages() & state.rng.getUint32();
   8547 			dstAccesses	= state.cache.getAllowedAcceses() & state.rng.getUint32();
   8548 
   8549 			// If there are no bits in dst stage mask use all stages
   8550 			dstStages	= dstStages ? dstStages : state.cache.getAllowedStages();
   8551 
   8552 			if (!srcStages)
   8553 				srcStages = dstStages;
   8554 
   8555 			removeIllegalAccessFlags(dstAccesses, dstStages);
   8556 			removeIllegalAccessFlags(srcAccesses, srcStages);
   8557 
   8558 			if (srcLayout == vk::VK_IMAGE_LAYOUT_UNDEFINED)
   8559 				state.imageDefined = false;
   8560 
   8561 			state.commandBufferIsEmpty = false;
   8562 			state.imageLayout = dstLayout;
   8563 			state.memoryDefined = false;
   8564 			state.cache.imageLayoutBarrier(srcStages, srcAccesses, dstStages, dstAccesses);
   8565 			break;
   8566 		}
   8567 
   8568 		case OP_QUEUE_WAIT_FOR_IDLE:
   8569 			DE_ASSERT(state.stage == STAGE_HOST);
   8570 			DE_ASSERT(!state.queueIdle);
   8571 
   8572 			state.queueIdle = true;
   8573 
   8574 			state.cache.waitForIdle();
   8575 			break;
   8576 
   8577 		case OP_DEVICE_WAIT_FOR_IDLE:
   8578 			DE_ASSERT(state.stage == STAGE_HOST);
   8579 			DE_ASSERT(!state.deviceIdle);
   8580 
   8581 			state.queueIdle = true;
   8582 			state.deviceIdle = true;
   8583 
   8584 			state.cache.waitForIdle();
   8585 			break;
   8586 
   8587 		case OP_COMMAND_BUFFER_BEGIN:
   8588 			DE_ASSERT(state.stage == STAGE_HOST);
   8589 			state.stage = STAGE_COMMAND_BUFFER;
   8590 			state.commandBufferIsEmpty = true;
   8591 			// Makes host writes visible to command buffer
   8592 			state.cache.submitCommandBuffer();
   8593 			break;
   8594 
   8595 		case OP_COMMAND_BUFFER_END:
   8596 			DE_ASSERT(state.stage == STAGE_COMMAND_BUFFER);
   8597 			state.stage = STAGE_HOST;
   8598 			state.queueIdle = false;
   8599 			state.deviceIdle = false;
   8600 			break;
   8601 
   8602 		case OP_BUFFER_COPY_FROM_BUFFER:
   8603 		case OP_BUFFER_COPY_FROM_IMAGE:
   8604 		case OP_BUFFER_UPDATE:
   8605 		case OP_BUFFER_FILL:
   8606 			state.rng.getUint32();
   8607 			DE_ASSERT(state.stage == STAGE_COMMAND_BUFFER);
   8608 
   8609 			if ((memory.getMemoryType().propertyFlags & vk::VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) == 0)
   8610 				state.hostInvalidated = false;
   8611 
   8612 			state.commandBufferIsEmpty = false;
   8613 			state.memoryDefined = true;
   8614 			state.imageDefined = false;
   8615 			state.imageLayout = vk::VK_IMAGE_LAYOUT_UNDEFINED;
   8616 			state.cache.perform(vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_ACCESS_TRANSFER_WRITE_BIT);
   8617 			break;
   8618 
   8619 		case OP_BUFFER_COPY_TO_BUFFER:
   8620 		case OP_BUFFER_COPY_TO_IMAGE:
   8621 			DE_ASSERT(state.stage == STAGE_COMMAND_BUFFER);
   8622 
   8623 			state.commandBufferIsEmpty = false;
   8624 			state.cache.perform(vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT);
   8625 			break;
   8626 
   8627 		case OP_IMAGE_BLIT_FROM_IMAGE:
   8628 			state.rng.getBool();
   8629 			// Fall through
   8630 		case OP_IMAGE_COPY_FROM_BUFFER:
   8631 		case OP_IMAGE_COPY_FROM_IMAGE:
   8632 			state.rng.getUint32();
   8633 			DE_ASSERT(state.stage == STAGE_COMMAND_BUFFER);
   8634 
   8635 			if ((memory.getMemoryType().propertyFlags & vk::VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) == 0)
   8636 				state.hostInvalidated = false;
   8637 
   8638 			state.commandBufferIsEmpty = false;
   8639 			state.memoryDefined = false;
   8640 			state.imageDefined = true;
   8641 			state.cache.perform(vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_ACCESS_TRANSFER_WRITE_BIT);
   8642 			break;
   8643 
   8644 		case OP_IMAGE_BLIT_TO_IMAGE:
   8645 			state.rng.getBool();
   8646 			// Fall through
   8647 		case OP_IMAGE_COPY_TO_BUFFER:
   8648 		case OP_IMAGE_COPY_TO_IMAGE:
   8649 			DE_ASSERT(state.stage == STAGE_COMMAND_BUFFER);
   8650 
   8651 			state.commandBufferIsEmpty = false;
   8652 			state.cache.perform(vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT);
   8653 			break;
   8654 
   8655 		case OP_PIPELINE_BARRIER_GLOBAL:
   8656 		case OP_PIPELINE_BARRIER_BUFFER:
   8657 		case OP_PIPELINE_BARRIER_IMAGE:
   8658 		{
   8659 			DE_ASSERT(state.stage == STAGE_COMMAND_BUFFER);
   8660 
   8661 			vk::VkPipelineStageFlags	dirtySrcStages;
   8662 			vk::VkAccessFlags			dirtySrcAccesses;
   8663 			vk::VkPipelineStageFlags	dirtyDstStages;
   8664 			vk::VkAccessFlags			dirtyDstAccesses;
   8665 
   8666 			vk::VkPipelineStageFlags	srcStages;
   8667 			vk::VkAccessFlags			srcAccesses;
   8668 			vk::VkPipelineStageFlags	dstStages;
   8669 			vk::VkAccessFlags			dstAccesses;
   8670 
   8671 			state.cache.getFullBarrier(dirtySrcStages, dirtySrcAccesses, dirtyDstStages, dirtyDstAccesses);
   8672 
   8673 			// Try masking some random bits
   8674 			srcStages	= dirtySrcStages & state.rng.getUint32();
   8675 			srcAccesses	= dirtySrcAccesses & state.rng.getUint32();
   8676 
   8677 			dstStages	= dirtyDstStages & state.rng.getUint32();
   8678 			dstAccesses	= dirtyDstAccesses & state.rng.getUint32();
   8679 
   8680 			// If there are no bits in stage mask use the original dirty stages
   8681 			srcStages	= srcStages ? srcStages : dirtySrcStages;
   8682 			dstStages	= dstStages ? dstStages : dirtyDstStages;
   8683 
   8684 			if (!srcStages)
   8685 				srcStages = dstStages;
   8686 
   8687 			removeIllegalAccessFlags(dstAccesses, dstStages);
   8688 			removeIllegalAccessFlags(srcAccesses, srcStages);
   8689 
   8690 			state.commandBufferIsEmpty = false;
   8691 			state.cache.barrier(srcStages, srcAccesses, dstStages, dstAccesses);
   8692 			break;
   8693 		}
   8694 
   8695 		case OP_RENDERPASS_BEGIN:
   8696 		{
   8697 			DE_ASSERT(state.stage == STAGE_COMMAND_BUFFER);
   8698 
   8699 			state.renderPassIsEmpty	= true;
   8700 			state.stage				= STAGE_RENDER_PASS;
   8701 			break;
   8702 		}
   8703 
   8704 		case OP_RENDERPASS_END:
   8705 		{
   8706 			DE_ASSERT(state.stage == STAGE_RENDER_PASS);
   8707 
   8708 			state.renderPassIsEmpty	= true;
   8709 			state.stage				= STAGE_COMMAND_BUFFER;
   8710 			break;
   8711 		}
   8712 
   8713 		case OP_RENDER_VERTEX_BUFFER:
   8714 		{
   8715 			DE_ASSERT(state.stage == STAGE_RENDER_PASS);
   8716 
   8717 			state.renderPassIsEmpty = false;
   8718 			state.cache.perform(vk::VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, vk::VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT);
   8719 			break;
   8720 		}
   8721 
   8722 		case OP_RENDER_INDEX_BUFFER:
   8723 		{
   8724 			DE_ASSERT(state.stage == STAGE_RENDER_PASS);
   8725 
   8726 			state.renderPassIsEmpty = false;
   8727 			state.cache.perform(vk::VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, vk::VK_ACCESS_INDEX_READ_BIT);
   8728 			break;
   8729 		}
   8730 
   8731 		case OP_RENDER_VERTEX_UNIFORM_BUFFER:
   8732 		case OP_RENDER_VERTEX_UNIFORM_TEXEL_BUFFER:
   8733 		{
   8734 			DE_ASSERT(state.stage == STAGE_RENDER_PASS);
   8735 
   8736 			state.renderPassIsEmpty = false;
   8737 			state.cache.perform(vk::VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, vk::VK_ACCESS_UNIFORM_READ_BIT);
   8738 			break;
   8739 		}
   8740 
   8741 		case OP_RENDER_FRAGMENT_UNIFORM_BUFFER:
   8742 		case OP_RENDER_FRAGMENT_UNIFORM_TEXEL_BUFFER:
   8743 		{
   8744 			DE_ASSERT(state.stage == STAGE_RENDER_PASS);
   8745 
   8746 			state.renderPassIsEmpty = false;
   8747 			state.cache.perform(vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, vk::VK_ACCESS_UNIFORM_READ_BIT);
   8748 			break;
   8749 		}
   8750 
   8751 		case OP_RENDER_VERTEX_STORAGE_BUFFER:
   8752 		case OP_RENDER_VERTEX_STORAGE_TEXEL_BUFFER:
   8753 		{
   8754 			DE_ASSERT(state.stage == STAGE_RENDER_PASS);
   8755 
   8756 			state.renderPassIsEmpty = false;
   8757 			state.cache.perform(vk::VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, vk::VK_ACCESS_SHADER_READ_BIT);
   8758 			break;
   8759 		}
   8760 
   8761 		case OP_RENDER_FRAGMENT_STORAGE_BUFFER:
   8762 		case OP_RENDER_FRAGMENT_STORAGE_TEXEL_BUFFER:
   8763 		{
   8764 			DE_ASSERT(state.stage == STAGE_RENDER_PASS);
   8765 
   8766 			state.renderPassIsEmpty = false;
   8767 			state.cache.perform(vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, vk::VK_ACCESS_SHADER_READ_BIT);
   8768 			break;
   8769 		}
   8770 
   8771 		case OP_RENDER_FRAGMENT_STORAGE_IMAGE:
   8772 		case OP_RENDER_FRAGMENT_SAMPLED_IMAGE:
   8773 		{
   8774 			DE_ASSERT(state.stage == STAGE_RENDER_PASS);
   8775 
   8776 			state.renderPassIsEmpty = false;
   8777 			state.cache.perform(vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, vk::VK_ACCESS_SHADER_READ_BIT);
   8778 			break;
   8779 		}
   8780 
   8781 		case OP_RENDER_VERTEX_STORAGE_IMAGE:
   8782 		case OP_RENDER_VERTEX_SAMPLED_IMAGE:
   8783 		{
   8784 			DE_ASSERT(state.stage == STAGE_RENDER_PASS);
   8785 
   8786 			state.renderPassIsEmpty = false;
   8787 			state.cache.perform(vk::VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, vk::VK_ACCESS_SHADER_READ_BIT);
   8788 			break;
   8789 		}
   8790 
   8791 		default:
   8792 			DE_FATAL("Unknown op");
   8793 	}
   8794 }
   8795 
   8796 de::MovePtr<Command> createHostCommand (Op					op,
   8797 										de::Random&			rng,
   8798 										Usage				usage,
   8799 										vk::VkSharingMode	sharing)
   8800 {
   8801 	switch (op)
   8802 	{
   8803 		case OP_MAP:					return de::MovePtr<Command>(new Map());
   8804 		case OP_UNMAP:					return de::MovePtr<Command>(new UnMap());
   8805 
   8806 		case OP_MAP_FLUSH:				return de::MovePtr<Command>(new Flush());
   8807 		case OP_MAP_INVALIDATE:			return de::MovePtr<Command>(new Invalidate());
   8808 
   8809 		case OP_MAP_READ:				return de::MovePtr<Command>(new HostMemoryAccess(true, false, rng.getUint32()));
   8810 		case OP_MAP_WRITE:				return de::MovePtr<Command>(new HostMemoryAccess(false, true, rng.getUint32()));
   8811 		case OP_MAP_MODIFY:				return de::MovePtr<Command>(new HostMemoryAccess(true, true, rng.getUint32()));
   8812 
   8813 		case OP_BUFFER_CREATE:			return de::MovePtr<Command>(new CreateBuffer(usageToBufferUsageFlags(usage), sharing));
   8814 		case OP_BUFFER_DESTROY:			return de::MovePtr<Command>(new DestroyBuffer());
   8815 		case OP_BUFFER_BINDMEMORY:		return de::MovePtr<Command>(new BindBufferMemory());
   8816 
   8817 		case OP_IMAGE_CREATE:			return de::MovePtr<Command>(new CreateImage(usageToImageUsageFlags(usage), sharing));
   8818 		case OP_IMAGE_DESTROY:			return de::MovePtr<Command>(new DestroyImage());
   8819 		case OP_IMAGE_BINDMEMORY:		return de::MovePtr<Command>(new BindImageMemory());
   8820 
   8821 		case OP_QUEUE_WAIT_FOR_IDLE:	return de::MovePtr<Command>(new QueueWaitIdle());
   8822 		case OP_DEVICE_WAIT_FOR_IDLE:	return de::MovePtr<Command>(new DeviceWaitIdle());
   8823 
   8824 		default:
   8825 			DE_FATAL("Unknown op");
   8826 			return de::MovePtr<Command>(DE_NULL);
   8827 	}
   8828 }
   8829 
   8830 de::MovePtr<CmdCommand> createCmdCommand (de::Random&	rng,
   8831 										  const State&	state,
   8832 										  Op			op,
   8833 										  Usage			usage)
   8834 {
   8835 	switch (op)
   8836 	{
   8837 		case OP_BUFFER_FILL:					return de::MovePtr<CmdCommand>(new FillBuffer(rng.getUint32()));
   8838 		case OP_BUFFER_UPDATE:					return de::MovePtr<CmdCommand>(new UpdateBuffer(rng.getUint32()));
   8839 		case OP_BUFFER_COPY_TO_BUFFER:			return de::MovePtr<CmdCommand>(new BufferCopyToBuffer());
   8840 		case OP_BUFFER_COPY_FROM_BUFFER:		return de::MovePtr<CmdCommand>(new BufferCopyFromBuffer(rng.getUint32()));
   8841 
   8842 		case OP_BUFFER_COPY_TO_IMAGE:			return de::MovePtr<CmdCommand>(new BufferCopyToImage());
   8843 		case OP_BUFFER_COPY_FROM_IMAGE:			return de::MovePtr<CmdCommand>(new BufferCopyFromImage(rng.getUint32()));
   8844 
   8845 		case OP_IMAGE_TRANSITION_LAYOUT:
   8846 		{
   8847 			DE_ASSERT(state.stage == STAGE_COMMAND_BUFFER);
   8848 			DE_ASSERT(state.hasImage);
   8849 			DE_ASSERT(state.hasBoundImageMemory);
   8850 
   8851 			const vk::VkImageLayout		srcLayout	= rng.getFloat() < 0.9f ? state.imageLayout : vk::VK_IMAGE_LAYOUT_UNDEFINED;
   8852 			const vk::VkImageLayout		dstLayout	= getRandomNextLayout(rng, usage, srcLayout);
   8853 
   8854 			vk::VkPipelineStageFlags	dirtySrcStages;
   8855 			vk::VkAccessFlags			dirtySrcAccesses;
   8856 			vk::VkPipelineStageFlags	dirtyDstStages;
   8857 			vk::VkAccessFlags			dirtyDstAccesses;
   8858 
   8859 			vk::VkPipelineStageFlags	srcStages;
   8860 			vk::VkAccessFlags			srcAccesses;
   8861 			vk::VkPipelineStageFlags	dstStages;
   8862 			vk::VkAccessFlags			dstAccesses;
   8863 
   8864 			state.cache.getFullBarrier(dirtySrcStages, dirtySrcAccesses, dirtyDstStages, dirtyDstAccesses);
   8865 
   8866 			// Try masking some random bits
   8867 			srcStages	= dirtySrcStages;
   8868 			srcAccesses	= dirtySrcAccesses;
   8869 
   8870 			dstStages	= state.cache.getAllowedStages() & rng.getUint32();
   8871 			dstAccesses	= state.cache.getAllowedAcceses() & rng.getUint32();
   8872 
   8873 			// If there are no bits in dst stage mask use all stages
   8874 			dstStages	= dstStages ? dstStages : state.cache.getAllowedStages();
   8875 
   8876 			if (!srcStages)
   8877 				srcStages = dstStages;
   8878 
   8879 			removeIllegalAccessFlags(dstAccesses, dstStages);
   8880 			removeIllegalAccessFlags(srcAccesses, srcStages);
   8881 
   8882 			return de::MovePtr<CmdCommand>(new ImageTransition(srcStages, srcAccesses, dstStages, dstAccesses, srcLayout, dstLayout));
   8883 		}
   8884 
   8885 		case OP_IMAGE_COPY_TO_BUFFER:			return de::MovePtr<CmdCommand>(new ImageCopyToBuffer(state.imageLayout));
   8886 		case OP_IMAGE_COPY_FROM_BUFFER:			return de::MovePtr<CmdCommand>(new ImageCopyFromBuffer(rng.getUint32(), state.imageLayout));
   8887 		case OP_IMAGE_COPY_TO_IMAGE:			return de::MovePtr<CmdCommand>(new ImageCopyToImage(state.imageLayout));
   8888 		case OP_IMAGE_COPY_FROM_IMAGE:			return de::MovePtr<CmdCommand>(new ImageCopyFromImage(rng.getUint32(), state.imageLayout));
   8889 		case OP_IMAGE_BLIT_TO_IMAGE:
   8890 		{
   8891 			const BlitScale scale = rng.getBool() ? BLIT_SCALE_20 : BLIT_SCALE_10;
   8892 			return de::MovePtr<CmdCommand>(new ImageBlitToImage(scale, state.imageLayout));
   8893 		}
   8894 
   8895 		case OP_IMAGE_BLIT_FROM_IMAGE:
   8896 		{
   8897 			const BlitScale scale = rng.getBool() ? BLIT_SCALE_20 : BLIT_SCALE_10;
   8898 			return de::MovePtr<CmdCommand>(new ImageBlitFromImage(rng.getUint32(), scale, state.imageLayout));
   8899 		}
   8900 
   8901 		case OP_PIPELINE_BARRIER_GLOBAL:
   8902 		case OP_PIPELINE_BARRIER_BUFFER:
   8903 		case OP_PIPELINE_BARRIER_IMAGE:
   8904 		{
   8905 			vk::VkPipelineStageFlags	dirtySrcStages;
   8906 			vk::VkAccessFlags			dirtySrcAccesses;
   8907 			vk::VkPipelineStageFlags	dirtyDstStages;
   8908 			vk::VkAccessFlags			dirtyDstAccesses;
   8909 
   8910 			vk::VkPipelineStageFlags	srcStages;
   8911 			vk::VkAccessFlags			srcAccesses;
   8912 			vk::VkPipelineStageFlags	dstStages;
   8913 			vk::VkAccessFlags			dstAccesses;
   8914 
   8915 			state.cache.getFullBarrier(dirtySrcStages, dirtySrcAccesses, dirtyDstStages, dirtyDstAccesses);
   8916 
   8917 			// Try masking some random bits
   8918 			srcStages	= dirtySrcStages & rng.getUint32();
   8919 			srcAccesses	= dirtySrcAccesses & rng.getUint32();
   8920 
   8921 			dstStages	= dirtyDstStages & rng.getUint32();
   8922 			dstAccesses	= dirtyDstAccesses & rng.getUint32();
   8923 
   8924 			// If there are no bits in stage mask use the original dirty stages
   8925 			srcStages	= srcStages ? srcStages : dirtySrcStages;
   8926 			dstStages	= dstStages ? dstStages : dirtyDstStages;
   8927 
   8928 			if (!srcStages)
   8929 				srcStages = dstStages;
   8930 
   8931 			removeIllegalAccessFlags(dstAccesses, dstStages);
   8932 			removeIllegalAccessFlags(srcAccesses, srcStages);
   8933 
   8934 			PipelineBarrier::Type type;
   8935 
   8936 			if (op == OP_PIPELINE_BARRIER_IMAGE)
   8937 				type = PipelineBarrier::TYPE_IMAGE;
   8938 			else if (op == OP_PIPELINE_BARRIER_BUFFER)
   8939 				type = PipelineBarrier::TYPE_BUFFER;
   8940 			else if (op == OP_PIPELINE_BARRIER_GLOBAL)
   8941 				type = PipelineBarrier::TYPE_GLOBAL;
   8942 			else
   8943 			{
   8944 				type = PipelineBarrier::TYPE_LAST;
   8945 				DE_FATAL("Unknown op");
   8946 			}
   8947 
   8948 			if (type == PipelineBarrier::TYPE_IMAGE)
   8949 				return de::MovePtr<CmdCommand>(new PipelineBarrier(srcStages, srcAccesses, dstStages, dstAccesses, type, tcu::just(state.imageLayout)));
   8950 			else
   8951 				return de::MovePtr<CmdCommand>(new PipelineBarrier(srcStages, srcAccesses, dstStages, dstAccesses, type, tcu::nothing<vk::VkImageLayout>()));
   8952 		}
   8953 
   8954 		default:
   8955 			DE_FATAL("Unknown op");
   8956 			return de::MovePtr<CmdCommand>(DE_NULL);
   8957 	}
   8958 }
   8959 
   8960 de::MovePtr<RenderPassCommand> createRenderPassCommand (de::Random&,
   8961 														const State&,
   8962 														Op				op)
   8963 {
   8964 	switch (op)
   8965 	{
   8966 		case OP_RENDER_VERTEX_BUFFER:					return de::MovePtr<RenderPassCommand>(new RenderVertexBuffer());
   8967 		case OP_RENDER_INDEX_BUFFER:					return de::MovePtr<RenderPassCommand>(new RenderIndexBuffer());
   8968 
   8969 		case OP_RENDER_VERTEX_UNIFORM_BUFFER:			return de::MovePtr<RenderPassCommand>(new RenderVertexUniformBuffer());
   8970 		case OP_RENDER_FRAGMENT_UNIFORM_BUFFER:			return de::MovePtr<RenderPassCommand>(new RenderFragmentUniformBuffer());
   8971 
   8972 		case OP_RENDER_VERTEX_UNIFORM_TEXEL_BUFFER:		return de::MovePtr<RenderPassCommand>(new RenderVertexUniformTexelBuffer());
   8973 		case OP_RENDER_FRAGMENT_UNIFORM_TEXEL_BUFFER:	return de::MovePtr<RenderPassCommand>(new RenderFragmentUniformTexelBuffer());
   8974 
   8975 		case OP_RENDER_VERTEX_STORAGE_BUFFER:			return de::MovePtr<RenderPassCommand>(new RenderVertexStorageBuffer());
   8976 		case OP_RENDER_FRAGMENT_STORAGE_BUFFER:			return de::MovePtr<RenderPassCommand>(new RenderFragmentStorageBuffer());
   8977 
   8978 		case OP_RENDER_VERTEX_STORAGE_TEXEL_BUFFER:		return de::MovePtr<RenderPassCommand>(new RenderVertexStorageTexelBuffer());
   8979 		case OP_RENDER_FRAGMENT_STORAGE_TEXEL_BUFFER:	return de::MovePtr<RenderPassCommand>(new RenderFragmentStorageTexelBuffer());
   8980 
   8981 		case OP_RENDER_VERTEX_STORAGE_IMAGE:			return de::MovePtr<RenderPassCommand>(new RenderVertexStorageImage());
   8982 		case OP_RENDER_FRAGMENT_STORAGE_IMAGE:			return de::MovePtr<RenderPassCommand>(new RenderFragmentStorageImage());
   8983 
   8984 		case OP_RENDER_VERTEX_SAMPLED_IMAGE:			return de::MovePtr<RenderPassCommand>(new RenderVertexSampledImage());
   8985 		case OP_RENDER_FRAGMENT_SAMPLED_IMAGE:			return de::MovePtr<RenderPassCommand>(new RenderFragmentSampledImage());
   8986 
   8987 		default:
   8988 			DE_FATAL("Unknown op");
   8989 			return de::MovePtr<RenderPassCommand>(DE_NULL);
   8990 	}
   8991 }
   8992 
   8993 de::MovePtr<CmdCommand> createRenderPassCommands (const Memory&	memory,
   8994 												  de::Random&	nextOpRng,
   8995 												  State&		state,
   8996 												  Usage			usage,
   8997 												  size_t&		opNdx,
   8998 												  size_t		opCount)
   8999 {
   9000 	vector<RenderPassCommand*>	commands;
   9001 
   9002 	try
   9003 	{
   9004 		for (; opNdx < opCount; opNdx++)
   9005 		{
   9006 			vector<Op>	ops;
   9007 
   9008 			getAvailableOps(state, memory.getSupportBuffers(), memory.getSupportImages(), usage, ops);
   9009 
   9010 			DE_ASSERT(!ops.empty());
   9011 
   9012 			{
   9013 				const Op op = nextOpRng.choose<Op>(ops.begin(), ops.end());
   9014 
   9015 				if (op == OP_RENDERPASS_END)
   9016 				{
   9017 					break;
   9018 				}
   9019 				else
   9020 				{
   9021 					de::Random	rng	(state.rng);
   9022 
   9023 					commands.push_back(createRenderPassCommand(rng, state, op).release());
   9024 					applyOp(state, memory, op, usage);
   9025 
   9026 					DE_ASSERT(state.rng == rng);
   9027 				}
   9028 			}
   9029 		}
   9030 
   9031 		applyOp(state, memory, OP_RENDERPASS_END, usage);
   9032 		return de::MovePtr<CmdCommand>(new SubmitRenderPass(commands));
   9033 	}
   9034 	catch (...)
   9035 	{
   9036 		for (size_t commandNdx = 0; commandNdx < commands.size(); commandNdx++)
   9037 			delete commands[commandNdx];
   9038 
   9039 		throw;
   9040 	}
   9041 }
   9042 
   9043 de::MovePtr<Command> createCmdCommands (const Memory&	memory,
   9044 										de::Random&		nextOpRng,
   9045 										State&			state,
   9046 										Usage			usage,
   9047 										size_t&			opNdx,
   9048 										size_t			opCount)
   9049 {
   9050 	vector<CmdCommand*>	commands;
   9051 
   9052 	try
   9053 	{
   9054 		for (; opNdx < opCount; opNdx++)
   9055 		{
   9056 			vector<Op>	ops;
   9057 
   9058 			getAvailableOps(state, memory.getSupportBuffers(), memory.getSupportImages(), usage, ops);
   9059 
   9060 			DE_ASSERT(!ops.empty());
   9061 
   9062 			{
   9063 				const Op op = nextOpRng.choose<Op>(ops.begin(), ops.end());
   9064 
   9065 				if (op == OP_COMMAND_BUFFER_END)
   9066 				{
   9067 					break;
   9068 				}
   9069 				else
   9070 				{
   9071 					// \note Command needs to known the state before the operation
   9072 					if (op == OP_RENDERPASS_BEGIN)
   9073 					{
   9074 						applyOp(state, memory, op, usage);
   9075 						commands.push_back(createRenderPassCommands(memory, nextOpRng, state, usage, opNdx, opCount).release());
   9076 					}
   9077 					else
   9078 					{
   9079 						de::Random	rng	(state.rng);
   9080 
   9081 						commands.push_back(createCmdCommand(rng, state, op, usage).release());
   9082 						applyOp(state, memory, op, usage);
   9083 
   9084 						DE_ASSERT(state.rng == rng);
   9085 					}
   9086 
   9087 				}
   9088 			}
   9089 		}
   9090 
   9091 		applyOp(state, memory, OP_COMMAND_BUFFER_END, usage);
   9092 		return de::MovePtr<Command>(new SubmitCommandBuffer(commands));
   9093 	}
   9094 	catch (...)
   9095 	{
   9096 		for (size_t commandNdx = 0; commandNdx < commands.size(); commandNdx++)
   9097 			delete commands[commandNdx];
   9098 
   9099 		throw;
   9100 	}
   9101 }
   9102 
   9103 void createCommands (vector<Command*>&	commands,
   9104 					 deUint32			seed,
   9105 					 const Memory&		memory,
   9106 					 Usage				usage,
   9107 					 vk::VkSharingMode	sharingMode,
   9108 					 size_t				opCount)
   9109 {
   9110 	State			state		(usage, seed);
   9111 	// Used to select next operation only
   9112 	de::Random		nextOpRng	(seed ^ 12930809);
   9113 
   9114 	commands.reserve(opCount);
   9115 
   9116 	for (size_t opNdx = 0; opNdx < opCount; opNdx++)
   9117 	{
   9118 		vector<Op>	ops;
   9119 
   9120 		getAvailableOps(state, memory.getSupportBuffers(), memory.getSupportImages(), usage, ops);
   9121 
   9122 		DE_ASSERT(!ops.empty());
   9123 
   9124 		{
   9125 			const Op	op	= nextOpRng.choose<Op>(ops.begin(), ops.end());
   9126 
   9127 			if (op == OP_COMMAND_BUFFER_BEGIN)
   9128 			{
   9129 				applyOp(state, memory, op, usage);
   9130 				commands.push_back(createCmdCommands(memory, nextOpRng, state, usage, opNdx, opCount).release());
   9131 			}
   9132 			else
   9133 			{
   9134 				de::Random	rng	(state.rng);
   9135 
   9136 				commands.push_back(createHostCommand(op, rng, usage, sharingMode).release());
   9137 				applyOp(state, memory, op, usage);
   9138 
   9139 				// Make sure that random generator is in sync
   9140 				DE_ASSERT(state.rng == rng);
   9141 			}
   9142 		}
   9143 	}
   9144 
   9145 	// Clean up resources
   9146 	if (state.hasBuffer && state.hasImage)
   9147 	{
   9148 		if (!state.queueIdle)
   9149 			commands.push_back(new QueueWaitIdle());
   9150 
   9151 		if (state.hasBuffer)
   9152 			commands.push_back(new DestroyBuffer());
   9153 
   9154 		if (state.hasImage)
   9155 			commands.push_back(new DestroyImage());
   9156 	}
   9157 }
   9158 
   9159 class MemoryTestInstance : public TestInstance
   9160 {
   9161 public:
   9162 
   9163 	typedef bool(MemoryTestInstance::*StageFunc)(void);
   9164 
   9165 												MemoryTestInstance				(::vkt::Context& context, const TestConfig& config);
   9166 												~MemoryTestInstance				(void);
   9167 
   9168 	tcu::TestStatus								iterate							(void);
   9169 
   9170 private:
   9171 	const TestConfig							m_config;
   9172 	const size_t								m_iterationCount;
   9173 	const size_t								m_opCount;
   9174 	const vk::VkPhysicalDeviceMemoryProperties	m_memoryProperties;
   9175 	deUint32									m_memoryTypeNdx;
   9176 	size_t										m_iteration;
   9177 	StageFunc									m_stage;
   9178 	tcu::ResultCollector						m_resultCollector;
   9179 
   9180 	vector<Command*>							m_commands;
   9181 	MovePtr<Memory>								m_memory;
   9182 	MovePtr<Context>							m_renderContext;
   9183 	MovePtr<PrepareContext>						m_prepareContext;
   9184 
   9185 	bool										nextIteration					(void);
   9186 	bool										nextMemoryType					(void);
   9187 
   9188 	bool										createCommandsAndAllocateMemory	(void);
   9189 	bool										prepare							(void);
   9190 	bool										execute							(void);
   9191 	bool										verify							(void);
   9192 	void										resetResources					(void);
   9193 };
   9194 
   9195 void MemoryTestInstance::resetResources (void)
   9196 {
   9197 	const vk::DeviceInterface&	vkd		= m_context.getDeviceInterface();
   9198 	const vk::VkDevice			device	= m_context.getDevice();
   9199 
   9200 	VK_CHECK(vkd.deviceWaitIdle(device));
   9201 
   9202 	for (size_t commandNdx = 0; commandNdx < m_commands.size(); commandNdx++)
   9203 	{
   9204 		delete m_commands[commandNdx];
   9205 		m_commands[commandNdx] = DE_NULL;
   9206 	}
   9207 
   9208 	m_commands.clear();
   9209 	m_prepareContext.clear();
   9210 	m_memory.clear();
   9211 }
   9212 
   9213 bool MemoryTestInstance::nextIteration (void)
   9214 {
   9215 	m_iteration++;
   9216 
   9217 	if (m_iteration < m_iterationCount)
   9218 	{
   9219 		resetResources();
   9220 		m_stage = &MemoryTestInstance::createCommandsAndAllocateMemory;
   9221 		return true;
   9222 	}
   9223 	else
   9224 		return nextMemoryType();
   9225 }
   9226 
   9227 bool MemoryTestInstance::nextMemoryType (void)
   9228 {
   9229 	resetResources();
   9230 
   9231 	DE_ASSERT(m_commands.empty());
   9232 
   9233 	m_memoryTypeNdx++;
   9234 
   9235 	if (m_memoryTypeNdx < m_memoryProperties.memoryTypeCount)
   9236 	{
   9237 		m_iteration	= 0;
   9238 		m_stage		= &MemoryTestInstance::createCommandsAndAllocateMemory;
   9239 
   9240 		return true;
   9241 	}
   9242 	else
   9243 	{
   9244 		m_stage = DE_NULL;
   9245 		return false;
   9246 	}
   9247 }
   9248 
   9249 MemoryTestInstance::MemoryTestInstance (::vkt::Context& context, const TestConfig& config)
   9250 	: TestInstance			(context)
   9251 	, m_config				(config)
   9252 	, m_iterationCount		(5)
   9253 	, m_opCount				(50)
   9254 	, m_memoryProperties	(vk::getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()))
   9255 	, m_memoryTypeNdx		(0)
   9256 	, m_iteration			(0)
   9257 	, m_stage				(&MemoryTestInstance::createCommandsAndAllocateMemory)
   9258 	, m_resultCollector		(context.getTestContext().getLog())
   9259 
   9260 	, m_memory				(DE_NULL)
   9261 {
   9262 	TestLog&	log	= context.getTestContext().getLog();
   9263 	{
   9264 		const tcu::ScopedLogSection section (log, "TestCaseInfo", "Test Case Info");
   9265 
   9266 		log << TestLog::Message << "Buffer size: " << config.size << TestLog::EndMessage;
   9267 		log << TestLog::Message << "Sharing: " << config.sharing << TestLog::EndMessage;
   9268 		log << TestLog::Message << "Access: " << config.usage << TestLog::EndMessage;
   9269 	}
   9270 
   9271 	{
   9272 		const tcu::ScopedLogSection section (log, "MemoryProperties", "Memory Properties");
   9273 
   9274 		for (deUint32 heapNdx = 0; heapNdx < m_memoryProperties.memoryHeapCount; heapNdx++)
   9275 		{
   9276 			const tcu::ScopedLogSection heapSection (log, "Heap" + de::toString(heapNdx), "Heap " + de::toString(heapNdx));
   9277 
   9278 			log << TestLog::Message << "Size: " << m_memoryProperties.memoryHeaps[heapNdx].size << TestLog::EndMessage;
   9279 			log << TestLog::Message << "Flags: " << m_memoryProperties.memoryHeaps[heapNdx].flags << TestLog::EndMessage;
   9280 		}
   9281 
   9282 		for (deUint32 memoryTypeNdx = 0; memoryTypeNdx < m_memoryProperties.memoryTypeCount; memoryTypeNdx++)
   9283 		{
   9284 			const tcu::ScopedLogSection memoryTypeSection (log, "MemoryType" + de::toString(memoryTypeNdx), "Memory type " + de::toString(memoryTypeNdx));
   9285 
   9286 			log << TestLog::Message << "Properties: " << m_memoryProperties.memoryTypes[memoryTypeNdx].propertyFlags << TestLog::EndMessage;
   9287 			log << TestLog::Message << "Heap: " << m_memoryProperties.memoryTypes[memoryTypeNdx].heapIndex << TestLog::EndMessage;
   9288 		}
   9289 	}
   9290 
   9291 	{
   9292 		const vk::InstanceInterface&			vki					= context.getInstanceInterface();
   9293 		const vk::VkPhysicalDevice				physicalDevice		= context.getPhysicalDevice();
   9294 		const vk::DeviceInterface&				vkd					= context.getDeviceInterface();
   9295 		const vk::VkDevice						device				= context.getDevice();
   9296 		const vk::VkQueue						queue				= context.getUniversalQueue();
   9297 		const deUint32							queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
   9298 		vector<pair<deUint32, vk::VkQueue> >	queues;
   9299 
   9300 		queues.push_back(std::make_pair(queueFamilyIndex, queue));
   9301 
   9302 		m_renderContext = MovePtr<Context>(new Context(vki, vkd, physicalDevice, device, queue, queueFamilyIndex, queues, context.getBinaryCollection()));
   9303 	}
   9304 }
   9305 
   9306 MemoryTestInstance::~MemoryTestInstance (void)
   9307 {
   9308 	resetResources();
   9309 }
   9310 
   9311 bool MemoryTestInstance::createCommandsAndAllocateMemory (void)
   9312 {
   9313 	const vk::VkDevice							device				= m_context.getDevice();
   9314 	TestLog&									log					= m_context.getTestContext().getLog();
   9315 	const vk::InstanceInterface&				vki					= m_context.getInstanceInterface();
   9316 	const vk::VkPhysicalDevice					physicalDevice		= m_context.getPhysicalDevice();
   9317 	const vk::DeviceInterface&					vkd					= m_context.getDeviceInterface();
   9318 	const vk::VkPhysicalDeviceMemoryProperties	memoryProperties	= vk::getPhysicalDeviceMemoryProperties(vki, physicalDevice);
   9319 	const tcu::ScopedLogSection					section				(log, "MemoryType" + de::toString(m_memoryTypeNdx) + "CreateCommands" + de::toString(m_iteration),
   9320 																		  "Memory type " + de::toString(m_memoryTypeNdx) + " create commands iteration " + de::toString(m_iteration));
   9321 	const vector<deUint32>&						queues				= m_renderContext->getQueueFamilies();
   9322 
   9323 	DE_ASSERT(m_commands.empty());
   9324 
   9325 	if (m_config.usage & (USAGE_HOST_READ | USAGE_HOST_WRITE)
   9326 		&& !(memoryProperties.memoryTypes[m_memoryTypeNdx].propertyFlags & vk::VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT))
   9327 	{
   9328 		log << TestLog::Message << "Memory type not supported" << TestLog::EndMessage;
   9329 
   9330 		return nextMemoryType();
   9331 	}
   9332 	else
   9333 	{
   9334 		try
   9335 		{
   9336 			const vk::VkBufferUsageFlags	bufferUsage		= usageToBufferUsageFlags(m_config.usage);
   9337 			const vk::VkImageUsageFlags		imageUsage		= usageToImageUsageFlags(m_config.usage);
   9338 			const vk::VkDeviceSize			maxBufferSize	= bufferUsage != 0
   9339 															? roundBufferSizeToWxHx4(findMaxBufferSize(vkd, device, bufferUsage, m_config.sharing, queues, m_config.size, m_memoryTypeNdx))
   9340 															: 0;
   9341 			const IVec2						maxImageSize	= imageUsage != 0
   9342 															? findMaxRGBA8ImageSize(vkd, device, imageUsage, m_config.sharing, queues, m_config.size, m_memoryTypeNdx)
   9343 															: IVec2(0, 0);
   9344 
   9345 			log << TestLog::Message << "Max buffer size: " << maxBufferSize << TestLog::EndMessage;
   9346 			log << TestLog::Message << "Max RGBA8 image size: " << maxImageSize << TestLog::EndMessage;
   9347 
   9348 			// Skip tests if there are no supported operations
   9349 			if (maxBufferSize == 0
   9350 				&& maxImageSize[0] == 0
   9351 				&& (m_config.usage & (USAGE_HOST_READ|USAGE_HOST_WRITE)) == 0)
   9352 			{
   9353 				log << TestLog::Message << "Skipping memory type. None of the usages are supported." << TestLog::EndMessage;
   9354 
   9355 				return nextMemoryType();
   9356 			}
   9357 			else
   9358 			{
   9359 				const deUint32	seed	= 2830980989u ^ deUint32Hash((deUint32)(m_iteration) * m_memoryProperties.memoryTypeCount +  m_memoryTypeNdx);
   9360 
   9361 				m_memory	= MovePtr<Memory>(new Memory(vki, vkd, physicalDevice, device, m_config.size, m_memoryTypeNdx, maxBufferSize, maxImageSize[0], maxImageSize[1]));
   9362 
   9363 				log << TestLog::Message << "Create commands" << TestLog::EndMessage;
   9364 				createCommands(m_commands, seed, *m_memory, m_config.usage, m_config.sharing, m_opCount);
   9365 
   9366 				m_stage = &MemoryTestInstance::prepare;
   9367 				return true;
   9368 			}
   9369 		}
   9370 		catch (const tcu::TestError& e)
   9371 		{
   9372 			m_resultCollector.fail("Failed, got exception: " + string(e.getMessage()));
   9373 			return nextMemoryType();
   9374 		}
   9375 	}
   9376 }
   9377 
   9378 bool MemoryTestInstance::prepare (void)
   9379 {
   9380 	TestLog&					log		= m_context.getTestContext().getLog();
   9381 	const tcu::ScopedLogSection	section	(log, "MemoryType" + de::toString(m_memoryTypeNdx) + "Prepare" + de::toString(m_iteration),
   9382 											  "Memory type " + de::toString(m_memoryTypeNdx) + " prepare iteration" + de::toString(m_iteration));
   9383 
   9384 	m_prepareContext = MovePtr<PrepareContext>(new PrepareContext(*m_renderContext, *m_memory));
   9385 
   9386 	DE_ASSERT(!m_commands.empty());
   9387 
   9388 	for (size_t cmdNdx = 0; cmdNdx < m_commands.size(); cmdNdx++)
   9389 	{
   9390 		Command& command = *m_commands[cmdNdx];
   9391 
   9392 		try
   9393 		{
   9394 			command.prepare(*m_prepareContext);
   9395 		}
   9396 		catch (const tcu::TestError& e)
   9397 		{
   9398 			m_resultCollector.fail(de::toString(cmdNdx) + ":" + command.getName() + " failed to prepare, got exception: " + string(e.getMessage()));
   9399 			return nextMemoryType();
   9400 		}
   9401 	}
   9402 
   9403 	m_stage = &MemoryTestInstance::execute;
   9404 	return true;
   9405 }
   9406 
   9407 bool MemoryTestInstance::execute (void)
   9408 {
   9409 	TestLog&					log				= m_context.getTestContext().getLog();
   9410 	const tcu::ScopedLogSection	section			(log, "MemoryType" + de::toString(m_memoryTypeNdx) + "Execute" + de::toString(m_iteration),
   9411 													  "Memory type " + de::toString(m_memoryTypeNdx) + " execute iteration " + de::toString(m_iteration));
   9412 	ExecuteContext				executeContext	(*m_renderContext);
   9413 	const vk::VkDevice			device			= m_context.getDevice();
   9414 	const vk::DeviceInterface&	vkd				= m_context.getDeviceInterface();
   9415 
   9416 	DE_ASSERT(!m_commands.empty());
   9417 
   9418 	for (size_t cmdNdx = 0; cmdNdx < m_commands.size(); cmdNdx++)
   9419 	{
   9420 		Command& command = *m_commands[cmdNdx];
   9421 
   9422 		try
   9423 		{
   9424 			command.execute(executeContext);
   9425 		}
   9426 		catch (const tcu::TestError& e)
   9427 		{
   9428 			m_resultCollector.fail(de::toString(cmdNdx) + ":" + command.getName() + " failed to execute, got exception: " + string(e.getMessage()));
   9429 			return nextIteration();
   9430 		}
   9431 	}
   9432 
   9433 	VK_CHECK(vkd.deviceWaitIdle(device));
   9434 
   9435 	m_stage = &MemoryTestInstance::verify;
   9436 	return true;
   9437 }
   9438 
   9439 bool MemoryTestInstance::verify (void)
   9440 {
   9441 	DE_ASSERT(!m_commands.empty());
   9442 
   9443 	TestLog&					log				= m_context.getTestContext().getLog();
   9444 	const tcu::ScopedLogSection	section			(log, "MemoryType" + de::toString(m_memoryTypeNdx) + "Verify" + de::toString(m_iteration),
   9445 													  "Memory type " + de::toString(m_memoryTypeNdx) + " verify iteration " + de::toString(m_iteration));
   9446 	VerifyContext				verifyContext	(log, m_resultCollector, *m_renderContext, m_config.size);
   9447 
   9448 	log << TestLog::Message << "Begin verify" << TestLog::EndMessage;
   9449 
   9450 	for (size_t cmdNdx = 0; cmdNdx < m_commands.size(); cmdNdx++)
   9451 	{
   9452 		Command& command = *m_commands[cmdNdx];
   9453 
   9454 		try
   9455 		{
   9456 			command.verify(verifyContext, cmdNdx);
   9457 		}
   9458 		catch (const tcu::TestError& e)
   9459 		{
   9460 			m_resultCollector.fail(de::toString(cmdNdx) + ":" + command.getName() + " failed to verify, got exception: " + string(e.getMessage()));
   9461 			return nextIteration();
   9462 		}
   9463 	}
   9464 
   9465 	return nextIteration();
   9466 }
   9467 
   9468 tcu::TestStatus MemoryTestInstance::iterate (void)
   9469 {
   9470 	if ((this->*m_stage)())
   9471 		return tcu::TestStatus::incomplete();
   9472 	else
   9473 		return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
   9474 }
   9475 
   9476 struct AddPrograms
   9477 {
   9478 	void init (vk::SourceCollections& sources, TestConfig config) const
   9479 	{
   9480 		// Vertex buffer rendering
   9481 		if (config.usage & USAGE_VERTEX_BUFFER)
   9482 		{
   9483 			const char* const vertexShader =
   9484 				"#version 310 es\n"
   9485 				"layout(location = 0) in highp vec2 a_position;\n"
   9486 				"void main (void) {\n"
   9487 				"\tgl_PointSize = 1.0;\n"
   9488 				"\tgl_Position = vec4(1.998 * a_position - vec2(0.999), 0.0, 1.0);\n"
   9489 				"}\n";
   9490 
   9491 			sources.glslSources.add("vertex-buffer.vert")
   9492 				<< glu::VertexSource(vertexShader);
   9493 		}
   9494 
   9495 		// Index buffer rendering
   9496 		if (config.usage & USAGE_INDEX_BUFFER)
   9497 		{
   9498 			const char* const vertexShader =
   9499 				"#version 310 es\n"
   9500 				"precision highp float;\n"
   9501 				"void main (void) {\n"
   9502 				"\tgl_PointSize = 1.0;\n"
   9503 				"\thighp vec2 pos = vec2(gl_VertexIndex % 256, gl_VertexIndex / 256) / vec2(255.0);\n"
   9504 				"\tgl_Position = vec4(1.998 * pos - vec2(0.999), 0.0, 1.0);\n"
   9505 				"}\n";
   9506 
   9507 			sources.glslSources.add("index-buffer.vert")
   9508 				<< glu::VertexSource(vertexShader);
   9509 		}
   9510 
   9511 		if (config.usage & USAGE_UNIFORM_BUFFER)
   9512 		{
   9513 			{
   9514 				std::ostringstream vertexShader;
   9515 
   9516 				vertexShader <<
   9517 					"#version 310 es\n"
   9518 					"precision highp float;\n"
   9519 					"layout(set=0, binding=0) uniform Block\n"
   9520 					"{\n"
   9521 					"\thighp uvec4 values[" << de::toString<size_t>(MAX_UNIFORM_BUFFER_SIZE / (sizeof(deUint32) * 4)) << "];\n"
   9522 					"} block;\n"
   9523 					"void main (void) {\n"
   9524 					"\tgl_PointSize = 1.0;\n"
   9525 					"\thighp uvec4 vecVal = block.values[gl_VertexIndex / 8];\n"
   9526 					"\thighp uint val;\n"
   9527 					"\tif (((gl_VertexIndex / 2) % 4 == 0))\n"
   9528 					"\t\tval = vecVal.x;\n"
   9529 					"\telse if (((gl_VertexIndex / 2) % 4 == 1))\n"
   9530 					"\t\tval = vecVal.y;\n"
   9531 					"\telse if (((gl_VertexIndex / 2) % 4 == 2))\n"
   9532 					"\t\tval = vecVal.z;\n"
   9533 					"\telse if (((gl_VertexIndex / 2) % 4 == 3))\n"
   9534 					"\t\tval = vecVal.w;\n"
   9535 					"\tif ((gl_VertexIndex % 2) == 0)\n"
   9536 					"\t\tval = val & 0xFFFFu;\n"
   9537 					"\telse\n"
   9538 					"\t\tval = val >> 16u;\n"
   9539 					"\thighp vec2 pos = vec2(val & 0xFFu, val >> 8u) / vec2(255.0);\n"
   9540 					"\tgl_Position = vec4(1.998 * pos - vec2(0.999), 0.0, 1.0);\n"
   9541 					"}\n";
   9542 
   9543 				sources.glslSources.add("uniform-buffer.vert")
   9544 					<< glu::VertexSource(vertexShader.str());
   9545 			}
   9546 
   9547 			{
   9548 				const size_t		arraySize		= MAX_UNIFORM_BUFFER_SIZE / (sizeof(deUint32) * 4);
   9549 				const size_t		arrayIntSize	= arraySize * 4;
   9550 				std::ostringstream	fragmentShader;
   9551 
   9552 				fragmentShader <<
   9553 					"#version 310 es\n"
   9554 					"precision highp float;\n"
   9555 					"precision highp int;\n"
   9556 					"layout(location = 0) out highp vec4 o_color;\n"
   9557 					"layout(set=0, binding=0) uniform Block\n"
   9558 					"{\n"
   9559 					"\thighp uvec4 values[" << arraySize << "];\n"
   9560 					"} block;\n"
   9561 					"layout(push_constant) uniform PushC\n"
   9562 					"{\n"
   9563 					"\tuint callId;\n"
   9564 					"\tuint valuesPerPixel;\n"
   9565 					"} pushC;\n"
   9566 					"void main (void) {\n"
   9567 					"\thighp uint id = pushC.callId * (" << arrayIntSize << "u / pushC.valuesPerPixel) + uint(gl_FragCoord.y) * 256u + uint(gl_FragCoord.x);\n"
   9568 					"\tif (uint(gl_FragCoord.y) * 256u + uint(gl_FragCoord.x) < pushC.callId * (" << arrayIntSize  << "u / pushC.valuesPerPixel))\n"
   9569 					"\t\tdiscard;\n"
   9570 					"\thighp uint value = id;\n"
   9571 					"\tfor (uint i = 0u; i < pushC.valuesPerPixel; i++)\n"
   9572 					"\t{\n"
   9573 					"\t\thighp uvec4 vecVal = block.values[(value / 4u) % " << arraySize << "u];\n"
   9574 					"\t\tif ((value % 4u) == 0u)\n"
   9575 					"\t\t\tvalue = vecVal.x;\n"
   9576 					"\t\telse if ((value % 4u) == 1u)\n"
   9577 					"\t\t\tvalue = vecVal.y;\n"
   9578 					"\t\telse if ((value % 4u) == 2u)\n"
   9579 					"\t\t\tvalue = vecVal.z;\n"
   9580 					"\t\telse if ((value % 4u) == 3u)\n"
   9581 					"\t\t\tvalue = vecVal.w;\n"
   9582 					"\t}\n"
   9583 					"\tuvec4 valueOut = uvec4(value & 0xFFu, (value >> 8u) & 0xFFu, (value >> 16u) & 0xFFu, (value >> 24u) & 0xFFu);\n"
   9584 					"\to_color = vec4(valueOut) / vec4(255.0);\n"
   9585 					"}\n";
   9586 
   9587 				sources.glslSources.add("uniform-buffer.frag")
   9588 					<< glu::FragmentSource(fragmentShader.str());
   9589 			}
   9590 		}
   9591 
   9592 		if (config.usage & USAGE_STORAGE_BUFFER)
   9593 		{
   9594 			{
   9595 				// Vertex storage buffer rendering
   9596 				const char* const vertexShader =
   9597 					"#version 310 es\n"
   9598 					"precision highp float;\n"
   9599 					"layout(set=0, binding=0) buffer Block\n"
   9600 					"{\n"
   9601 					"\thighp uvec4 values[];\n"
   9602 					"} block;\n"
   9603 					"void main (void) {\n"
   9604 					"\tgl_PointSize = 1.0;\n"
   9605 					"\thighp uvec4 vecVal = block.values[gl_VertexIndex / 8];\n"
   9606 					"\thighp uint val;\n"
   9607 					"\tif (((gl_VertexIndex / 2) % 4 == 0))\n"
   9608 					"\t\tval = vecVal.x;\n"
   9609 					"\telse if (((gl_VertexIndex / 2) % 4 == 1))\n"
   9610 					"\t\tval = vecVal.y;\n"
   9611 					"\telse if (((gl_VertexIndex / 2) % 4 == 2))\n"
   9612 					"\t\tval = vecVal.z;\n"
   9613 					"\telse if (((gl_VertexIndex / 2) % 4 == 3))\n"
   9614 					"\t\tval = vecVal.w;\n"
   9615 					"\tif ((gl_VertexIndex % 2) == 0)\n"
   9616 					"\t\tval = val & 0xFFFFu;\n"
   9617 					"\telse\n"
   9618 					"\t\tval = val >> 16u;\n"
   9619 					"\thighp vec2 pos = vec2(val & 0xFFu, val >> 8u) / vec2(255.0);\n"
   9620 					"\tgl_Position = vec4(1.998 * pos - vec2(0.999), 0.0, 1.0);\n"
   9621 					"}\n";
   9622 
   9623 				sources.glslSources.add("storage-buffer.vert")
   9624 					<< glu::VertexSource(vertexShader);
   9625 			}
   9626 
   9627 			{
   9628 				std::ostringstream	fragmentShader;
   9629 
   9630 				fragmentShader <<
   9631 					"#version 310 es\n"
   9632 					"precision highp float;\n"
   9633 					"precision highp int;\n"
   9634 					"layout(location = 0) out highp vec4 o_color;\n"
   9635 					"layout(set=0, binding=0) buffer Block\n"
   9636 					"{\n"
   9637 					"\thighp uvec4 values[];\n"
   9638 					"} block;\n"
   9639 					"layout(push_constant) uniform PushC\n"
   9640 					"{\n"
   9641 					"\tuint valuesPerPixel;\n"
   9642 					"\tuint bufferSize;\n"
   9643 					"} pushC;\n"
   9644 					"void main (void) {\n"
   9645 					"\thighp uint arrayIntSize = pushC.bufferSize / 4u;\n"
   9646 					"\thighp uint id = uint(gl_FragCoord.y) * 256u + uint(gl_FragCoord.x);\n"
   9647 					"\thighp uint value = id;\n"
   9648 					"\tfor (uint i = 0u; i < pushC.valuesPerPixel; i++)\n"
   9649 					"\t{\n"
   9650 					"\t\thighp uvec4 vecVal = block.values[(value / 4u) % (arrayIntSize / 4u)];\n"
   9651 					"\t\tif ((value % 4u) == 0u)\n"
   9652 					"\t\t\tvalue = vecVal.x;\n"
   9653 					"\t\telse if ((value % 4u) == 1u)\n"
   9654 					"\t\t\tvalue = vecVal.y;\n"
   9655 					"\t\telse if ((value % 4u) == 2u)\n"
   9656 					"\t\t\tvalue = vecVal.z;\n"
   9657 					"\t\telse if ((value % 4u) == 3u)\n"
   9658 					"\t\t\tvalue = vecVal.w;\n"
   9659 					"\t}\n"
   9660 					"\tuvec4 valueOut = uvec4(value & 0xFFu, (value >> 8u) & 0xFFu, (value >> 16u) & 0xFFu, (value >> 24u) & 0xFFu);\n"
   9661 					"\to_color = vec4(valueOut) / vec4(255.0);\n"
   9662 					"}\n";
   9663 
   9664 				sources.glslSources.add("storage-buffer.frag")
   9665 					<< glu::FragmentSource(fragmentShader.str());
   9666 			}
   9667 		}
   9668 
   9669 		if (config.usage & USAGE_UNIFORM_TEXEL_BUFFER)
   9670 		{
   9671 			{
   9672 				// Vertex uniform texel buffer rendering
   9673 				const char* const vertexShader =
   9674 					"#version 310 es\n"
   9675 					"#extension GL_EXT_texture_buffer : require\n"
   9676 					"precision highp float;\n"
   9677 					"layout(set=0, binding=0) uniform highp usamplerBuffer u_sampler;\n"
   9678 					"void main (void) {\n"
   9679 					"\tgl_PointSize = 1.0;\n"
   9680 					"\thighp uint val = texelFetch(u_sampler, gl_VertexIndex).x;\n"
   9681 					"\thighp vec2 pos = vec2(val & 0xFFu, val >> 8u) / vec2(255.0);\n"
   9682 					"\tgl_Position = vec4(1.998 * pos - vec2(0.999), 0.0, 1.0);\n"
   9683 					"}\n";
   9684 
   9685 				sources.glslSources.add("uniform-texel-buffer.vert")
   9686 					<< glu::VertexSource(vertexShader);
   9687 			}
   9688 
   9689 			{
   9690 				// Fragment uniform texel buffer rendering
   9691 				const char* const fragmentShader =
   9692 					"#version 310 es\n"
   9693 					"#extension GL_EXT_texture_buffer : require\n"
   9694 					"precision highp float;\n"
   9695 					"precision highp int;\n"
   9696 					"layout(set=0, binding=0) uniform highp usamplerBuffer u_sampler;\n"
   9697 					"layout(location = 0) out highp vec4 o_color;\n"
   9698 					"layout(push_constant) uniform PushC\n"
   9699 					"{\n"
   9700 					"\tuint callId;\n"
   9701 					"\tuint valuesPerPixel;\n"
   9702 					"\tuint maxTexelCount;\n"
   9703 					"} pushC;\n"
   9704 					"void main (void) {\n"
   9705 					"\thighp uint id = uint(gl_FragCoord.y) * 256u + uint(gl_FragCoord.x);\n"
   9706 					"\thighp uint value = id;\n"
   9707 					"\tif (uint(gl_FragCoord.y) * 256u + uint(gl_FragCoord.x) < pushC.callId * (pushC.maxTexelCount / pushC.valuesPerPixel))\n"
   9708 					"\t\tdiscard;\n"
   9709 					"\tfor (uint i = 0u; i < pushC.valuesPerPixel; i++)\n"
   9710 					"\t{\n"
   9711 					"\t\tvalue = texelFetch(u_sampler, int(value % uint(textureSize(u_sampler)))).x;\n"
   9712 					"\t}\n"
   9713 					"\tuvec4 valueOut = uvec4(value & 0xFFu, (value >> 8u) & 0xFFu, (value >> 16u) & 0xFFu, (value >> 24u) & 0xFFu);\n"
   9714 					"\to_color = vec4(valueOut) / vec4(255.0);\n"
   9715 					"}\n";
   9716 
   9717 				sources.glslSources.add("uniform-texel-buffer.frag")
   9718 					<< glu::FragmentSource(fragmentShader);
   9719 			}
   9720 		}
   9721 
   9722 		if (config.usage & USAGE_STORAGE_TEXEL_BUFFER)
   9723 		{
   9724 			{
   9725 				// Vertex storage texel buffer rendering
   9726 				const char* const vertexShader =
   9727 					"#version 450\n"
   9728 					"#extension GL_EXT_texture_buffer : require\n"
   9729 					"precision highp float;\n"
   9730 					"layout(set=0, binding=0, r32ui) uniform readonly highp uimageBuffer u_sampler;\n"
   9731 					"out gl_PerVertex {\n"
   9732 					"\tvec4 gl_Position;\n"
   9733 					"\tfloat gl_PointSize;\n"
   9734 					"};\n"
   9735 					"void main (void) {\n"
   9736 					"\tgl_PointSize = 1.0;\n"
   9737 					"\thighp uint val = imageLoad(u_sampler, gl_VertexIndex / 2).x;\n"
   9738 					"\tif (gl_VertexIndex % 2 == 0)\n"
   9739 					"\t\tval = val & 0xFFFFu;\n"
   9740 					"\telse\n"
   9741 					"\t\tval = val >> 16;\n"
   9742 					"\thighp vec2 pos = vec2(val & 0xFFu, val >> 8u) / vec2(255.0);\n"
   9743 					"\tgl_Position = vec4(1.998 * pos - vec2(0.999), 0.0, 1.0);\n"
   9744 					"}\n";
   9745 
   9746 				sources.glslSources.add("storage-texel-buffer.vert")
   9747 					<< glu::VertexSource(vertexShader);
   9748 			}
   9749 			{
   9750 				// Fragment storage texel buffer rendering
   9751 				const char* const fragmentShader =
   9752 					"#version 310 es\n"
   9753 					"#extension GL_EXT_texture_buffer : require\n"
   9754 					"precision highp float;\n"
   9755 					"precision highp int;\n"
   9756 					"layout(set=0, binding=0, r32ui) uniform readonly highp uimageBuffer u_sampler;\n"
   9757 					"layout(location = 0) out highp vec4 o_color;\n"
   9758 					"layout(push_constant) uniform PushC\n"
   9759 					"{\n"
   9760 					"\tuint callId;\n"
   9761 					"\tuint valuesPerPixel;\n"
   9762 					"\tuint maxTexelCount;\n"
   9763 					"\tuint width;\n"
   9764 					"} pushC;\n"
   9765 					"void main (void) {\n"
   9766 					"\thighp uint id = uint(gl_FragCoord.y) * 256u + uint(gl_FragCoord.x);\n"
   9767 					"\thighp uint value = id;\n"
   9768 					"\tif (uint(gl_FragCoord.y) * 256u + uint(gl_FragCoord.x) < pushC.callId * (pushC.maxTexelCount / pushC.valuesPerPixel))\n"
   9769 					"\t\tdiscard;\n"
   9770 					"\tfor (uint i = 0u; i < pushC.valuesPerPixel; i++)\n"
   9771 					"\t{\n"
   9772 					"\t\tvalue = imageLoad(u_sampler, int(value % pushC.width)).x;\n"
   9773 					"\t}\n"
   9774 					"\tuvec4 valueOut = uvec4(value & 0xFFu, (value >> 8u) & 0xFFu, (value >> 16u) & 0xFFu, (value >> 24u) & 0xFFu);\n"
   9775 					"\to_color = vec4(valueOut) / vec4(255.0);\n"
   9776 					"}\n";
   9777 
   9778 				sources.glslSources.add("storage-texel-buffer.frag")
   9779 					<< glu::FragmentSource(fragmentShader);
   9780 			}
   9781 		}
   9782 
   9783 		if (config.usage & USAGE_STORAGE_IMAGE)
   9784 		{
   9785 			{
   9786 				// Vertex storage image
   9787 				const char* const vertexShader =
   9788 					"#version 450\n"
   9789 					"precision highp float;\n"
   9790 					"layout(set=0, binding=0, rgba8) uniform image2D u_image;\n"
   9791 					"out gl_PerVertex {\n"
   9792 					"\tvec4 gl_Position;\n"
   9793 					"\tfloat gl_PointSize;\n"
   9794 					"};\n"
   9795 					"void main (void) {\n"
   9796 					"\tgl_PointSize = 1.0;\n"
   9797 					"\thighp vec4 val = imageLoad(u_image, ivec2((gl_VertexIndex / 2) / imageSize(u_image).x, (gl_VertexIndex / 2) % imageSize(u_image).x));\n"
   9798 					"\thighp vec2 pos;\n"
   9799 					"\tif (gl_VertexIndex % 2 == 0)\n"
   9800 					"\t\tpos = val.xy;\n"
   9801 					"\telse\n"
   9802 					"\t\tpos = val.zw;\n"
   9803 					"\tgl_Position = vec4(1.998 * pos - vec2(0.999), 0.0, 1.0);\n"
   9804 					"}\n";
   9805 
   9806 				sources.glslSources.add("storage-image.vert")
   9807 					<< glu::VertexSource(vertexShader);
   9808 			}
   9809 			{
   9810 				// Fragment storage image
   9811 				const char* const fragmentShader =
   9812 					"#version 450\n"
   9813 					"#extension GL_EXT_texture_buffer : require\n"
   9814 					"precision highp float;\n"
   9815 					"layout(set=0, binding=0, rgba8) uniform image2D u_image;\n"
   9816 					"layout(location = 0) out highp vec4 o_color;\n"
   9817 					"void main (void) {\n"
   9818 					"\thighp uvec2 size = uvec2(imageSize(u_image).x, imageSize(u_image).y);\n"
   9819 					"\thighp uint valuesPerPixel = max(1u, (size.x * size.y) / (256u * 256u));\n"
   9820 					"\thighp uvec4 value = uvec4(uint(gl_FragCoord.x), uint(gl_FragCoord.y), 0u, 0u);\n"
   9821 					"\tfor (uint i = 0u; i < valuesPerPixel; i++)\n"
   9822 					"\t{\n"
   9823 					"\t\thighp vec4 floatValue = imageLoad(u_image, ivec2(int((value.z *  256u + (value.x ^ value.z)) % size.x), int((value.w * 256u + (value.y ^ value.w)) % size.y)));\n"
   9824 					"\t\tvalue = uvec4(uint(floatValue.x * 255.0), uint(floatValue.y * 255.0), uint(floatValue.z * 255.0), uint(floatValue.w * 255.0));\n"
   9825 					"\t}\n"
   9826 					"\to_color = vec4(value) / vec4(255.0);\n"
   9827 					"}\n";
   9828 
   9829 				sources.glslSources.add("storage-image.frag")
   9830 					<< glu::FragmentSource(fragmentShader);
   9831 			}
   9832 		}
   9833 
   9834 		if (config.usage & USAGE_SAMPLED_IMAGE)
   9835 		{
   9836 			{
   9837 				// Vertex storage image
   9838 				const char* const vertexShader =
   9839 					"#version 450\n"
   9840 					"precision highp float;\n"
   9841 					"layout(set=0, binding=0) uniform sampler2D u_sampler;\n"
   9842 					"out gl_PerVertex {\n"
   9843 					"\tvec4 gl_Position;\n"
   9844 					"\tfloat gl_PointSize;\n"
   9845 					"};\n"
   9846 					"void main (void) {\n"
   9847 					"\tgl_PointSize = 1.0;\n"
   9848 					"\thighp vec4 val = texelFetch(u_sampler, ivec2((gl_VertexIndex / 2) / textureSize(u_sampler, 0).x, (gl_VertexIndex / 2) % textureSize(u_sampler, 0).x), 0);\n"
   9849 					"\thighp vec2 pos;\n"
   9850 					"\tif (gl_VertexIndex % 2 == 0)\n"
   9851 					"\t\tpos = val.xy;\n"
   9852 					"\telse\n"
   9853 					"\t\tpos = val.zw;\n"
   9854 					"\tgl_Position = vec4(1.998 * pos - vec2(0.999), 0.0, 1.0);\n"
   9855 					"}\n";
   9856 
   9857 				sources.glslSources.add("sampled-image.vert")
   9858 					<< glu::VertexSource(vertexShader);
   9859 			}
   9860 			{
   9861 				// Fragment storage image
   9862 				const char* const fragmentShader =
   9863 					"#version 450\n"
   9864 					"#extension GL_EXT_texture_buffer : require\n"
   9865 					"precision highp float;\n"
   9866 					"layout(set=0, binding=0) uniform sampler2D u_sampler;\n"
   9867 					"layout(location = 0) out highp vec4 o_color;\n"
   9868 					"void main (void) {\n"
   9869 					"\thighp uvec2 size = uvec2(textureSize(u_sampler, 0).x, textureSize(u_sampler, 0).y);\n"
   9870 					"\thighp uint valuesPerPixel = max(1u, (size.x * size.y) / (256u * 256u));\n"
   9871 					"\thighp uvec4 value = uvec4(uint(gl_FragCoord.x), uint(gl_FragCoord.y), 0u, 0u);\n"
   9872 					"\tfor (uint i = 0u; i < valuesPerPixel; i++)\n"
   9873 					"\t{\n"
   9874 					"\t\thighp vec4 floatValue = texelFetch(u_sampler, ivec2(int((value.z *  256u + (value.x ^ value.z)) % size.x), int((value.w * 256u + (value.y ^ value.w)) % size.y)), 0);\n"
   9875 					"\t\tvalue = uvec4(uint(floatValue.x * 255.0), uint(floatValue.y * 255.0), uint(floatValue.z * 255.0), uint(floatValue.w * 255.0));\n"
   9876 					"\t}\n"
   9877 					"\to_color = vec4(value) / vec4(255.0);\n"
   9878 					"}\n";
   9879 
   9880 				sources.glslSources.add("sampled-image.frag")
   9881 					<< glu::FragmentSource(fragmentShader);
   9882 			}
   9883 		}
   9884 
   9885 		{
   9886 			const char* const vertexShader =
   9887 				"#version 450\n"
   9888 				"out gl_PerVertex {\n"
   9889 				"\tvec4 gl_Position;\n"
   9890 				"};\n"
   9891 				"precision highp float;\n"
   9892 				"void main (void) {\n"
   9893 				"\tgl_Position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
   9894 				"\t                   ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
   9895 				"}\n";
   9896 
   9897 			sources.glslSources.add("render-quad.vert")
   9898 				<< glu::VertexSource(vertexShader);
   9899 		}
   9900 
   9901 		{
   9902 			const char* const fragmentShader =
   9903 				"#version 310 es\n"
   9904 				"layout(location = 0) out highp vec4 o_color;\n"
   9905 				"void main (void) {\n"
   9906 				"\to_color = vec4(1.0);\n"
   9907 				"}\n";
   9908 
   9909 			sources.glslSources.add("render-white.frag")
   9910 				<< glu::FragmentSource(fragmentShader);
   9911 		}
   9912 	}
   9913 };
   9914 
   9915 } // anonymous
   9916 
   9917 tcu::TestCaseGroup* createPipelineBarrierTests (tcu::TestContext& testCtx)
   9918 {
   9919 	de::MovePtr<tcu::TestCaseGroup>	group			(new tcu::TestCaseGroup(testCtx, "pipeline_barrier", "Pipeline barrier tests."));
   9920 	const vk::VkDeviceSize			sizes[]			=
   9921 	{
   9922 		1024,		// 1K
   9923 		8*1024,		// 8K
   9924 		64*1024,	// 64K
   9925 		1024*1024,	// 1M
   9926 	};
   9927 	const Usage						usages[]		=
   9928 	{
   9929 		USAGE_HOST_READ,
   9930 		USAGE_HOST_WRITE,
   9931 		USAGE_TRANSFER_SRC,
   9932 		USAGE_TRANSFER_DST,
   9933 		USAGE_VERTEX_BUFFER,
   9934 		USAGE_INDEX_BUFFER,
   9935 		USAGE_UNIFORM_BUFFER,
   9936 		USAGE_UNIFORM_TEXEL_BUFFER,
   9937 		USAGE_STORAGE_BUFFER,
   9938 		USAGE_STORAGE_TEXEL_BUFFER,
   9939 		USAGE_STORAGE_IMAGE,
   9940 		USAGE_SAMPLED_IMAGE
   9941 	};
   9942 	const Usage						readUsages[]		=
   9943 	{
   9944 		USAGE_HOST_READ,
   9945 		USAGE_TRANSFER_SRC,
   9946 		USAGE_VERTEX_BUFFER,
   9947 		USAGE_INDEX_BUFFER,
   9948 		USAGE_UNIFORM_BUFFER,
   9949 		USAGE_UNIFORM_TEXEL_BUFFER,
   9950 		USAGE_STORAGE_BUFFER,
   9951 		USAGE_STORAGE_TEXEL_BUFFER,
   9952 		USAGE_STORAGE_IMAGE,
   9953 		USAGE_SAMPLED_IMAGE
   9954 	};
   9955 
   9956 	const Usage						writeUsages[]	=
   9957 	{
   9958 		USAGE_HOST_WRITE,
   9959 		USAGE_TRANSFER_DST
   9960 	};
   9961 
   9962 	for (size_t writeUsageNdx = 0; writeUsageNdx < DE_LENGTH_OF_ARRAY(writeUsages); writeUsageNdx++)
   9963 	{
   9964 		const Usage	writeUsage	= writeUsages[writeUsageNdx];
   9965 
   9966 		for (size_t readUsageNdx = 0; readUsageNdx < DE_LENGTH_OF_ARRAY(readUsages); readUsageNdx++)
   9967 		{
   9968 			const Usage						readUsage		= readUsages[readUsageNdx];
   9969 			const Usage						usage			= writeUsage | readUsage;
   9970 			const string					usageGroupName	(usageToName(usage));
   9971 			de::MovePtr<tcu::TestCaseGroup>	usageGroup		(new tcu::TestCaseGroup(testCtx, usageGroupName.c_str(), usageGroupName.c_str()));
   9972 
   9973 			for (size_t sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizes); sizeNdx++)
   9974 			{
   9975 				const vk::VkDeviceSize	size		= sizes[sizeNdx];
   9976 				const string			testName	(de::toString((deUint64)(size)));
   9977 				const TestConfig		config		=
   9978 				{
   9979 					usage,
   9980 					size,
   9981 					vk::VK_SHARING_MODE_EXCLUSIVE
   9982 				};
   9983 
   9984 				usageGroup->addChild(new InstanceFactory1<MemoryTestInstance, TestConfig, AddPrograms>(testCtx,tcu::NODETYPE_SELF_VALIDATE,  testName, testName, AddPrograms(), config));
   9985 			}
   9986 
   9987 			group->addChild(usageGroup.get());
   9988 			usageGroup.release();
   9989 		}
   9990 	}
   9991 
   9992 	{
   9993 		Usage all = (Usage)0;
   9994 
   9995 		for (size_t usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(usages); usageNdx++)
   9996 			all = all | usages[usageNdx];
   9997 
   9998 		{
   9999 			const string					usageGroupName	("all");
   10000 			de::MovePtr<tcu::TestCaseGroup>	usageGroup		(new tcu::TestCaseGroup(testCtx, usageGroupName.c_str(), usageGroupName.c_str()));
   10001 
   10002 			for (size_t sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizes); sizeNdx++)
   10003 			{
   10004 				const vk::VkDeviceSize	size		= sizes[sizeNdx];
   10005 				const string			testName	(de::toString((deUint64)(size)));
   10006 				const TestConfig		config		=
   10007 				{
   10008 					all,
   10009 					size,
   10010 					vk::VK_SHARING_MODE_EXCLUSIVE
   10011 				};
   10012 
   10013 				usageGroup->addChild(new InstanceFactory1<MemoryTestInstance, TestConfig, AddPrograms>(testCtx,tcu::NODETYPE_SELF_VALIDATE,  testName, testName, AddPrograms(), config));
   10014 			}
   10015 
   10016 			group->addChild(usageGroup.get());
   10017 			usageGroup.release();
   10018 		}
   10019 
   10020 		{
   10021 			const string					usageGroupName	("all_device");
   10022 			de::MovePtr<tcu::TestCaseGroup>	usageGroup		(new tcu::TestCaseGroup(testCtx, usageGroupName.c_str(), usageGroupName.c_str()));
   10023 
   10024 			for (size_t sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizes); sizeNdx++)
   10025 			{
   10026 				const vk::VkDeviceSize	size		= sizes[sizeNdx];
   10027 				const string			testName	(de::toString((deUint64)(size)));
   10028 				const TestConfig		config		=
   10029 				{
   10030 					(Usage)(all & (~(USAGE_HOST_READ|USAGE_HOST_WRITE))),
   10031 					size,
   10032 					vk::VK_SHARING_MODE_EXCLUSIVE
   10033 				};
   10034 
   10035 				usageGroup->addChild(new InstanceFactory1<MemoryTestInstance, TestConfig, AddPrograms>(testCtx,tcu::NODETYPE_SELF_VALIDATE,  testName, testName, AddPrograms(), config));
   10036 			}
   10037 
   10038 			group->addChild(usageGroup.get());
   10039 			usageGroup.release();
   10040 		}
   10041 	}
   10042 
   10043 	return group.release();
   10044 }
   10045 
   10046 } // memory
   10047 } // vkt
   10048