1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2016 The Khronos Group Inc.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * \brief Synchronization operation abstraction
22 *//*--------------------------------------------------------------------*/
24 #include "vktSynchronizationOperation.hpp"
26 #include "vktTestCase.hpp"
27 #include "vktTestCaseUtil.hpp"
29 #include "vkRefUtil.hpp"
30 #include "vkMemUtil.hpp"
31 #include "vkQueryUtil.hpp"
32 #include "vkTypeUtil.hpp"
33 #include "vkImageUtil.hpp"
34 #include "vkBuilderUtil.hpp"
35 #include "deUniquePtr.hpp"
36 #include "tcuTestLog.hpp"
37 #include "tcuTextureUtil.hpp"
43 namespace synchronization
51 MAX_IMAGE_DIMENSION_2D = 0x1000u,
52 MAX_UBO_RANGE = 0x4000u,
53 MAX_UPDATE_BUFFER_SIZE = 0x10000u,
70 PIPELINE_TYPE_GRAPHICS,
71 PIPELINE_TYPE_COMPUTE,
74 static const char* const s_perVertexBlock = "gl_PerVertex {\n"
75 " vec4 gl_Position;\n"
78 //! A pipeline that can be embedded inside an operation.
82 virtual ~Pipeline (void) {}
83 virtual void recordCommands (OperationContext& context, const VkCommandBuffer cmdBuffer, const VkDescriptorSet descriptorSet) = 0;
86 //! Vertex data that covers the whole viewport with two triangles.
90 VertexGrid (OperationContext& context)
92 const DeviceInterface& vk = context.getDeviceInterface();
93 const VkDevice device = context.getDevice();
94 Allocator& allocator = context.getAllocator();
98 m_vertexData.push_back(tcu::Vec4( 1.0f, 1.0f, 0.0f, 1.0f));
99 m_vertexData.push_back(tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f));
100 m_vertexData.push_back(tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f));
102 m_vertexData.push_back(tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f));
103 m_vertexData.push_back(tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f));
104 m_vertexData.push_back(tcu::Vec4( 1.0f, 1.0f, 0.0f, 1.0f));
106 m_vertexFormat = VK_FORMAT_R32G32B32A32_SFLOAT;
107 m_vertexStride = tcu::getPixelSize(mapVkFormat(m_vertexFormat));
108 const VkDeviceSize vertexDataSizeBytes = m_vertexData.size() * sizeof(m_vertexData[0]);
110 m_vertexBuffer = de::MovePtr<Buffer>(new Buffer(vk, device, allocator,
111 makeBufferCreateInfo(vertexDataSizeBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible));
113 DE_ASSERT(sizeof(m_vertexData[0]) == m_vertexStride);
116 const Allocation& alloc = m_vertexBuffer->getAllocation();
117 deMemcpy(alloc.getHostPtr(), &m_vertexData[0], static_cast<std::size_t>(vertexDataSizeBytes));
118 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), vertexDataSizeBytes);
123 const VkDeviceSize indexBufferSizeBytes = sizeof(deUint32) * m_vertexData.size();
124 const deUint32 numIndices = static_cast<deUint32>(m_vertexData.size());
125 m_indexBuffer = de::MovePtr<Buffer>(new Buffer(vk, device, allocator,
126 makeBufferCreateInfo(indexBufferSizeBytes, VK_BUFFER_USAGE_INDEX_BUFFER_BIT), MemoryRequirement::HostVisible));
128 const Allocation& alloc = m_indexBuffer->getAllocation();
129 deUint32* const pData = static_cast<deUint32*>(alloc.getHostPtr());
131 for (deUint32 i = 0; i < numIndices; ++i)
134 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), indexBufferSizeBytes);
138 VkFormat getVertexFormat (void) const { return m_vertexFormat; }
139 deUint32 getVertexStride (void) const { return m_vertexStride; }
140 VkIndexType getIndexType (void) const { return VK_INDEX_TYPE_UINT32; }
141 deUint32 getNumVertices (void) const { return static_cast<deUint32>(m_vertexData.size()); }
142 deUint32 getNumIndices (void) const { return getNumVertices(); }
143 VkBuffer getVertexBuffer (void) const { return **m_vertexBuffer; }
144 VkBuffer getIndexBuffer (void) const { return **m_indexBuffer; }
147 VkFormat m_vertexFormat;
148 deUint32 m_vertexStride;
149 std::vector<tcu::Vec4> m_vertexData;
150 de::MovePtr<Buffer> m_vertexBuffer;
151 de::MovePtr<Buffer> m_indexBuffer;
154 //! Add flags for all shader stages required to support a particular stage (e.g. fragment requires vertex as well).
155 VkShaderStageFlags getRequiredStages (const VkShaderStageFlagBits stage)
157 if (stage & VK_SHADER_STAGE_COMPUTE_BIT)
159 DE_ASSERT(stage == VK_SHADER_STAGE_COMPUTE_BIT);
163 DE_ASSERT((stage & VK_SHADER_STAGE_COMPUTE_BIT) == 0);
165 VkShaderStageFlags flags = 0u;
167 if (stage & VK_SHADER_STAGE_ALL_GRAPHICS)
168 flags |= VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
169 if (stage & (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT))
170 flags |= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
171 if (stage & VK_SHADER_STAGE_GEOMETRY_BIT)
172 flags |= VK_SHADER_STAGE_GEOMETRY_BIT;
177 //! Check that SSBO read/write is available and that all shader stages are supported.
178 void requireFeaturesForSSBOAccess (OperationContext& context, const VkShaderStageFlags usedStages)
180 const InstanceInterface& vki = context.getInstanceInterface();
181 const VkPhysicalDevice physDevice = context.getPhysicalDevice();
182 FeatureFlags flags = (FeatureFlags)0;
184 if (usedStages & VK_SHADER_STAGE_FRAGMENT_BIT)
185 flags |= FEATURE_FRAGMENT_STORES_AND_ATOMICS;
186 if (usedStages & (VK_SHADER_STAGE_ALL_GRAPHICS & (~VK_SHADER_STAGE_FRAGMENT_BIT)))
187 flags |= FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS;
188 if (usedStages & VK_SHADER_STAGE_GEOMETRY_BIT)
189 flags |= FEATURE_GEOMETRY_SHADER;
190 if (usedStages & (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT))
191 flags |= FEATURE_TESSELLATION_SHADER;
193 requireFeatures(vki, physDevice, flags);
196 Data getHostBufferData (const OperationContext& context, const Buffer& hostBuffer, const VkDeviceSize size)
198 const DeviceInterface& vk = context.getDeviceInterface();
199 const VkDevice device = context.getDevice();
200 const Allocation& alloc = hostBuffer.getAllocation();
202 invalidateMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), size);
206 static_cast<std::size_t>(size), // std::size_t size;
207 static_cast<deUint8*>(alloc.getHostPtr()), // const deUint8* data;
212 void assertValidShaderStage (const VkShaderStageFlagBits stage)
216 case VK_SHADER_STAGE_VERTEX_BIT:
217 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
218 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
219 case VK_SHADER_STAGE_GEOMETRY_BIT:
220 case VK_SHADER_STAGE_FRAGMENT_BIT:
221 case VK_SHADER_STAGE_COMPUTE_BIT:
231 VkPipelineStageFlags pipelineStageFlagsFromShaderStageFlagBits (const VkShaderStageFlagBits shaderStage)
235 case VK_SHADER_STAGE_VERTEX_BIT: return VK_PIPELINE_STAGE_VERTEX_SHADER_BIT;
236 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: return VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT;
237 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: return VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT;
238 case VK_SHADER_STAGE_GEOMETRY_BIT: return VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT;
239 case VK_SHADER_STAGE_FRAGMENT_BIT: return VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
240 case VK_SHADER_STAGE_COMPUTE_BIT: return VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
242 // Other usages are probably an error, so flag that.
245 return (VkPipelineStageFlags)0;
249 //! Fill destination buffer with a repeating pattern.
250 void fillPattern (void* const pData, const VkDeviceSize size)
252 static const deUint8 pattern[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31 };
253 deUint8* const pBytes = static_cast<deUint8*>(pData);
255 for (deUint32 i = 0; i < size; ++i)
256 pBytes[i] = pattern[i % DE_LENGTH_OF_ARRAY(pattern)];
259 //! Get size in bytes of a pixel buffer with given extent.
260 VkDeviceSize getPixelBufferSize (const VkFormat format, const VkExtent3D& extent)
262 const int pixelSize = tcu::getPixelSize(mapVkFormat(format));
263 return (pixelSize * extent.width * extent.height * extent.depth);
266 //! Determine the size of a 2D image that can hold sizeBytes data.
267 VkExtent3D get2DImageExtentWithSize (const VkDeviceSize sizeBytes, const deUint32 pixelSize)
269 const deUint32 size = static_cast<deUint32>(sizeBytes / pixelSize);
271 DE_ASSERT(size <= MAX_IMAGE_DIMENSION_2D * MAX_IMAGE_DIMENSION_2D);
274 std::min(size, static_cast<deUint32>(MAX_IMAGE_DIMENSION_2D)),
275 (size / MAX_IMAGE_DIMENSION_2D) + (size % MAX_IMAGE_DIMENSION_2D != 0 ? 1u : 0u),
279 VkClearValue makeClearValue (const VkFormat format)
281 if (isDepthStencilFormat(format))
282 return makeClearValueDepthStencil(0.4f, 21u);
285 if (isIntFormat(format) || isUintFormat(format))
286 return makeClearValueColorU32(8u, 16u, 24u, 32u);
288 return makeClearValueColorF32(0.25f, 0.49f, 0.75f, 1.0f);
292 void clearPixelBuffer (tcu::PixelBufferAccess& pixels, const VkClearValue& clearValue)
294 const tcu::TextureFormat format = pixels.getFormat();
295 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
297 if (format.order == tcu::TextureFormat::D)
299 for (int z = 0; z < pixels.getDepth(); z++)
300 for (int y = 0; y < pixels.getHeight(); y++)
301 for (int x = 0; x < pixels.getWidth(); x++)
302 pixels.setPixDepth(clearValue.depthStencil.depth, x, y, z);
304 else if (format.order == tcu::TextureFormat::S)
306 for (int z = 0; z < pixels.getDepth(); z++)
307 for (int y = 0; y < pixels.getHeight(); y++)
308 for (int x = 0; x < pixels.getWidth(); x++)
309 pixels.setPixStencil(clearValue.depthStencil.stencil, x, y, z);
311 else if (format.order == tcu::TextureFormat::DS)
313 for (int z = 0; z < pixels.getDepth(); z++)
314 for (int y = 0; y < pixels.getHeight(); y++)
315 for (int x = 0; x < pixels.getWidth(); x++)
317 pixels.setPixDepth(clearValue.depthStencil.depth, x, y, z);
318 pixels.setPixStencil(clearValue.depthStencil.stencil, x, y, z);
321 else if (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
323 const tcu::UVec4 color (clearValue.color.uint32);
325 for (int z = 0; z < pixels.getDepth(); z++)
326 for (int y = 0; y < pixels.getHeight(); y++)
327 for (int x = 0; x < pixels.getWidth(); x++)
328 pixels.setPixel(color, x, y, z);
332 const tcu::Vec4 color (clearValue.color.float32);
334 for (int z = 0; z < pixels.getDepth(); z++)
335 for (int y = 0; y < pixels.getHeight(); y++)
336 for (int x = 0; x < pixels.getWidth(); x++)
337 pixels.setPixel(color, x, y, z);
341 //! Storage image format that requires StorageImageExtendedFormats SPIR-V capability (listed only Vulkan-defined formats).
342 bool isStorageImageExtendedFormat (const VkFormat format)
346 case VK_FORMAT_R32G32_SFLOAT:
347 case VK_FORMAT_R32G32_SINT:
348 case VK_FORMAT_R32G32_UINT:
349 case VK_FORMAT_R16G16B16A16_UNORM:
350 case VK_FORMAT_R16G16B16A16_SNORM:
351 case VK_FORMAT_R16G16_SFLOAT:
352 case VK_FORMAT_R16G16_UNORM:
353 case VK_FORMAT_R16G16_SNORM:
354 case VK_FORMAT_R16G16_SINT:
355 case VK_FORMAT_R16G16_UINT:
356 case VK_FORMAT_R16_SFLOAT:
357 case VK_FORMAT_R16_UNORM:
358 case VK_FORMAT_R16_SNORM:
359 case VK_FORMAT_R16_SINT:
360 case VK_FORMAT_R16_UINT:
361 case VK_FORMAT_R8G8_UNORM:
362 case VK_FORMAT_R8G8_SNORM:
363 case VK_FORMAT_R8G8_SINT:
364 case VK_FORMAT_R8G8_UINT:
365 case VK_FORMAT_R8_UNORM:
366 case VK_FORMAT_R8_SNORM:
367 case VK_FORMAT_R8_SINT:
368 case VK_FORMAT_R8_UINT:
376 VkImageViewType getImageViewType (const VkImageType imageType)
380 case VK_IMAGE_TYPE_1D: return VK_IMAGE_VIEW_TYPE_1D;
381 case VK_IMAGE_TYPE_2D: return VK_IMAGE_VIEW_TYPE_2D;
382 case VK_IMAGE_TYPE_3D: return VK_IMAGE_VIEW_TYPE_3D;
386 return VK_IMAGE_VIEW_TYPE_LAST;
390 std::string getShaderImageType (const VkFormat format, const VkImageType imageType)
392 const tcu::TextureFormat texFormat = mapVkFormat(format);
393 const std::string formatPart = tcu::getTextureChannelClass(texFormat.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ? "u" :
394 tcu::getTextureChannelClass(texFormat.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ? "i" : "";
397 case VK_IMAGE_TYPE_1D: return formatPart + "image1D";
398 case VK_IMAGE_TYPE_2D: return formatPart + "image2D";
399 case VK_IMAGE_TYPE_3D: return formatPart + "image3D";
407 std::string getShaderImageFormatQualifier (const VkFormat format)
409 const tcu::TextureFormat texFormat = mapVkFormat(format);
410 const char* orderPart = DE_NULL;
411 const char* typePart = DE_NULL;
413 switch (texFormat.order)
415 case tcu::TextureFormat::R: orderPart = "r"; break;
416 case tcu::TextureFormat::RG: orderPart = "rg"; break;
417 case tcu::TextureFormat::RGB: orderPart = "rgb"; break;
418 case tcu::TextureFormat::RGBA: orderPart = "rgba"; break;
425 switch (texFormat.type)
427 case tcu::TextureFormat::FLOAT: typePart = "32f"; break;
428 case tcu::TextureFormat::HALF_FLOAT: typePart = "16f"; break;
430 case tcu::TextureFormat::UNSIGNED_INT32: typePart = "32ui"; break;
431 case tcu::TextureFormat::UNSIGNED_INT16: typePart = "16ui"; break;
432 case tcu::TextureFormat::UNSIGNED_INT8: typePart = "8ui"; break;
434 case tcu::TextureFormat::SIGNED_INT32: typePart = "32i"; break;
435 case tcu::TextureFormat::SIGNED_INT16: typePart = "16i"; break;
436 case tcu::TextureFormat::SIGNED_INT8: typePart = "8i"; break;
438 case tcu::TextureFormat::UNORM_INT16: typePart = "16"; break;
439 case tcu::TextureFormat::UNORM_INT8: typePart = "8"; break;
441 case tcu::TextureFormat::SNORM_INT16: typePart = "16_snorm"; break;
442 case tcu::TextureFormat::SNORM_INT8: typePart = "8_snorm"; break;
449 return std::string() + orderPart + typePart;
452 namespace FillUpdateBuffer
461 class Implementation : public Operation
464 Implementation (OperationContext& context, Resource& resource, const BufferOp bufferOp)
465 : m_context (context)
466 , m_resource (resource)
468 , m_bufferOp (bufferOp)
470 DE_ASSERT((m_resource.getBuffer().size % sizeof(deUint32)) == 0);
471 DE_ASSERT(m_bufferOp == BUFFER_OP_FILL || m_resource.getBuffer().size <= MAX_UPDATE_BUFFER_SIZE);
473 m_data.resize(static_cast<size_t>(m_resource.getBuffer().size));
475 if (m_bufferOp == BUFFER_OP_FILL)
477 const std::size_t size = m_data.size() / sizeof(m_fillValue);
478 deUint32* pData = reinterpret_cast<deUint32*>(&m_data[0]);
479 for (deUint32 i = 0; i < size; ++i)
480 pData[i] = m_fillValue;
482 else if (m_bufferOp == BUFFER_OP_UPDATE)
483 fillPattern(&m_data[0], m_data.size());
486 void recordCommands (const VkCommandBuffer cmdBuffer)
488 const DeviceInterface& vk = m_context.getDeviceInterface();
490 if (m_bufferOp == BUFFER_OP_FILL)
491 vk.cmdFillBuffer(cmdBuffer, m_resource.getBuffer().handle, m_resource.getBuffer().offset, m_resource.getBuffer().size, m_fillValue);
492 else if (m_bufferOp == BUFFER_OP_UPDATE)
493 vk.cmdUpdateBuffer(cmdBuffer, m_resource.getBuffer().handle, m_resource.getBuffer().offset, m_resource.getBuffer().size, reinterpret_cast<deUint32*>(&m_data[0]));
496 SyncInfo getSyncInfo (void) const
498 const SyncInfo syncInfo =
500 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
501 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags accessMask;
502 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
507 Data getData (void) const
511 m_data.size(), // std::size_t size;
512 &m_data[0], // const deUint8* data;
518 OperationContext& m_context;
519 Resource& m_resource;
520 std::vector<deUint8> m_data;
521 const deUint32 m_fillValue;
522 const BufferOp m_bufferOp;
525 class Support : public OperationSupport
528 Support (const ResourceDescription& resourceDesc, const BufferOp bufferOp)
529 : m_resourceDesc (resourceDesc)
530 , m_bufferOp (bufferOp)
532 DE_ASSERT(m_bufferOp == BUFFER_OP_FILL || m_bufferOp == BUFFER_OP_UPDATE);
533 DE_ASSERT(m_resourceDesc.type == RESOURCE_TYPE_BUFFER);
536 deUint32 getResourceUsageFlags (void) const
538 return VK_BUFFER_USAGE_TRANSFER_DST_BIT;
541 VkQueueFlags getQueueFlags (void) const
543 return VK_QUEUE_TRANSFER_BIT;
546 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
548 return de::MovePtr<Operation>(new Implementation(context, resource, m_bufferOp));
552 const ResourceDescription m_resourceDesc;
553 const BufferOp m_bufferOp;
556 } // FillUpdateBuffer ns
561 class Implementation : public Operation
564 Implementation (OperationContext& context, Resource& resource, const AccessMode mode)
565 : m_context (context)
566 , m_resource (resource)
569 const DeviceInterface& vk = m_context.getDeviceInterface();
570 const VkDevice device = m_context.getDevice();
571 Allocator& allocator = m_context.getAllocator();
573 const VkBufferUsageFlags hostBufferUsage = (m_mode == ACCESS_MODE_READ ? VK_BUFFER_USAGE_TRANSFER_DST_BIT : VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
575 m_hostBuffer = de::MovePtr<Buffer>(new Buffer(
576 vk, device, allocator, makeBufferCreateInfo(m_resource.getBuffer().size, hostBufferUsage), MemoryRequirement::HostVisible));
578 const Allocation& alloc = m_hostBuffer->getAllocation();
579 if (m_mode == ACCESS_MODE_READ)
580 deMemset(alloc.getHostPtr(), 0, static_cast<size_t>(m_resource.getBuffer().size));
582 fillPattern(alloc.getHostPtr(), m_resource.getBuffer().size);
583 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), m_resource.getBuffer().size);
586 void recordCommands (const VkCommandBuffer cmdBuffer)
588 const DeviceInterface& vk = m_context.getDeviceInterface();
589 const VkBufferCopy copyRegion = makeBufferCopy(0u, 0u, m_resource.getBuffer().size);
591 if (m_mode == ACCESS_MODE_READ)
593 vk.cmdCopyBuffer(cmdBuffer, m_resource.getBuffer().handle, **m_hostBuffer, 1u, ©Region);
595 // Insert a barrier so copied data is available to the host
596 const VkBufferMemoryBarrier barrier = makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, **m_hostBuffer, 0u, m_resource.getBuffer().size);
597 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
600 vk.cmdCopyBuffer(cmdBuffer, **m_hostBuffer, m_resource.getBuffer().handle, 1u, ©Region);
603 SyncInfo getSyncInfo (void) const
605 const VkAccessFlags access = (m_mode == ACCESS_MODE_READ ? VK_ACCESS_TRANSFER_READ_BIT : VK_ACCESS_TRANSFER_WRITE_BIT);
606 const SyncInfo syncInfo =
608 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
609 access, // VkAccessFlags accessMask;
610 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
615 Data getData (void) const
617 return getHostBufferData(m_context, *m_hostBuffer, m_resource.getBuffer().size);
621 OperationContext& m_context;
622 Resource& m_resource;
623 const AccessMode m_mode;
624 de::MovePtr<Buffer> m_hostBuffer;
627 class Support : public OperationSupport
630 Support (const ResourceDescription& resourceDesc, const AccessMode mode)
633 DE_ASSERT(resourceDesc.type == RESOURCE_TYPE_BUFFER);
634 DE_UNREF(resourceDesc);
637 deUint32 getResourceUsageFlags (void) const
639 return (m_mode == ACCESS_MODE_READ ? VK_BUFFER_USAGE_TRANSFER_SRC_BIT : VK_BUFFER_USAGE_TRANSFER_DST_BIT);
642 VkQueueFlags getQueueFlags (void) const
644 return VK_QUEUE_TRANSFER_BIT;
647 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
649 return de::MovePtr<Operation>(new Implementation(context, resource, m_mode));
653 const AccessMode m_mode;
658 namespace CopyBlitImage
661 class ImplementationBase : public Operation
664 //! Copy/Blit/Resolve etc. operation
665 virtual void recordCopyCommand (const VkCommandBuffer cmdBuffer) = 0;
667 ImplementationBase (OperationContext& context, Resource& resource, const AccessMode mode)
668 : m_context (context)
669 , m_resource (resource)
671 , m_bufferSize (getPixelBufferSize(m_resource.getImage().format, m_resource.getImage().extent))
673 const DeviceInterface& vk = m_context.getDeviceInterface();
674 const VkDevice device = m_context.getDevice();
675 Allocator& allocator = m_context.getAllocator();
677 m_hostBuffer = de::MovePtr<Buffer>(new Buffer(
678 vk, device, allocator, makeBufferCreateInfo(m_bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT),
679 MemoryRequirement::HostVisible));
681 const Allocation& alloc = m_hostBuffer->getAllocation();
682 if (m_mode == ACCESS_MODE_READ)
683 deMemset(alloc.getHostPtr(), 0, static_cast<size_t>(m_bufferSize));
685 fillPattern(alloc.getHostPtr(), m_bufferSize);
686 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), m_bufferSize);
689 m_image = de::MovePtr<Image>(new Image(
690 vk, device, allocator,
691 makeImageCreateInfo(m_resource.getImage().imageType, m_resource.getImage().extent, m_resource.getImage().format, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT),
692 MemoryRequirement::Any));
695 void recordCommands (const VkCommandBuffer cmdBuffer)
697 const DeviceInterface& vk = m_context.getDeviceInterface();
698 const VkBufferImageCopy bufferCopyRegion = makeBufferImageCopy(m_resource.getImage().subresourceLayers, m_resource.getImage().extent);
700 const VkImageMemoryBarrier stagingImageTransferSrcLayoutBarrier = makeImageMemoryBarrier(
701 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
702 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
703 **m_image, m_resource.getImage().subresourceRange);
705 // Staging image layout
707 const VkImageMemoryBarrier layoutBarrier = makeImageMemoryBarrier(
708 (VkAccessFlags)0, VK_ACCESS_TRANSFER_WRITE_BIT,
709 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
710 **m_image, m_resource.getImage().subresourceRange);
712 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
713 0u, DE_NULL, 0u, DE_NULL, 1u, &layoutBarrier);
716 if (m_mode == ACCESS_MODE_READ)
718 // Resource Image -> Staging image
719 recordCopyCommand(cmdBuffer);
721 // Staging image layout
722 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
723 0u, DE_NULL, 0u, DE_NULL, 1u, &stagingImageTransferSrcLayoutBarrier);
725 // Image -> Host buffer
726 vk.cmdCopyImageToBuffer(cmdBuffer, **m_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_hostBuffer, 1u, &bufferCopyRegion);
728 // Insert a barrier so copied data is available to the host
729 const VkBufferMemoryBarrier barrier = makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, **m_hostBuffer, 0u, m_bufferSize);
730 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
734 // Host buffer -> Staging image
735 vk.cmdCopyBufferToImage(cmdBuffer, **m_hostBuffer, **m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &bufferCopyRegion);
737 // Staging image layout
738 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
739 0u, DE_NULL, 0u, DE_NULL, 1u, &stagingImageTransferSrcLayoutBarrier);
741 // Resource image layout
743 const VkImageMemoryBarrier layoutBarrier = makeImageMemoryBarrier(
744 (VkAccessFlags)0, VK_ACCESS_TRANSFER_WRITE_BIT,
745 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
746 m_resource.getImage().handle, m_resource.getImage().subresourceRange);
748 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
749 0u, DE_NULL, 0u, DE_NULL, 1u, &layoutBarrier);
752 // Staging image -> Resource Image
753 recordCopyCommand(cmdBuffer);
757 SyncInfo getSyncInfo (void) const
759 const VkAccessFlags access = (m_mode == ACCESS_MODE_READ ? VK_ACCESS_TRANSFER_READ_BIT : VK_ACCESS_TRANSFER_WRITE_BIT);
760 const VkImageLayout layout = (m_mode == ACCESS_MODE_READ ? VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL : VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
761 const SyncInfo syncInfo =
763 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
764 access, // VkAccessFlags accessMask;
765 layout, // VkImageLayout imageLayout;
770 Data getData (void) const
772 return getHostBufferData(m_context, *m_hostBuffer, m_bufferSize);
776 OperationContext& m_context;
777 Resource& m_resource;
778 const AccessMode m_mode;
779 const VkDeviceSize m_bufferSize;
780 de::MovePtr<Buffer> m_hostBuffer;
781 de::MovePtr<Image> m_image;
784 VkOffset3D makeExtentOffset (const Resource& resource)
786 DE_ASSERT(resource.getType() == RESOURCE_TYPE_IMAGE);
787 const VkExtent3D extent = resource.getImage().extent;
789 switch (resource.getImage().imageType)
791 case VK_IMAGE_TYPE_1D: return makeOffset3D(extent.width, 1, 1);
792 case VK_IMAGE_TYPE_2D: return makeOffset3D(extent.width, extent.height, 1);
793 case VK_IMAGE_TYPE_3D: return makeOffset3D(extent.width, extent.height, extent.depth);
800 VkImageBlit makeBlitRegion (const Resource& resource)
802 const VkImageBlit blitRegion =
804 resource.getImage().subresourceLayers, // VkImageSubresourceLayers srcSubresource;
805 { makeOffset3D(0, 0, 0), makeExtentOffset(resource) }, // VkOffset3D srcOffsets[2];
806 resource.getImage().subresourceLayers, // VkImageSubresourceLayers dstSubresource;
807 { makeOffset3D(0, 0, 0), makeExtentOffset(resource) }, // VkOffset3D dstOffsets[2];
812 class BlitImplementation : public ImplementationBase
815 BlitImplementation (OperationContext& context, Resource& resource, const AccessMode mode)
816 : ImplementationBase (context, resource, mode)
817 , m_blitRegion (makeBlitRegion(m_resource))
819 const InstanceInterface& vki = m_context.getInstanceInterface();
820 const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
821 const VkFormatProperties formatProps = getPhysicalDeviceFormatProperties(vki, physDevice, m_resource.getImage().format);
822 const VkFormatFeatureFlags requiredFlags = (VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT);
824 // SRC and DST blit is required because both images are using the same format.
825 if ((formatProps.optimalTilingFeatures & requiredFlags) != requiredFlags)
826 TCU_THROW(NotSupportedError, "Format doesn't support blits");
829 void recordCopyCommand (const VkCommandBuffer cmdBuffer)
831 const DeviceInterface& vk = m_context.getDeviceInterface();
833 if (m_mode == ACCESS_MODE_READ)
835 // Resource Image -> Staging image
836 vk.cmdBlitImage(cmdBuffer, m_resource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
837 1u, &m_blitRegion, VK_FILTER_NEAREST);
841 // Staging image -> Resource Image
842 vk.cmdBlitImage(cmdBuffer, **m_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_resource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
843 1u, &m_blitRegion, VK_FILTER_NEAREST);
848 const VkImageBlit m_blitRegion;
851 VkImageCopy makeImageCopyRegion (const Resource& resource)
853 const VkImageCopy imageCopyRegion =
855 resource.getImage().subresourceLayers, // VkImageSubresourceLayers srcSubresource;
856 makeOffset3D(0, 0, 0), // VkOffset3D srcOffset;
857 resource.getImage().subresourceLayers, // VkImageSubresourceLayers dstSubresource;
858 makeOffset3D(0, 0, 0), // VkOffset3D dstOffset;
859 resource.getImage().extent, // VkExtent3D extent;
861 return imageCopyRegion;
864 class CopyImplementation : public ImplementationBase
867 CopyImplementation (OperationContext& context, Resource& resource, const AccessMode mode)
868 : ImplementationBase (context, resource, mode)
869 , m_imageCopyRegion (makeImageCopyRegion(m_resource))
873 void recordCopyCommand (const VkCommandBuffer cmdBuffer)
875 const DeviceInterface& vk = m_context.getDeviceInterface();
877 if (m_mode == ACCESS_MODE_READ)
879 // Resource Image -> Staging image
880 vk.cmdCopyImage(cmdBuffer, m_resource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &m_imageCopyRegion);
884 // Staging image -> Resource Image
885 vk.cmdCopyImage(cmdBuffer, **m_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_resource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &m_imageCopyRegion);
890 const VkImageCopy m_imageCopyRegion;
899 class Support : public OperationSupport
902 Support (const ResourceDescription& resourceDesc, const Type type, const AccessMode mode)
906 DE_ASSERT(resourceDesc.type == RESOURCE_TYPE_IMAGE);
908 const bool isDepthStencil = isDepthStencilFormat(resourceDesc.imageFormat);
909 m_requiredQueueFlags = (isDepthStencil || m_type == TYPE_BLIT ? VK_QUEUE_GRAPHICS_BIT : VK_QUEUE_TRANSFER_BIT);
911 // Don't blit depth/stencil images.
912 DE_ASSERT(m_type != TYPE_BLIT || !isDepthStencil);
915 deUint32 getResourceUsageFlags (void) const
917 return (m_mode == ACCESS_MODE_READ ? VK_BUFFER_USAGE_TRANSFER_SRC_BIT : VK_BUFFER_USAGE_TRANSFER_DST_BIT);
920 VkQueueFlags getQueueFlags (void) const
922 return m_requiredQueueFlags;
925 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
927 if (m_type == TYPE_COPY)
928 return de::MovePtr<Operation>(new CopyImplementation(context, resource, m_mode));
930 return de::MovePtr<Operation>(new BlitImplementation(context, resource, m_mode));
935 const AccessMode m_mode;
936 VkQueueFlags m_requiredQueueFlags;
939 } // CopyBlitImage ns
941 namespace ShaderAccess
946 DISPATCH_CALL_DISPATCH,
947 DISPATCH_CALL_DISPATCH_INDIRECT,
950 class GraphicsPipeline : public Pipeline
953 GraphicsPipeline (OperationContext& context, const VkShaderStageFlagBits stage, const std::string& shaderPrefix, const VkDescriptorSetLayout descriptorSetLayout)
954 : m_vertices (context)
956 const DeviceInterface& vk = context.getDeviceInterface();
957 const VkDevice device = context.getDevice();
958 Allocator& allocator = context.getAllocator();
959 const VkShaderStageFlags requiredStages = getRequiredStages(stage);
963 m_colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
964 m_colorImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
965 m_colorImageExtent = makeExtent3D(16u, 16u, 1u);
966 m_colorAttachmentImage = de::MovePtr<Image>(new Image(vk, device, allocator,
967 makeImageCreateInfo(VK_IMAGE_TYPE_2D, m_colorImageExtent, m_colorFormat, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT),
968 MemoryRequirement::Any));
972 m_colorAttachmentView = makeImageView (vk, device, **m_colorAttachmentImage, VK_IMAGE_VIEW_TYPE_2D, m_colorFormat, m_colorImageSubresourceRange);
973 m_renderPass = makeRenderPass (vk, device, m_colorFormat);
974 m_framebuffer = makeFramebuffer (vk, device, *m_renderPass, *m_colorAttachmentView, m_colorImageExtent.width, m_colorImageExtent.height, 1u);
975 m_pipelineLayout = makePipelineLayout(vk, device, descriptorSetLayout);
977 GraphicsPipelineBuilder pipelineBuilder;
979 .setRenderSize (tcu::IVec2(m_colorImageExtent.width, m_colorImageExtent.height))
980 .setVertexInputSingleAttribute (m_vertices.getVertexFormat(), m_vertices.getVertexStride())
981 .setShader (vk, device, VK_SHADER_STAGE_VERTEX_BIT, context.getBinaryCollection().get(shaderPrefix + "vert"), DE_NULL)
982 .setShader (vk, device, VK_SHADER_STAGE_FRAGMENT_BIT, context.getBinaryCollection().get(shaderPrefix + "frag"), DE_NULL);
984 if (requiredStages & (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT))
986 .setPatchControlPoints (m_vertices.getNumVertices())
987 .setShader (vk, device, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, context.getBinaryCollection().get(shaderPrefix + "tesc"), DE_NULL)
988 .setShader (vk, device, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, context.getBinaryCollection().get(shaderPrefix + "tese"), DE_NULL);
990 if (requiredStages & VK_SHADER_STAGE_GEOMETRY_BIT)
992 .setShader (vk, device, VK_SHADER_STAGE_GEOMETRY_BIT, context.getBinaryCollection().get(shaderPrefix + "geom"), DE_NULL);
994 m_pipeline = pipelineBuilder.build(vk, device, *m_pipelineLayout, *m_renderPass, context.getPipelineCacheData());
997 void recordCommands (OperationContext& context, const VkCommandBuffer cmdBuffer, const VkDescriptorSet descriptorSet)
999 const DeviceInterface& vk = context.getDeviceInterface();
1001 // Change color attachment image layout
1003 const VkImageMemoryBarrier colorAttachmentLayoutBarrier = makeImageMemoryBarrier(
1004 (VkAccessFlags)0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1005 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
1006 **m_colorAttachmentImage, m_colorImageSubresourceRange);
1008 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0,
1009 0u, DE_NULL, 0u, DE_NULL, 1u, &colorAttachmentLayoutBarrier);
1013 const VkRect2D renderArea = {
1015 makeExtent2D(m_colorImageExtent.width, m_colorImageExtent.height),
1017 const tcu::Vec4 clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
1019 beginRenderPass(vk, cmdBuffer, *m_renderPass, *m_framebuffer, renderArea, clearColor);
1022 vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
1023 vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &descriptorSet, 0u, DE_NULL);
1025 const VkDeviceSize vertexBufferOffset = 0ull;
1026 const VkBuffer vertexBuffer = m_vertices.getVertexBuffer();
1027 vk.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer, &vertexBufferOffset);
1030 vk.cmdDraw(cmdBuffer, m_vertices.getNumVertices(), 1u, 0u, 0u);
1031 endRenderPass(vk, cmdBuffer);
1035 const VertexGrid m_vertices;
1036 VkFormat m_colorFormat;
1037 de::MovePtr<Image> m_colorAttachmentImage;
1038 Move<VkImageView> m_colorAttachmentView;
1039 VkExtent3D m_colorImageExtent;
1040 VkImageSubresourceRange m_colorImageSubresourceRange;
1041 Move<VkRenderPass> m_renderPass;
1042 Move<VkFramebuffer> m_framebuffer;
1043 Move<VkPipelineLayout> m_pipelineLayout;
1044 Move<VkPipeline> m_pipeline;
1047 class ComputePipeline : public Pipeline
1050 ComputePipeline (OperationContext& context, const DispatchCall dispatchCall, const std::string& shaderPrefix, const VkDescriptorSetLayout descriptorSetLayout)
1051 : m_dispatchCall (dispatchCall)
1053 const DeviceInterface& vk = context.getDeviceInterface();
1054 const VkDevice device = context.getDevice();
1055 Allocator& allocator = context.getAllocator();
1057 if (m_dispatchCall == DISPATCH_CALL_DISPATCH_INDIRECT)
1059 m_indirectBuffer = de::MovePtr<Buffer>(new Buffer(vk, device, allocator,
1060 makeBufferCreateInfo(sizeof(VkDispatchIndirectCommand), VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT), MemoryRequirement::HostVisible));
1062 const Allocation& alloc = m_indirectBuffer->getAllocation();
1063 VkDispatchIndirectCommand* const pIndirectCommand = static_cast<VkDispatchIndirectCommand*>(alloc.getHostPtr());
1065 pIndirectCommand->x = 1u;
1066 pIndirectCommand->y = 1u;
1067 pIndirectCommand->z = 1u;
1069 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), sizeof(VkDispatchIndirectCommand));
1072 const Unique<VkShaderModule> shaderModule(createShaderModule(vk, device, context.getBinaryCollection().get(shaderPrefix + "comp"), (VkShaderModuleCreateFlags)0));
1074 m_pipelineLayout = makePipelineLayout(vk, device, descriptorSetLayout);
1075 m_pipeline = makeComputePipeline(vk, device, *m_pipelineLayout, *shaderModule, DE_NULL, context.getPipelineCacheData());
1078 void recordCommands (OperationContext& context, const VkCommandBuffer cmdBuffer, const VkDescriptorSet descriptorSet)
1080 const DeviceInterface& vk = context.getDeviceInterface();
1082 vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipeline);
1083 vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0u, 1u, &descriptorSet, 0u, DE_NULL);
1085 if (m_dispatchCall == DISPATCH_CALL_DISPATCH_INDIRECT)
1086 vk.cmdDispatchIndirect(cmdBuffer, **m_indirectBuffer, 0u);
1088 vk.cmdDispatch(cmdBuffer, 1u, 1u, 1u);
1092 const DispatchCall m_dispatchCall;
1093 de::MovePtr<Buffer> m_indirectBuffer;
1094 Move<VkPipelineLayout> m_pipelineLayout;
1095 Move<VkPipeline> m_pipeline;
1098 //! Read/write operation on a UBO/SSBO in graphics/compute pipeline.
1099 class BufferImplementation : public Operation
1102 BufferImplementation (OperationContext& context,
1104 const VkShaderStageFlagBits stage,
1105 const BufferType bufferType,
1106 const std::string& shaderPrefix,
1107 const AccessMode mode,
1108 const PipelineType pipelineType,
1109 const DispatchCall dispatchCall)
1110 : m_context (context)
1111 , m_resource (resource)
1113 , m_pipelineStage (pipelineStageFlagsFromShaderStageFlagBits(m_stage))
1114 , m_bufferType (bufferType)
1116 , m_dispatchCall (dispatchCall)
1118 requireFeaturesForSSBOAccess (m_context, m_stage);
1120 const DeviceInterface& vk = m_context.getDeviceInterface();
1121 const VkDevice device = m_context.getDevice();
1122 Allocator& allocator = m_context.getAllocator();
1124 m_hostBuffer = de::MovePtr<Buffer>(new Buffer(
1125 vk, device, allocator, makeBufferCreateInfo(m_resource.getBuffer().size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible));
1127 // Init host buffer data
1129 const Allocation& alloc = m_hostBuffer->getAllocation();
1130 if (m_mode == ACCESS_MODE_READ)
1131 deMemset(alloc.getHostPtr(), 0, static_cast<size_t>(m_resource.getBuffer().size));
1133 fillPattern(alloc.getHostPtr(), m_resource.getBuffer().size);
1134 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), m_resource.getBuffer().size);
1137 // Prepare descriptors
1139 const VkDescriptorType bufferDescriptorType = (m_bufferType == BUFFER_TYPE_UNIFORM ? VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER : VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
1141 m_descriptorSetLayout = DescriptorSetLayoutBuilder()
1142 .addSingleBinding(bufferDescriptorType, m_stage)
1143 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, m_stage)
1146 m_descriptorPool = DescriptorPoolBuilder()
1147 .addType(bufferDescriptorType)
1148 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
1149 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1151 m_descriptorSet = makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout);
1153 const VkDescriptorBufferInfo bufferInfo = makeDescriptorBufferInfo(m_resource.getBuffer().handle, m_resource.getBuffer().offset, m_resource.getBuffer().size);
1154 const VkDescriptorBufferInfo hostBufferInfo = makeDescriptorBufferInfo(**m_hostBuffer, 0u, m_resource.getBuffer().size);
1156 if (m_mode == ACCESS_MODE_READ)
1158 DescriptorSetUpdateBuilder()
1159 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), bufferDescriptorType, &bufferInfo)
1160 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &hostBufferInfo)
1161 .update(vk, device);
1165 DescriptorSetUpdateBuilder()
1166 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &hostBufferInfo)
1167 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufferInfo)
1168 .update(vk, device);
1173 m_pipeline = (pipelineType == PIPELINE_TYPE_GRAPHICS ? de::MovePtr<Pipeline>(new GraphicsPipeline(context, stage, shaderPrefix, *m_descriptorSetLayout))
1174 : de::MovePtr<Pipeline>(new ComputePipeline(context, m_dispatchCall, shaderPrefix, *m_descriptorSetLayout)));
1177 void recordCommands (const VkCommandBuffer cmdBuffer)
1179 m_pipeline->recordCommands(m_context, cmdBuffer, *m_descriptorSet);
1181 // Post draw/dispatch commands
1183 if (m_mode == ACCESS_MODE_READ)
1185 const DeviceInterface& vk = m_context.getDeviceInterface();
1187 // Insert a barrier so data written by the shader is available to the host
1188 const VkBufferMemoryBarrier barrier = makeBufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, **m_hostBuffer, 0u, m_resource.getBuffer().size);
1189 vk.cmdPipelineBarrier(cmdBuffer, m_pipelineStage, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
1193 SyncInfo getSyncInfo (void) const
1195 const VkAccessFlags accessFlags = (m_mode == ACCESS_MODE_READ ? (m_bufferType == BUFFER_TYPE_UNIFORM ? VK_ACCESS_UNIFORM_READ_BIT
1196 : VK_ACCESS_SHADER_READ_BIT)
1197 : VK_ACCESS_SHADER_WRITE_BIT);
1198 const SyncInfo syncInfo =
1200 m_pipelineStage, // VkPipelineStageFlags stageMask;
1201 accessFlags, // VkAccessFlags accessMask;
1202 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
1207 Data getData (void) const
1209 return getHostBufferData(m_context, *m_hostBuffer, m_resource.getBuffer().size);
1213 OperationContext& m_context;
1214 Resource& m_resource;
1215 const VkShaderStageFlagBits m_stage;
1216 const VkPipelineStageFlags m_pipelineStage;
1217 const BufferType m_bufferType;
1218 const AccessMode m_mode;
1219 const DispatchCall m_dispatchCall;
1220 de::MovePtr<Buffer> m_hostBuffer;
1221 Move<VkDescriptorPool> m_descriptorPool;
1222 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
1223 Move<VkDescriptorSet> m_descriptorSet;
1224 de::MovePtr<Pipeline> m_pipeline;
1227 class ImageImplementation : public Operation
1230 ImageImplementation (OperationContext& context,
1232 const VkShaderStageFlagBits stage,
1233 const std::string& shaderPrefix,
1234 const AccessMode mode,
1235 const PipelineType pipelineType,
1236 const DispatchCall dispatchCall)
1237 : m_context (context)
1238 , m_resource (resource)
1240 , m_pipelineStage (pipelineStageFlagsFromShaderStageFlagBits(m_stage))
1242 , m_dispatchCall (dispatchCall)
1243 , m_hostBufferSizeBytes (getPixelBufferSize(m_resource.getImage().format, m_resource.getImage().extent))
1245 const DeviceInterface& vk = m_context.getDeviceInterface();
1246 const InstanceInterface& vki = m_context.getInstanceInterface();
1247 const VkDevice device = m_context.getDevice();
1248 const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
1249 Allocator& allocator = m_context.getAllocator();
1251 // Image stores are always required, in either access mode.
1252 requireFeaturesForSSBOAccess(m_context, m_stage);
1254 // Some storage image formats require additional capability.
1255 if (isStorageImageExtendedFormat(m_resource.getImage().format))
1256 requireFeatures(vki, physDevice, FEATURE_SHADER_STORAGE_IMAGE_EXTENDED_FORMATS);
1258 m_hostBuffer = de::MovePtr<Buffer>(new Buffer(
1259 vk, device, allocator, makeBufferCreateInfo(m_hostBufferSizeBytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT),
1260 MemoryRequirement::HostVisible));
1262 // Init host buffer data
1264 const Allocation& alloc = m_hostBuffer->getAllocation();
1265 if (m_mode == ACCESS_MODE_READ)
1266 deMemset(alloc.getHostPtr(), 0, static_cast<size_t>(m_hostBufferSizeBytes));
1268 fillPattern(alloc.getHostPtr(), m_hostBufferSizeBytes);
1269 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), m_hostBufferSizeBytes);
1274 m_image = de::MovePtr<Image>(new Image(vk, device, allocator,
1275 makeImageCreateInfo(m_resource.getImage().imageType, m_resource.getImage().extent, m_resource.getImage().format,
1276 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_STORAGE_BIT),
1277 MemoryRequirement::Any));
1279 if (m_mode == ACCESS_MODE_READ)
1281 m_srcImage = &m_resource.getImage().handle;
1282 m_dstImage = &(**m_image);
1286 m_srcImage = &(**m_image);
1287 m_dstImage = &m_resource.getImage().handle;
1290 const VkImageViewType viewType = getImageViewType(m_resource.getImage().imageType);
1292 m_srcImageView = makeImageView(vk, device, *m_srcImage, viewType, m_resource.getImage().format, m_resource.getImage().subresourceRange);
1293 m_dstImageView = makeImageView(vk, device, *m_dstImage, viewType, m_resource.getImage().format, m_resource.getImage().subresourceRange);
1296 // Prepare descriptors
1298 m_descriptorSetLayout = DescriptorSetLayoutBuilder()
1299 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, m_stage)
1300 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, m_stage)
1303 m_descriptorPool = DescriptorPoolBuilder()
1304 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1305 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1306 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1308 m_descriptorSet = makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout);
1310 const VkDescriptorImageInfo srcImageInfo = makeDescriptorImageInfo(DE_NULL, *m_srcImageView, VK_IMAGE_LAYOUT_GENERAL);
1311 const VkDescriptorImageInfo dstImageInfo = makeDescriptorImageInfo(DE_NULL, *m_dstImageView, VK_IMAGE_LAYOUT_GENERAL);
1313 DescriptorSetUpdateBuilder()
1314 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &srcImageInfo)
1315 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &dstImageInfo)
1316 .update(vk, device);
1320 m_pipeline = (pipelineType == PIPELINE_TYPE_GRAPHICS ? de::MovePtr<Pipeline>(new GraphicsPipeline(context, stage, shaderPrefix, *m_descriptorSetLayout))
1321 : de::MovePtr<Pipeline>(new ComputePipeline(context, m_dispatchCall, shaderPrefix, *m_descriptorSetLayout)));
1324 void recordCommands (const VkCommandBuffer cmdBuffer)
1326 const DeviceInterface& vk = m_context.getDeviceInterface();
1327 const VkBufferImageCopy bufferCopyRegion = makeBufferImageCopy(m_resource.getImage().subresourceLayers, m_resource.getImage().extent);
1329 // Destination image layout
1331 const VkImageMemoryBarrier barrier = makeImageMemoryBarrier(
1332 (VkAccessFlags)0, VK_ACCESS_SHADER_WRITE_BIT,
1333 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
1334 *m_dstImage, m_resource.getImage().subresourceRange);
1336 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, m_pipelineStage, (VkDependencyFlags)0,
1337 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
1340 // In write mode, source image must be filled with data.
1341 if (m_mode == ACCESS_MODE_WRITE)
1343 // Layout for transfer
1345 const VkImageMemoryBarrier barrier = makeImageMemoryBarrier(
1346 (VkAccessFlags)0, VK_ACCESS_TRANSFER_WRITE_BIT,
1347 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1348 *m_srcImage, m_resource.getImage().subresourceRange);
1350 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
1351 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
1354 // Host buffer -> Src image
1355 vk.cmdCopyBufferToImage(cmdBuffer, **m_hostBuffer, *m_srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &bufferCopyRegion);
1357 // Layout for shader reading
1359 const VkImageMemoryBarrier barrier = makeImageMemoryBarrier(
1360 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT,
1361 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
1362 *m_srcImage, m_resource.getImage().subresourceRange);
1364 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, m_pipelineStage, (VkDependencyFlags)0,
1365 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
1371 m_pipeline->recordCommands(m_context, cmdBuffer, *m_descriptorSet);
1373 // Post draw/dispatch commands
1375 if (m_mode == ACCESS_MODE_READ)
1377 // Layout for transfer
1379 const VkImageMemoryBarrier barrier = makeImageMemoryBarrier(
1380 VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
1381 VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1382 *m_dstImage, m_resource.getImage().subresourceRange);
1384 vk.cmdPipelineBarrier(cmdBuffer, m_pipelineStage, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
1385 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
1388 // Dst image -> Host buffer
1389 vk.cmdCopyImageToBuffer(cmdBuffer, *m_dstImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_hostBuffer, 1u, &bufferCopyRegion);
1391 // Insert a barrier so data written by the shader is available to the host
1393 const VkBufferMemoryBarrier barrier = makeBufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, **m_hostBuffer, 0u, m_hostBufferSizeBytes);
1394 vk.cmdPipelineBarrier(cmdBuffer, m_pipelineStage, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
1399 SyncInfo getSyncInfo (void) const
1401 const VkAccessFlags accessFlags = (m_mode == ACCESS_MODE_READ ? VK_ACCESS_SHADER_READ_BIT : VK_ACCESS_SHADER_WRITE_BIT);
1402 const SyncInfo syncInfo =
1404 m_pipelineStage, // VkPipelineStageFlags stageMask;
1405 accessFlags, // VkAccessFlags accessMask;
1406 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout;
1411 Data getData (void) const
1413 return getHostBufferData(m_context, *m_hostBuffer, m_hostBufferSizeBytes);
1417 OperationContext& m_context;
1418 Resource& m_resource;
1419 const VkShaderStageFlagBits m_stage;
1420 const VkPipelineStageFlags m_pipelineStage;
1421 const AccessMode m_mode;
1422 const DispatchCall m_dispatchCall;
1423 const VkDeviceSize m_hostBufferSizeBytes;
1424 de::MovePtr<Buffer> m_hostBuffer;
1425 de::MovePtr<Image> m_image; //! Additional image used as src or dst depending on operation mode.
1426 const VkImage* m_srcImage;
1427 const VkImage* m_dstImage;
1428 Move<VkImageView> m_srcImageView;
1429 Move<VkImageView> m_dstImageView;
1430 Move<VkDescriptorPool> m_descriptorPool;
1431 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
1432 Move<VkDescriptorSet> m_descriptorSet;
1433 de::MovePtr<Pipeline> m_pipeline;
1436 //! Create generic passthrough shaders with bits of custom code inserted in a specific shader stage.
1437 void initPassthroughPrograms (SourceCollections& programCollection,
1438 const std::string& shaderPrefix,
1439 const std::string& declCode,
1440 const std::string& mainCode,
1441 const VkShaderStageFlagBits stage)
1443 const VkShaderStageFlags requiredStages = getRequiredStages(stage);
1445 if (requiredStages & VK_SHADER_STAGE_VERTEX_BIT)
1447 std::ostringstream src;
1448 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
1450 << "layout(location = 0) in vec4 v_in_position;\n"
1452 << "out " << s_perVertexBlock << ";\n"
1454 << (stage & VK_SHADER_STAGE_VERTEX_BIT ? declCode + "\n" : "")
1455 << "void main (void)\n"
1457 << " gl_Position = v_in_position;\n"
1458 << (stage & VK_SHADER_STAGE_VERTEX_BIT ? mainCode : "")
1461 programCollection.glslSources.add(shaderPrefix + "vert") << glu::VertexSource(src.str());
1464 if (requiredStages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
1466 std::ostringstream src;
1467 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
1469 << "layout(vertices = 3) out;\n"
1471 << "in " << s_perVertexBlock << " gl_in[gl_MaxPatchVertices];\n"
1473 << "out " << s_perVertexBlock << " gl_out[];\n"
1475 << (stage & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ? declCode + "\n" : "")
1476 << "void main (void)\n"
1478 << " gl_TessLevelInner[0] = 1.0;\n"
1479 << " gl_TessLevelInner[1] = 1.0;\n"
1481 << " gl_TessLevelOuter[0] = 1.0;\n"
1482 << " gl_TessLevelOuter[1] = 1.0;\n"
1483 << " gl_TessLevelOuter[2] = 1.0;\n"
1484 << " gl_TessLevelOuter[3] = 1.0;\n"
1486 << " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1487 << (stage & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ? "\n" + mainCode : "")
1490 programCollection.glslSources.add(shaderPrefix + "tesc") << glu::TessellationControlSource(src.str());
1493 if (requiredStages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
1495 std::ostringstream src;
1496 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
1498 << "layout(triangles, equal_spacing, ccw) in;\n"
1500 << "in " << s_perVertexBlock << " gl_in[gl_MaxPatchVertices];\n"
1502 << "out " << s_perVertexBlock << ";\n"
1504 << (stage & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT ? declCode + "\n" : "")
1505 << "void main (void)\n"
1507 << " vec3 px = gl_TessCoord.x * gl_in[0].gl_Position.xyz;\n"
1508 << " vec3 py = gl_TessCoord.y * gl_in[1].gl_Position.xyz;\n"
1509 << " vec3 pz = gl_TessCoord.z * gl_in[2].gl_Position.xyz;\n"
1510 << " gl_Position = vec4(px + py + pz, 1.0);\n"
1511 << (stage & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT ? mainCode : "")
1514 programCollection.glslSources.add(shaderPrefix + "tese") << glu::TessellationEvaluationSource(src.str());
1517 if (requiredStages & VK_SHADER_STAGE_GEOMETRY_BIT)
1519 std::ostringstream src;
1520 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
1522 << "layout(triangles) in;\n"
1523 << "layout(triangle_strip, max_vertices = 3) out;\n"
1525 << "in " << s_perVertexBlock << " gl_in[];\n"
1527 << "out " << s_perVertexBlock << ";\n"
1529 << (stage & VK_SHADER_STAGE_GEOMETRY_BIT ? declCode + "\n" : "")
1530 << "void main (void)\n"
1532 << " gl_Position = gl_in[0].gl_Position;\n"
1533 << " EmitVertex();\n"
1535 << " gl_Position = gl_in[1].gl_Position;\n"
1536 << " EmitVertex();\n"
1538 << " gl_Position = gl_in[2].gl_Position;\n"
1539 << " EmitVertex();\n"
1540 << (stage & VK_SHADER_STAGE_GEOMETRY_BIT ? "\n" + mainCode : "")
1543 programCollection.glslSources.add(shaderPrefix + "geom") << glu::GeometrySource(src.str());
1546 if (requiredStages & VK_SHADER_STAGE_FRAGMENT_BIT)
1548 std::ostringstream src;
1549 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
1551 << "layout(location = 0) out vec4 o_color;\n"
1553 << (stage & VK_SHADER_STAGE_FRAGMENT_BIT ? declCode + "\n" : "")
1554 << "void main (void)\n"
1556 << " o_color = vec4(1.0);\n"
1557 << (stage & VK_SHADER_STAGE_FRAGMENT_BIT ? "\n" + mainCode : "")
1560 programCollection.glslSources.add(shaderPrefix + "frag") << glu::FragmentSource(src.str());
1563 if (requiredStages & VK_SHADER_STAGE_COMPUTE_BIT)
1565 std::ostringstream src;
1566 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
1568 << "layout(local_size_x = 1) in;\n"
1570 << (stage & VK_SHADER_STAGE_COMPUTE_BIT ? declCode + "\n" : "")
1571 << "void main (void)\n"
1573 << (stage & VK_SHADER_STAGE_COMPUTE_BIT ? mainCode : "")
1576 programCollection.glslSources.add(shaderPrefix + "comp") << glu::ComputeSource(src.str());
1580 class BufferSupport : public OperationSupport
1583 BufferSupport (const ResourceDescription& resourceDesc,
1584 const BufferType bufferType,
1585 const AccessMode mode,
1586 const VkShaderStageFlagBits stage,
1587 const DispatchCall dispatchCall = DISPATCH_CALL_DISPATCH)
1588 : m_resourceDesc (resourceDesc)
1589 , m_bufferType (bufferType)
1592 , m_shaderPrefix (std::string(m_mode == ACCESS_MODE_READ ? "read_" : "write_") + (m_bufferType == BUFFER_TYPE_UNIFORM ? "ubo_" : "ssbo_"))
1593 , m_dispatchCall (dispatchCall)
1595 DE_ASSERT(m_resourceDesc.type == RESOURCE_TYPE_BUFFER);
1596 DE_ASSERT(m_bufferType == BUFFER_TYPE_UNIFORM || m_bufferType == BUFFER_TYPE_STORAGE);
1597 DE_ASSERT(m_mode == ACCESS_MODE_READ || m_mode == ACCESS_MODE_WRITE);
1598 DE_ASSERT(m_mode == ACCESS_MODE_READ || m_bufferType == BUFFER_TYPE_STORAGE);
1599 DE_ASSERT(m_bufferType != BUFFER_TYPE_UNIFORM || m_resourceDesc.size.x() <= MAX_UBO_RANGE);
1600 DE_ASSERT(m_dispatchCall == DISPATCH_CALL_DISPATCH || m_dispatchCall == DISPATCH_CALL_DISPATCH_INDIRECT);
1602 assertValidShaderStage(m_stage);
1605 void initPrograms (SourceCollections& programCollection) const
1607 DE_ASSERT((m_resourceDesc.size.x() % sizeof(tcu::UVec4)) == 0);
1609 const std::string bufferTypeStr = (m_bufferType == BUFFER_TYPE_UNIFORM ? "uniform" : "buffer");
1610 const int numVecElements = static_cast<int>(m_resourceDesc.size.x() / sizeof(tcu::UVec4)); // std140 must be aligned to a multiple of 16
1612 std::ostringstream declSrc;
1613 declSrc << "layout(set = 0, binding = 0, std140) readonly " << bufferTypeStr << " Input {\n"
1614 << " uvec4 data[" << numVecElements << "];\n"
1617 << "layout(set = 0, binding = 1, std140) writeonly buffer Output {\n"
1618 << " uvec4 data[" << numVecElements << "];\n"
1621 std::ostringstream copySrc;
1622 copySrc << " for (int i = 0; i < " << numVecElements << "; ++i) {\n"
1623 << " b_out.data[i] = b_in.data[i];\n"
1626 initPassthroughPrograms(programCollection, m_shaderPrefix, declSrc.str(), copySrc.str(), m_stage);
1629 deUint32 getResourceUsageFlags (void) const
1631 return (m_bufferType == BUFFER_TYPE_UNIFORM ? VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT : VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1634 VkQueueFlags getQueueFlags (void) const
1636 return (m_stage == VK_SHADER_STAGE_COMPUTE_BIT ? VK_QUEUE_COMPUTE_BIT : VK_QUEUE_GRAPHICS_BIT);
1639 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
1641 if (m_stage & VK_SHADER_STAGE_COMPUTE_BIT)
1642 return de::MovePtr<Operation>(new BufferImplementation(context, resource, m_stage, m_bufferType, m_shaderPrefix, m_mode, PIPELINE_TYPE_COMPUTE, m_dispatchCall));
1644 return de::MovePtr<Operation>(new BufferImplementation(context, resource, m_stage, m_bufferType, m_shaderPrefix, m_mode, PIPELINE_TYPE_GRAPHICS, m_dispatchCall));
1648 const ResourceDescription m_resourceDesc;
1649 const BufferType m_bufferType;
1650 const AccessMode m_mode;
1651 const VkShaderStageFlagBits m_stage;
1652 const std::string m_shaderPrefix;
1653 const DispatchCall m_dispatchCall;
1656 class ImageSupport : public OperationSupport
1659 ImageSupport (const ResourceDescription& resourceDesc,
1660 const AccessMode mode,
1661 const VkShaderStageFlagBits stage,
1662 const DispatchCall dispatchCall = DISPATCH_CALL_DISPATCH)
1663 : m_resourceDesc (resourceDesc)
1666 , m_shaderPrefix (m_mode == ACCESS_MODE_READ ? "read_image_" : "write_image_")
1667 , m_dispatchCall (dispatchCall)
1669 DE_ASSERT(m_resourceDesc.type == RESOURCE_TYPE_IMAGE);
1670 DE_ASSERT(m_mode == ACCESS_MODE_READ || m_mode == ACCESS_MODE_WRITE);
1671 DE_ASSERT(m_dispatchCall == DISPATCH_CALL_DISPATCH || m_dispatchCall == DISPATCH_CALL_DISPATCH_INDIRECT);
1673 assertValidShaderStage(m_stage);
1676 void initPrograms (SourceCollections& programCollection) const
1678 const std::string imageFormat = getShaderImageFormatQualifier(m_resourceDesc.imageFormat);
1679 const std::string imageType = getShaderImageType(m_resourceDesc.imageFormat, m_resourceDesc.imageType);
1681 std::ostringstream declSrc;
1682 declSrc << "layout(set = 0, binding = 0, " << imageFormat << ") readonly uniform " << imageType << " srcImg;\n"
1683 << "layout(set = 0, binding = 1, " << imageFormat << ") writeonly uniform " << imageType << " dstImg;\n";
1685 std::ostringstream mainSrc;
1686 if (m_resourceDesc.imageType == VK_IMAGE_TYPE_1D)
1687 mainSrc << " for (int x = 0; x < " << m_resourceDesc.size.x() << "; ++x)\n"
1688 << " imageStore(dstImg, x, imageLoad(srcImg, x));\n";
1689 else if (m_resourceDesc.imageType == VK_IMAGE_TYPE_2D)
1690 mainSrc << " for (int y = 0; y < " << m_resourceDesc.size.y() << "; ++y)\n"
1691 << " for (int x = 0; x < " << m_resourceDesc.size.x() << "; ++x)\n"
1692 << " imageStore(dstImg, ivec2(x, y), imageLoad(srcImg, ivec2(x, y)));\n";
1693 else if (m_resourceDesc.imageType == VK_IMAGE_TYPE_3D)
1694 mainSrc << " for (int z = 0; z < " << m_resourceDesc.size.z() << "; ++z)\n"
1695 << " for (int y = 0; y < " << m_resourceDesc.size.y() << "; ++y)\n"
1696 << " for (int x = 0; x < " << m_resourceDesc.size.x() << "; ++x)\n"
1697 << " imageStore(dstImg, ivec3(x, y, z), imageLoad(srcImg, ivec3(x, y, z)));\n";
1701 initPassthroughPrograms(programCollection, m_shaderPrefix, declSrc.str(), mainSrc.str(), m_stage);
1704 deUint32 getResourceUsageFlags (void) const
1706 return VK_IMAGE_USAGE_STORAGE_BIT;
1709 VkQueueFlags getQueueFlags (void) const
1711 return (m_stage == VK_SHADER_STAGE_COMPUTE_BIT ? VK_QUEUE_COMPUTE_BIT : VK_QUEUE_GRAPHICS_BIT);
1714 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
1716 if (m_stage & VK_SHADER_STAGE_COMPUTE_BIT)
1717 return de::MovePtr<Operation>(new ImageImplementation(context, resource, m_stage, m_shaderPrefix, m_mode, PIPELINE_TYPE_COMPUTE, m_dispatchCall));
1719 return de::MovePtr<Operation>(new ImageImplementation(context, resource, m_stage, m_shaderPrefix, m_mode, PIPELINE_TYPE_GRAPHICS, m_dispatchCall));
1723 const ResourceDescription m_resourceDesc;
1724 const AccessMode m_mode;
1725 const VkShaderStageFlagBits m_stage;
1726 const std::string m_shaderPrefix;
1727 const DispatchCall m_dispatchCall;
1730 } // ShaderAccess ns
1732 namespace CopyBufferToImage
1735 class WriteImplementation : public Operation
1738 WriteImplementation (OperationContext& context, Resource& resource)
1739 : m_context (context)
1740 , m_resource (resource)
1741 , m_bufferSize (getPixelBufferSize(m_resource.getImage().format, m_resource.getImage().extent))
1743 DE_ASSERT(m_resource.getType() == RESOURCE_TYPE_IMAGE);
1745 const DeviceInterface& vk = m_context.getDeviceInterface();
1746 const VkDevice device = m_context.getDevice();
1747 Allocator& allocator = m_context.getAllocator();
1749 m_hostBuffer = de::MovePtr<Buffer>(new Buffer(
1750 vk, device, allocator, makeBufferCreateInfo(m_bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT), MemoryRequirement::HostVisible));
1752 const Allocation& alloc = m_hostBuffer->getAllocation();
1753 fillPattern(alloc.getHostPtr(), m_bufferSize);
1754 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), m_bufferSize);
1757 void recordCommands (const VkCommandBuffer cmdBuffer)
1759 const DeviceInterface& vk = m_context.getDeviceInterface();
1760 const VkBufferImageCopy copyRegion = makeBufferImageCopy(m_resource.getImage().subresourceLayers, m_resource.getImage().extent);
1762 const VkImageMemoryBarrier layoutBarrier = makeImageMemoryBarrier(
1763 (VkAccessFlags)0, VK_ACCESS_TRANSFER_WRITE_BIT,
1764 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1765 m_resource.getImage().handle, m_resource.getImage().subresourceRange);
1766 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 0u, DE_NULL, 1u, &layoutBarrier);
1768 vk.cmdCopyBufferToImage(cmdBuffer, **m_hostBuffer, m_resource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ©Region);
1771 SyncInfo getSyncInfo (void) const
1773 const SyncInfo syncInfo =
1775 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
1776 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags accessMask;
1777 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout imageLayout;
1782 Data getData (void) const
1784 return getHostBufferData(m_context, *m_hostBuffer, m_bufferSize);
1788 OperationContext& m_context;
1789 Resource& m_resource;
1790 de::MovePtr<Buffer> m_hostBuffer;
1791 const VkDeviceSize m_bufferSize;
1794 class ReadImplementation : public Operation
1797 ReadImplementation (OperationContext& context, Resource& resource)
1798 : m_context (context)
1799 , m_resource (resource)
1800 , m_subresourceRange (makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u))
1801 , m_subresourceLayers (makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u))
1803 DE_ASSERT(m_resource.getType() == RESOURCE_TYPE_BUFFER);
1805 const DeviceInterface& vk = m_context.getDeviceInterface();
1806 const VkDevice device = m_context.getDevice();
1807 Allocator& allocator = m_context.getAllocator();
1808 const VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
1809 const deUint32 pixelSize = tcu::getPixelSize(mapVkFormat(format));
1811 DE_ASSERT((m_resource.getBuffer().size % pixelSize) == 0);
1812 m_imageExtent = get2DImageExtentWithSize(m_resource.getBuffer().size, pixelSize); // there may be some unused space at the end
1814 // Copy destination image.
1815 m_image = de::MovePtr<Image>(new Image(
1816 vk, device, allocator, makeImageCreateInfo(VK_IMAGE_TYPE_2D, m_imageExtent, format, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT), MemoryRequirement::Any));
1818 // Image data will be copied here, so it can be read on the host.
1819 m_hostBuffer = de::MovePtr<Buffer>(new Buffer(
1820 vk, device, allocator, makeBufferCreateInfo(m_resource.getBuffer().size, VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible));
1823 void recordCommands (const VkCommandBuffer cmdBuffer)
1825 const DeviceInterface& vk = m_context.getDeviceInterface();
1826 const VkBufferImageCopy copyRegion = makeBufferImageCopy(m_subresourceLayers, m_imageExtent);
1828 // Resource -> Image
1830 const VkImageMemoryBarrier layoutBarrier = makeImageMemoryBarrier(
1831 (VkAccessFlags)0, VK_ACCESS_TRANSFER_WRITE_BIT,
1832 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1833 **m_image, m_subresourceRange);
1834 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 0u, DE_NULL, 1u, &layoutBarrier);
1836 vk.cmdCopyBufferToImage(cmdBuffer, m_resource.getBuffer().handle, **m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ©Region);
1838 // Image -> Host buffer
1840 const VkImageMemoryBarrier layoutBarrier = makeImageMemoryBarrier(
1841 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
1842 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1843 **m_image, m_subresourceRange);
1844 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 0u, DE_NULL, 1u, &layoutBarrier);
1846 vk.cmdCopyImageToBuffer(cmdBuffer, **m_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_hostBuffer, 1u, ©Region);
1848 const VkBufferMemoryBarrier barrier = makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, **m_hostBuffer, 0u, m_resource.getBuffer().size);
1849 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
1853 SyncInfo getSyncInfo (void) const
1855 const SyncInfo syncInfo =
1857 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
1858 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags accessMask;
1859 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
1864 Data getData (void) const
1866 return getHostBufferData(m_context, *m_hostBuffer, m_resource.getBuffer().size);
1870 OperationContext& m_context;
1871 Resource& m_resource;
1872 const VkImageSubresourceRange m_subresourceRange;
1873 const VkImageSubresourceLayers m_subresourceLayers;
1874 de::MovePtr<Buffer> m_hostBuffer;
1875 de::MovePtr<Image> m_image;
1876 VkExtent3D m_imageExtent;
1879 class Support : public OperationSupport
1882 Support (const ResourceDescription& resourceDesc, const AccessMode mode)
1884 , m_requiredQueueFlags (resourceDesc.type == RESOURCE_TYPE_IMAGE && isDepthStencilFormat(resourceDesc.imageFormat) ? VK_QUEUE_GRAPHICS_BIT : VK_QUEUE_TRANSFER_BIT)
1887 // Because depth or stencil aspect buffer to image copies may require format conversions on some implementations,
1888 // they are not supported on queues that do not support graphics.
1890 DE_ASSERT(m_mode == ACCESS_MODE_READ || m_mode == ACCESS_MODE_WRITE);
1891 DE_ASSERT(m_mode == ACCESS_MODE_READ || resourceDesc.type != RESOURCE_TYPE_BUFFER);
1892 DE_ASSERT(m_mode == ACCESS_MODE_WRITE || resourceDesc.type != RESOURCE_TYPE_IMAGE);
1895 deUint32 getResourceUsageFlags (void) const
1897 if (m_mode == ACCESS_MODE_READ)
1898 return VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
1900 return VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1903 VkQueueFlags getQueueFlags (void) const
1905 return m_requiredQueueFlags;
1908 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
1910 if (m_mode == ACCESS_MODE_READ)
1911 return de::MovePtr<Operation>(new ReadImplementation(context, resource));
1913 return de::MovePtr<Operation>(new WriteImplementation(context, resource));
1917 const AccessMode m_mode;
1918 const VkQueueFlags m_requiredQueueFlags;
1921 } // CopyBufferToImage ns
1923 namespace CopyImageToBuffer
1926 class WriteImplementation : public Operation
1929 WriteImplementation (OperationContext& context, Resource& resource)
1930 : m_context (context)
1931 , m_resource (resource)
1932 , m_subresourceRange (makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u))
1933 , m_subresourceLayers (makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u))
1935 DE_ASSERT(m_resource.getType() == RESOURCE_TYPE_BUFFER);
1937 const DeviceInterface& vk = m_context.getDeviceInterface();
1938 const VkDevice device = m_context.getDevice();
1939 Allocator& allocator = m_context.getAllocator();
1940 const VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
1941 const deUint32 pixelSize = tcu::getPixelSize(mapVkFormat(format));
1943 DE_ASSERT((m_resource.getBuffer().size % pixelSize) == 0);
1944 m_imageExtent = get2DImageExtentWithSize(m_resource.getBuffer().size, pixelSize);
1946 // Source data staging buffer
1947 m_hostBuffer = de::MovePtr<Buffer>(new Buffer(
1948 vk, device, allocator, makeBufferCreateInfo(m_resource.getBuffer().size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT), MemoryRequirement::HostVisible));
1950 const Allocation& alloc = m_hostBuffer->getAllocation();
1951 fillPattern(alloc.getHostPtr(), m_resource.getBuffer().size);
1952 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), m_resource.getBuffer().size);
1954 // Source data image
1955 m_image = de::MovePtr<Image>(new Image(
1956 vk, device, allocator, makeImageCreateInfo(VK_IMAGE_TYPE_2D, m_imageExtent, format, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT), MemoryRequirement::Any));
1959 void recordCommands (const VkCommandBuffer cmdBuffer)
1961 const DeviceInterface& vk = m_context.getDeviceInterface();
1962 const VkBufferImageCopy copyRegion = makeBufferImageCopy(m_subresourceLayers, m_imageExtent);
1964 // Host buffer -> Image
1966 const VkImageMemoryBarrier layoutBarrier = makeImageMemoryBarrier(
1967 (VkAccessFlags)0, VK_ACCESS_TRANSFER_WRITE_BIT,
1968 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1969 **m_image, m_subresourceRange);
1970 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 0u, DE_NULL, 1u, &layoutBarrier);
1972 vk.cmdCopyBufferToImage(cmdBuffer, **m_hostBuffer, **m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ©Region);
1974 // Image -> Resource
1976 const VkImageMemoryBarrier layoutBarrier = makeImageMemoryBarrier(
1977 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
1978 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1979 **m_image, m_subresourceRange);
1980 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 0u, DE_NULL, 1u, &layoutBarrier);
1982 vk.cmdCopyImageToBuffer(cmdBuffer, **m_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_resource.getBuffer().handle, 1u, ©Region);
1986 SyncInfo getSyncInfo (void) const
1988 const SyncInfo syncInfo =
1990 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
1991 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags accessMask;
1992 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
1997 Data getData (void) const
1999 return getHostBufferData(m_context, *m_hostBuffer, m_resource.getBuffer().size);
2003 OperationContext& m_context;
2004 Resource& m_resource;
2005 const VkImageSubresourceRange m_subresourceRange;
2006 const VkImageSubresourceLayers m_subresourceLayers;
2007 de::MovePtr<Buffer> m_hostBuffer;
2008 de::MovePtr<Image> m_image;
2009 VkExtent3D m_imageExtent;
2012 class ReadImplementation : public Operation
2015 ReadImplementation (OperationContext& context, Resource& resource)
2016 : m_context (context)
2017 , m_resource (resource)
2018 , m_bufferSize (getPixelBufferSize(m_resource.getImage().format, m_resource.getImage().extent))
2020 DE_ASSERT(m_resource.getType() == RESOURCE_TYPE_IMAGE);
2022 const DeviceInterface& vk = m_context.getDeviceInterface();
2023 const VkDevice device = m_context.getDevice();
2024 Allocator& allocator = m_context.getAllocator();
2026 m_hostBuffer = de::MovePtr<Buffer>(new Buffer(
2027 vk, device, allocator, makeBufferCreateInfo(m_bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible));
2029 const Allocation& alloc = m_hostBuffer->getAllocation();
2030 deMemset(alloc.getHostPtr(), 0, static_cast<size_t>(m_bufferSize));
2031 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), m_bufferSize);
2034 void recordCommands (const VkCommandBuffer cmdBuffer)
2036 const DeviceInterface& vk = m_context.getDeviceInterface();
2037 const VkBufferImageCopy copyRegion = makeBufferImageCopy(m_resource.getImage().subresourceLayers, m_resource.getImage().extent);
2039 vk.cmdCopyImageToBuffer(cmdBuffer, m_resource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_hostBuffer, 1u, ©Region);
2042 SyncInfo getSyncInfo (void) const
2044 const SyncInfo syncInfo =
2046 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
2047 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags accessMask;
2048 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout imageLayout;
2053 Data getData (void) const
2055 return getHostBufferData(m_context, *m_hostBuffer, m_bufferSize);
2059 OperationContext& m_context;
2060 Resource& m_resource;
2061 de::MovePtr<Buffer> m_hostBuffer;
2062 const VkDeviceSize m_bufferSize;
2065 class Support : public OperationSupport
2068 Support (const ResourceDescription& resourceDesc, const AccessMode mode)
2070 , m_requiredQueueFlags (resourceDesc.type == RESOURCE_TYPE_IMAGE && isDepthStencilFormat(resourceDesc.imageFormat) ? VK_QUEUE_GRAPHICS_BIT : VK_QUEUE_TRANSFER_BIT)
2072 DE_ASSERT(m_mode == ACCESS_MODE_READ || m_mode == ACCESS_MODE_WRITE);
2073 DE_ASSERT(m_mode == ACCESS_MODE_READ || resourceDesc.type != RESOURCE_TYPE_IMAGE);
2074 DE_ASSERT(m_mode == ACCESS_MODE_WRITE || resourceDesc.type != RESOURCE_TYPE_BUFFER);
2077 deUint32 getResourceUsageFlags (void) const
2079 if (m_mode == ACCESS_MODE_READ)
2080 return VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
2082 return VK_BUFFER_USAGE_TRANSFER_DST_BIT;
2085 VkQueueFlags getQueueFlags (void) const
2087 return m_requiredQueueFlags;
2090 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
2092 if (m_mode == ACCESS_MODE_READ)
2093 return de::MovePtr<Operation>(new ReadImplementation(context, resource));
2095 return de::MovePtr<Operation>(new WriteImplementation(context, resource));
2099 const AccessMode m_mode;
2100 const VkQueueFlags m_requiredQueueFlags;
2103 } // CopyImageToBuffer ns
2105 namespace ClearImage
2111 CLEAR_MODE_DEPTH_STENCIL,
2114 class Implementation : public Operation
2117 Implementation (OperationContext& context, Resource& resource, const ClearMode mode)
2118 : m_context (context)
2119 , m_resource (resource)
2120 , m_clearValue (makeClearValue(m_resource.getImage().format))
2123 const VkDeviceSize size = getPixelBufferSize(m_resource.getImage().format, m_resource.getImage().extent);
2124 const VkExtent3D& extent = m_resource.getImage().extent;
2125 const VkFormat format = m_resource.getImage().format;
2126 const tcu::TextureFormat texFormat = mapVkFormat(format);
2128 m_data.resize(static_cast<std::size_t>(size));
2129 tcu::PixelBufferAccess imagePixels(texFormat, extent.width, extent.height, extent.depth, &m_data[0]);
2130 clearPixelBuffer(imagePixels, m_clearValue);
2133 void recordCommands (const VkCommandBuffer cmdBuffer)
2135 const DeviceInterface& vk = m_context.getDeviceInterface();
2137 const VkImageMemoryBarrier layoutBarrier = makeImageMemoryBarrier(
2138 (VkAccessFlags)0, VK_ACCESS_TRANSFER_WRITE_BIT,
2139 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
2140 m_resource.getImage().handle, m_resource.getImage().subresourceRange);
2142 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 0u, DE_NULL, 1u, &layoutBarrier);
2144 if (m_mode == CLEAR_MODE_COLOR)
2145 vk.cmdClearColorImage(cmdBuffer, m_resource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &m_clearValue.color, 1u, &m_resource.getImage().subresourceRange);
2147 vk.cmdClearDepthStencilImage(cmdBuffer, m_resource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &m_clearValue.depthStencil, 1u, &m_resource.getImage().subresourceRange);
2150 SyncInfo getSyncInfo (void) const
2152 const SyncInfo syncInfo =
2154 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
2155 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags accessMask;
2156 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout imageLayout;
2161 Data getData (void) const
2165 m_data.size(), // std::size_t size;
2166 &m_data[0], // const deUint8* data;
2172 OperationContext& m_context;
2173 Resource& m_resource;
2174 std::vector<deUint8> m_data;
2175 const VkClearValue m_clearValue;
2176 const ClearMode m_mode;
2179 class Support : public OperationSupport
2182 Support (const ResourceDescription& resourceDesc, const ClearMode mode)
2183 : m_resourceDesc (resourceDesc)
2186 DE_ASSERT(m_mode == CLEAR_MODE_COLOR || m_mode == CLEAR_MODE_DEPTH_STENCIL);
2187 DE_ASSERT(m_resourceDesc.type == RESOURCE_TYPE_IMAGE);
2188 DE_ASSERT(m_resourceDesc.imageAspect == VK_IMAGE_ASPECT_COLOR_BIT || (m_mode != CLEAR_MODE_COLOR));
2189 DE_ASSERT((m_resourceDesc.imageAspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) || (m_mode != CLEAR_MODE_DEPTH_STENCIL));
2192 deUint32 getResourceUsageFlags (void) const
2194 return VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2197 VkQueueFlags getQueueFlags (void) const
2199 if (m_mode == CLEAR_MODE_COLOR)
2200 return VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT;
2202 return VK_QUEUE_GRAPHICS_BIT;
2205 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
2207 return de::MovePtr<Operation>(new Implementation(context, resource, m_mode));
2211 const ResourceDescription m_resourceDesc;
2212 const ClearMode m_mode;
2223 DRAW_CALL_DRAW_INDEXED,
2224 DRAW_CALL_DRAW_INDIRECT,
2225 DRAW_CALL_DRAW_INDEXED_INDIRECT,
2228 //! A write operation that is a result of drawing to an image.
2229 //! \todo Add support for depth/stencil too?
2230 class Implementation : public Operation
2233 Implementation (OperationContext& context, Resource& resource, const DrawCall drawCall)
2234 : m_context (context)
2235 , m_resource (resource)
2236 , m_drawCall (drawCall)
2237 , m_vertices (context)
2239 const DeviceInterface& vk = context.getDeviceInterface();
2240 const VkDevice device = context.getDevice();
2241 Allocator& allocator = context.getAllocator();
2245 if (m_drawCall == DRAW_CALL_DRAW_INDIRECT)
2247 m_indirectBuffer = de::MovePtr<Buffer>(new Buffer(vk, device, allocator,
2248 makeBufferCreateInfo(sizeof(VkDrawIndirectCommand), VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT), MemoryRequirement::HostVisible));
2250 const Allocation& alloc = m_indirectBuffer->getAllocation();
2251 VkDrawIndirectCommand* const pIndirectCommand = static_cast<VkDrawIndirectCommand*>(alloc.getHostPtr());
2253 pIndirectCommand->vertexCount = m_vertices.getNumVertices();
2254 pIndirectCommand->instanceCount = 1u;
2255 pIndirectCommand->firstVertex = 0u;
2256 pIndirectCommand->firstInstance = 0u;
2258 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), sizeof(VkDrawIndirectCommand));
2260 else if (m_drawCall == DRAW_CALL_DRAW_INDEXED_INDIRECT)
2262 m_indirectBuffer = de::MovePtr<Buffer>(new Buffer(vk, device, allocator,
2263 makeBufferCreateInfo(sizeof(VkDrawIndexedIndirectCommand), VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT), MemoryRequirement::HostVisible));
2265 const Allocation& alloc = m_indirectBuffer->getAllocation();
2266 VkDrawIndexedIndirectCommand* const pIndirectCommand = static_cast<VkDrawIndexedIndirectCommand*>(alloc.getHostPtr());
2268 pIndirectCommand->indexCount = m_vertices.getNumIndices();
2269 pIndirectCommand->instanceCount = 1u;
2270 pIndirectCommand->firstIndex = 0u;
2271 pIndirectCommand->vertexOffset = 0u;
2272 pIndirectCommand->firstInstance = 0u;
2274 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), sizeof(VkDrawIndexedIndirectCommand));
2277 // Resource image is the color attachment
2279 m_colorFormat = m_resource.getImage().format;
2280 m_colorSubresourceRange = m_resource.getImage().subresourceRange;
2281 m_colorImage = m_resource.getImage().handle;
2282 m_attachmentExtent = m_resource.getImage().extent;
2286 m_colorAttachmentView = makeImageView (vk, device, m_colorImage, VK_IMAGE_VIEW_TYPE_2D, m_colorFormat, m_colorSubresourceRange);
2287 m_renderPass = makeRenderPass (vk, device, m_colorFormat);
2288 m_framebuffer = makeFramebuffer (vk, device, *m_renderPass, *m_colorAttachmentView, m_attachmentExtent.width, m_attachmentExtent.height, 1u);
2289 m_pipelineLayout = makePipelineLayoutWithoutDescriptors(vk, device);
2291 GraphicsPipelineBuilder pipelineBuilder;
2293 .setRenderSize (tcu::IVec2(m_attachmentExtent.width, m_attachmentExtent.height))
2294 .setVertexInputSingleAttribute (m_vertices.getVertexFormat(), m_vertices.getVertexStride())
2295 .setShader (vk, device, VK_SHADER_STAGE_VERTEX_BIT, context.getBinaryCollection().get("draw_vert"), DE_NULL)
2296 .setShader (vk, device, VK_SHADER_STAGE_FRAGMENT_BIT, context.getBinaryCollection().get("draw_frag"), DE_NULL);
2298 m_pipeline = pipelineBuilder.build(vk, device, *m_pipelineLayout, *m_renderPass, context.getPipelineCacheData());
2300 // Set expected draw values
2302 m_expectedData.resize(static_cast<size_t>(getPixelBufferSize(m_resource.getImage().format, m_resource.getImage().extent)));
2303 tcu::PixelBufferAccess imagePixels(mapVkFormat(m_colorFormat), m_attachmentExtent.width, m_attachmentExtent.height, m_attachmentExtent.depth, &m_expectedData[0]);
2304 clearPixelBuffer(imagePixels, makeClearValue(m_colorFormat));
2307 void recordCommands (const VkCommandBuffer cmdBuffer)
2309 const DeviceInterface& vk = m_context.getDeviceInterface();
2311 // Change color attachment image layout
2313 const VkImageMemoryBarrier colorAttachmentLayoutBarrier = makeImageMemoryBarrier(
2314 (VkAccessFlags)0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2315 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
2316 m_colorImage, m_colorSubresourceRange);
2318 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0,
2319 0u, DE_NULL, 0u, DE_NULL, 1u, &colorAttachmentLayoutBarrier);
2323 const VkRect2D renderArea = {
2325 makeExtent2D(m_attachmentExtent.width, m_attachmentExtent.height),
2327 const tcu::Vec4 clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
2329 beginRenderPass(vk, cmdBuffer, *m_renderPass, *m_framebuffer, renderArea, clearColor);
2332 vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
2334 const VkDeviceSize vertexBufferOffset = 0ull;
2335 const VkBuffer vertexBuffer = m_vertices.getVertexBuffer();
2336 vk.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer, &vertexBufferOffset);
2339 if (m_drawCall == DRAW_CALL_DRAW_INDEXED || m_drawCall == DRAW_CALL_DRAW_INDEXED_INDIRECT)
2340 vk.cmdBindIndexBuffer(cmdBuffer, m_vertices.getIndexBuffer(), 0u, m_vertices.getIndexType());
2344 case DRAW_CALL_DRAW:
2345 vk.cmdDraw(cmdBuffer, m_vertices.getNumVertices(), 1u, 0u, 0u);
2348 case DRAW_CALL_DRAW_INDEXED:
2349 vk.cmdDrawIndexed(cmdBuffer, m_vertices.getNumIndices(), 1u, 0u, 0, 0u);
2352 case DRAW_CALL_DRAW_INDIRECT:
2353 vk.cmdDrawIndirect(cmdBuffer, **m_indirectBuffer, 0u, 1u, 0u);
2356 case DRAW_CALL_DRAW_INDEXED_INDIRECT:
2357 vk.cmdDrawIndexedIndirect(cmdBuffer, **m_indirectBuffer, 0u, 1u, 0u);
2361 endRenderPass(vk, cmdBuffer);
2364 SyncInfo getSyncInfo (void) const
2366 const SyncInfo syncInfo =
2368 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags stageMask;
2369 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags accessMask;
2370 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout imageLayout;
2375 Data getData (void) const
2379 m_expectedData.size(), // std::size_t size;
2380 &m_expectedData[0], // const deUint8* data;
2386 OperationContext& m_context;
2387 Resource& m_resource;
2388 const DrawCall m_drawCall;
2389 const VertexGrid m_vertices;
2390 std::vector<deUint8> m_expectedData;
2391 de::MovePtr<Buffer> m_indirectBuffer;
2392 VkFormat m_colorFormat;
2393 VkImage m_colorImage;
2394 Move<VkImageView> m_colorAttachmentView;
2395 VkImageSubresourceRange m_colorSubresourceRange;
2396 VkExtent3D m_attachmentExtent;
2397 Move<VkRenderPass> m_renderPass;
2398 Move<VkFramebuffer> m_framebuffer;
2399 Move<VkPipelineLayout> m_pipelineLayout;
2400 Move<VkPipeline> m_pipeline;
2403 template<typename T, std::size_t N>
2404 std::string toString (const T (&values)[N])
2406 std::ostringstream str;
2407 for (std::size_t i = 0; i < N; ++i)
2408 str << (i != 0 ? ", " : "") << values[i];
2412 class Support : public OperationSupport
2415 Support (const ResourceDescription& resourceDesc, const DrawCall drawCall)
2416 : m_resourceDesc (resourceDesc)
2417 , m_drawCall (drawCall)
2419 DE_ASSERT(m_resourceDesc.type == RESOURCE_TYPE_IMAGE && m_resourceDesc.imageType == VK_IMAGE_TYPE_2D);
2420 DE_ASSERT(!isDepthStencilFormat(m_resourceDesc.imageFormat));
2423 void initPrograms (SourceCollections& programCollection) const
2427 std::ostringstream src;
2428 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
2430 << "layout(location = 0) in vec4 v_in_position;\n"
2432 << "out " << s_perVertexBlock << ";\n"
2434 << "void main (void)\n"
2436 << " gl_Position = v_in_position;\n"
2439 programCollection.glslSources.add("draw_vert") << glu::VertexSource(src.str());
2444 const VkClearValue clearValue = makeClearValue(m_resourceDesc.imageFormat);
2445 const bool isIntegerFormat = isIntFormat(m_resourceDesc.imageFormat) || isUintFormat(m_resourceDesc.imageFormat);
2446 const std::string colorType = (isIntegerFormat ? "uvec4" : "vec4");
2448 std::ostringstream src;
2449 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
2451 << "layout(location = 0) out " << colorType << " o_color;\n"
2453 << "void main (void)\n"
2455 << " o_color = " << colorType << "(" << (isIntegerFormat ? toString(clearValue.color.uint32) : toString(clearValue.color.float32)) << ");\n"
2458 programCollection.glslSources.add("draw_frag") << glu::FragmentSource(src.str());
2462 deUint32 getResourceUsageFlags (void) const
2464 return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
2467 VkQueueFlags getQueueFlags (void) const
2469 return VK_QUEUE_GRAPHICS_BIT;
2472 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
2474 return de::MovePtr<Operation>(new Implementation(context, resource, m_drawCall));
2478 const ResourceDescription m_resourceDesc;
2479 const DrawCall m_drawCall;
2484 namespace ClearAttachments
2487 class Implementation : public Operation
2490 Implementation (OperationContext& context, Resource& resource)
2491 : m_context (context)
2492 , m_resource (resource)
2493 , m_clearValue (makeClearValue(m_resource.getImage().format))
2495 const DeviceInterface& vk = context.getDeviceInterface();
2496 const VkDevice device = context.getDevice();
2498 const VkDeviceSize size = getPixelBufferSize(m_resource.getImage().format, m_resource.getImage().extent);
2499 const VkExtent3D& extent = m_resource.getImage().extent;
2500 const VkFormat format = m_resource.getImage().format;
2501 const tcu::TextureFormat texFormat = mapVkFormat(format);
2502 const SyncInfo syncInfo = getSyncInfo();
2504 m_data.resize(static_cast<std::size_t>(size));
2505 tcu::PixelBufferAccess imagePixels(texFormat, extent.width, extent.height, extent.depth, &m_data[0]);
2506 clearPixelBuffer(imagePixels, m_clearValue);
2508 m_attachmentView = makeImageView(vk, device, m_resource.getImage().handle, getImageViewType(m_resource.getImage().imageType), m_resource.getImage().format, m_resource.getImage().subresourceRange);
2510 const VkAttachmentDescription colorAttachmentDescription =
2512 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
2513 m_resource.getImage().format, // VkFormat format;
2514 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
2515 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp;
2516 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
2517 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
2518 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp stencilStoreOp;
2519 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
2520 syncInfo.imageLayout // VkImageLayout finalLayout;
2523 const VkAttachmentReference colorAttachmentReference =
2525 0u, // deUint32 attachment;
2526 syncInfo.imageLayout // VkImageLayout layout;
2529 const VkAttachmentReference depthStencilAttachmentReference =
2531 0u, // deUint32 attachment;
2532 syncInfo.imageLayout // VkImageLayout layout;
2535 VkSubpassDescription subpassDescription =
2537 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags;
2538 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
2539 0u, // deUint32 inputAttachmentCount;
2540 DE_NULL, // const VkAttachmentReference* pInputAttachments;
2541 0u, // deUint32 colorAttachmentCount;
2542 DE_NULL, // const VkAttachmentReference* pColorAttachments;
2543 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
2544 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
2545 0u, // deUint32 preserveAttachmentCount;
2546 DE_NULL // const deUint32* pPreserveAttachments;
2549 switch (m_resource.getImage().subresourceRange.aspectMask)
2551 case VK_IMAGE_ASPECT_COLOR_BIT:
2552 subpassDescription.colorAttachmentCount = 1u;
2553 subpassDescription.pColorAttachments = &colorAttachmentReference;
2555 case VK_IMAGE_ASPECT_STENCIL_BIT:
2556 case VK_IMAGE_ASPECT_DEPTH_BIT:
2557 subpassDescription.pDepthStencilAttachment = &depthStencilAttachmentReference;
2564 const VkRenderPassCreateInfo renderPassInfo =
2566 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
2567 DE_NULL, // const void* pNext;
2568 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags;
2569 1u, // deUint32 attachmentCount;
2570 &colorAttachmentDescription, // const VkAttachmentDescription* pAttachments;
2571 1u, // deUint32 subpassCount;
2572 &subpassDescription, // const VkSubpassDescription* pSubpasses;
2573 0u, // deUint32 dependencyCount;
2574 DE_NULL // const VkSubpassDependency* pDependencies;
2577 m_renderPass = createRenderPass(vk, device, &renderPassInfo);
2578 m_frameBuffer = makeFramebuffer(vk, device, *m_renderPass, *m_attachmentView, m_resource.getImage().extent.width, m_resource.getImage().extent.height, 1u);
2581 void recordCommands (const VkCommandBuffer cmdBuffer)
2583 const DeviceInterface& vk = m_context.getDeviceInterface();
2584 const VkRenderPassBeginInfo renderPassBeginInfo =
2586 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
2587 DE_NULL, // const void* pNext;
2588 *m_renderPass, // VkRenderPass renderPass;
2589 *m_frameBuffer, // VkFramebuffer framebuffer;
2591 { 0, 0 }, // VkOffset2D offset;
2593 m_resource.getImage().extent.width, // deUint32 width;
2594 m_resource.getImage().extent.height // deUint32 height;
2595 } // VkExtent2D extent;
2596 }, // VkRect2D renderArea;
2597 1u, // deUint32 clearValueCount;
2598 &m_clearValue // const VkClearValue* pClearValues;
2601 vk.cmdBeginRenderPass(cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
2603 const VkClearAttachment clearAttachment =
2605 m_resource.getImage().subresourceRange.aspectMask, // VkImageAspectFlags aspectMask;
2606 0, // deUint32 colorAttachment;
2607 m_clearValue // VkClearValue clearValue;
2610 const VkRect2D rect2D =
2612 { 0u, 0u, }, // VkOffset2D offset;
2613 { m_resource.getImage().extent.width, m_resource.getImage().extent.height }, // VkExtent2D extent;
2616 const VkClearRect clearRect =
2618 rect2D, // VkRect2D rect;
2619 0u, // deUint32 baseArrayLayer;
2620 m_resource.getImage().subresourceLayers.layerCount // deUint32 layerCount;
2623 vk.cmdClearAttachments(cmdBuffer, 1, &clearAttachment, 1, &clearRect);
2625 vk.cmdEndRenderPass(cmdBuffer);
2628 SyncInfo getSyncInfo (void) const
2631 syncInfo.stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
2633 switch (m_resource.getImage().subresourceRange.aspectMask)
2635 case VK_IMAGE_ASPECT_COLOR_BIT:
2636 syncInfo.accessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
2637 syncInfo.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
2639 case VK_IMAGE_ASPECT_STENCIL_BIT:
2640 case VK_IMAGE_ASPECT_DEPTH_BIT:
2641 syncInfo.accessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
2642 syncInfo.imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
2652 Data getData (void) const
2656 m_data.size(), // std::size_t size;
2657 &m_data[0], // const deUint8* data;
2663 OperationContext& m_context;
2664 Resource& m_resource;
2665 std::vector<deUint8> m_data;
2666 const VkClearValue m_clearValue;
2667 Move<VkImageView> m_attachmentView;
2668 Move<VkRenderPass> m_renderPass;
2669 Move<VkFramebuffer> m_frameBuffer;
2672 class Support : public OperationSupport
2675 Support (const ResourceDescription& resourceDesc)
2676 : m_resourceDesc (resourceDesc)
2678 DE_ASSERT(m_resourceDesc.type == RESOURCE_TYPE_IMAGE);
2681 deUint32 getResourceUsageFlags (void) const
2683 switch (m_resourceDesc.imageAspect)
2685 case VK_IMAGE_ASPECT_COLOR_BIT:
2686 return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
2687 case VK_IMAGE_ASPECT_STENCIL_BIT:
2688 case VK_IMAGE_ASPECT_DEPTH_BIT:
2689 return VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
2696 VkQueueFlags getQueueFlags (void) const
2698 return VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT;
2701 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
2703 return de::MovePtr<Operation>(new Implementation(context, resource));
2707 const ResourceDescription m_resourceDesc;
2710 } // ClearAttachments
2712 namespace IndirectBuffer
2715 class GraphicsPipeline : public Pipeline
2718 GraphicsPipeline (OperationContext& context,
2719 const ResourceType resourceType,
2720 const VkBuffer indirectBuffer,
2721 const std::string& shaderPrefix,
2722 const VkDescriptorSetLayout descriptorSetLayout)
2723 : m_resourceType (resourceType)
2724 , m_indirectBuffer (indirectBuffer)
2725 , m_vertices (context)
2727 const DeviceInterface& vk = context.getDeviceInterface();
2728 const VkDevice device = context.getDevice();
2729 Allocator& allocator = context.getAllocator();
2733 m_colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
2734 m_colorImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
2735 m_colorImageExtent = makeExtent3D(16u, 16u, 1u);
2736 m_colorAttachmentImage = de::MovePtr<Image>(new Image(vk, device, allocator,
2737 makeImageCreateInfo(VK_IMAGE_TYPE_2D, m_colorImageExtent, m_colorFormat, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT),
2738 MemoryRequirement::Any));
2742 m_colorAttachmentView = makeImageView (vk, device, **m_colorAttachmentImage, VK_IMAGE_VIEW_TYPE_2D, m_colorFormat, m_colorImageSubresourceRange);
2743 m_renderPass = makeRenderPass (vk, device, m_colorFormat);
2744 m_framebuffer = makeFramebuffer (vk, device, *m_renderPass, *m_colorAttachmentView, m_colorImageExtent.width, m_colorImageExtent.height, 1u);
2745 m_pipelineLayout = makePipelineLayout(vk, device, descriptorSetLayout);
2747 GraphicsPipelineBuilder pipelineBuilder;
2749 .setRenderSize (tcu::IVec2(m_colorImageExtent.width, m_colorImageExtent.height))
2750 .setVertexInputSingleAttribute (m_vertices.getVertexFormat(), m_vertices.getVertexStride())
2751 .setShader (vk, device, VK_SHADER_STAGE_VERTEX_BIT, context.getBinaryCollection().get(shaderPrefix + "vert"), DE_NULL)
2752 .setShader (vk, device, VK_SHADER_STAGE_FRAGMENT_BIT, context.getBinaryCollection().get(shaderPrefix + "frag"), DE_NULL);
2754 m_pipeline = pipelineBuilder.build(vk, device, *m_pipelineLayout, *m_renderPass, context.getPipelineCacheData());
2757 void recordCommands (OperationContext& context, const VkCommandBuffer cmdBuffer, const VkDescriptorSet descriptorSet)
2759 const DeviceInterface& vk = context.getDeviceInterface();
2761 // Change color attachment image layout
2763 const VkImageMemoryBarrier colorAttachmentLayoutBarrier = makeImageMemoryBarrier(
2764 (VkAccessFlags)0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2765 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
2766 **m_colorAttachmentImage, m_colorImageSubresourceRange);
2768 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0,
2769 0u, DE_NULL, 0u, DE_NULL, 1u, &colorAttachmentLayoutBarrier);
2773 const VkRect2D renderArea = {
2775 makeExtent2D(m_colorImageExtent.width, m_colorImageExtent.height),
2777 const tcu::Vec4 clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
2779 beginRenderPass(vk, cmdBuffer, *m_renderPass, *m_framebuffer, renderArea, clearColor);
2782 vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
2783 vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &descriptorSet, 0u, DE_NULL);
2785 const VkDeviceSize vertexBufferOffset = 0ull;
2786 const VkBuffer vertexBuffer = m_vertices.getVertexBuffer();
2787 vk.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer, &vertexBufferOffset);
2790 switch (m_resourceType)
2792 case RESOURCE_TYPE_INDIRECT_BUFFER_DRAW:
2793 vk.cmdDrawIndirect(cmdBuffer, m_indirectBuffer, 0u, 1u, 0u);
2796 case RESOURCE_TYPE_INDIRECT_BUFFER_DRAW_INDEXED:
2797 vk.cmdBindIndexBuffer(cmdBuffer, m_vertices.getIndexBuffer(), 0u, m_vertices.getIndexType());
2798 vk.cmdDrawIndexedIndirect(cmdBuffer, m_indirectBuffer, 0u, 1u, 0u);
2805 endRenderPass(vk, cmdBuffer);
2809 const ResourceType m_resourceType;
2810 const VkBuffer m_indirectBuffer;
2811 const VertexGrid m_vertices;
2812 VkFormat m_colorFormat;
2813 de::MovePtr<Image> m_colorAttachmentImage;
2814 Move<VkImageView> m_colorAttachmentView;
2815 VkExtent3D m_colorImageExtent;
2816 VkImageSubresourceRange m_colorImageSubresourceRange;
2817 Move<VkRenderPass> m_renderPass;
2818 Move<VkFramebuffer> m_framebuffer;
2819 Move<VkPipelineLayout> m_pipelineLayout;
2820 Move<VkPipeline> m_pipeline;
2823 class ComputePipeline : public Pipeline
2826 ComputePipeline (OperationContext& context,
2827 const VkBuffer indirectBuffer,
2828 const std::string& shaderPrefix,
2829 const VkDescriptorSetLayout descriptorSetLayout)
2830 : m_indirectBuffer (indirectBuffer)
2832 const DeviceInterface& vk = context.getDeviceInterface();
2833 const VkDevice device = context.getDevice();
2835 const Unique<VkShaderModule> shaderModule(createShaderModule(vk, device, context.getBinaryCollection().get(shaderPrefix + "comp"), (VkShaderModuleCreateFlags)0));
2837 m_pipelineLayout = makePipelineLayout(vk, device, descriptorSetLayout);
2838 m_pipeline = makeComputePipeline(vk, device, *m_pipelineLayout, *shaderModule, DE_NULL, context.getPipelineCacheData());
2841 void recordCommands (OperationContext& context, const VkCommandBuffer cmdBuffer, const VkDescriptorSet descriptorSet)
2843 const DeviceInterface& vk = context.getDeviceInterface();
2845 vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipeline);
2846 vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0u, 1u, &descriptorSet, 0u, DE_NULL);
2847 vk.cmdDispatchIndirect(cmdBuffer, m_indirectBuffer, 0u);
2851 const VkBuffer m_indirectBuffer;
2852 Move<VkPipelineLayout> m_pipelineLayout;
2853 Move<VkPipeline> m_pipeline;
2856 //! Read indirect buffer by executing an indirect draw or dispatch command.
2857 class ReadImplementation : public Operation
2860 ReadImplementation (OperationContext& context, Resource& resource)
2861 : m_context (context)
2862 , m_resource (resource)
2863 , m_stage (resource.getType() == RESOURCE_TYPE_INDIRECT_BUFFER_DISPATCH ? VK_SHADER_STAGE_COMPUTE_BIT : VK_SHADER_STAGE_VERTEX_BIT)
2864 , m_pipelineStage (pipelineStageFlagsFromShaderStageFlagBits(m_stage))
2865 , m_hostBufferSizeBytes (sizeof(deUint32))
2867 requireFeaturesForSSBOAccess (m_context, m_stage);
2869 const DeviceInterface& vk = m_context.getDeviceInterface();
2870 const VkDevice device = m_context.getDevice();
2871 Allocator& allocator = m_context.getAllocator();
2873 m_hostBuffer = de::MovePtr<Buffer>(new Buffer(
2874 vk, device, allocator, makeBufferCreateInfo(m_hostBufferSizeBytes, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible));
2876 // Init host buffer data
2878 const Allocation& alloc = m_hostBuffer->getAllocation();
2879 deMemset(alloc.getHostPtr(), 0, static_cast<size_t>(m_hostBufferSizeBytes));
2880 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), static_cast<size_t>(m_hostBufferSizeBytes));
2883 // Prepare descriptors
2885 m_descriptorSetLayout = DescriptorSetLayoutBuilder()
2886 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, m_stage)
2889 m_descriptorPool = DescriptorPoolBuilder()
2890 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
2891 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
2893 m_descriptorSet = makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout);
2895 const VkDescriptorBufferInfo hostBufferInfo = makeDescriptorBufferInfo(**m_hostBuffer, 0u, m_hostBufferSizeBytes);
2897 DescriptorSetUpdateBuilder()
2898 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &hostBufferInfo)
2899 .update(vk, device);
2903 m_pipeline = (m_resource.getType() == RESOURCE_TYPE_INDIRECT_BUFFER_DISPATCH
2904 ? de::MovePtr<Pipeline>(new ComputePipeline(context, m_resource.getBuffer().handle, "read_ib_", *m_descriptorSetLayout))
2905 : de::MovePtr<Pipeline>(new GraphicsPipeline(context, m_resource.getType(), m_resource.getBuffer().handle, "read_ib_", *m_descriptorSetLayout)));
2908 void recordCommands (const VkCommandBuffer cmdBuffer)
2910 const DeviceInterface& vk = m_context.getDeviceInterface();
2912 m_pipeline->recordCommands(m_context, cmdBuffer, *m_descriptorSet);
2914 // Insert a barrier so data written by the shader is available to the host
2915 const VkBufferMemoryBarrier barrier = makeBufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, **m_hostBuffer, 0u, m_hostBufferSizeBytes);
2916 vk.cmdPipelineBarrier(cmdBuffer, m_pipelineStage, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
2919 SyncInfo getSyncInfo (void) const
2921 const SyncInfo syncInfo =
2923 VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, // VkPipelineStageFlags stageMask;
2924 VK_ACCESS_INDIRECT_COMMAND_READ_BIT, // VkAccessFlags accessMask;
2925 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
2930 Data getData (void) const
2932 return getHostBufferData(m_context, *m_hostBuffer, m_hostBufferSizeBytes);
2936 OperationContext& m_context;
2937 Resource& m_resource;
2938 const VkShaderStageFlagBits m_stage;
2939 const VkPipelineStageFlags m_pipelineStage;
2940 const VkDeviceSize m_hostBufferSizeBytes;
2941 de::MovePtr<Buffer> m_hostBuffer;
2942 Move<VkDescriptorPool> m_descriptorPool;
2943 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
2944 Move<VkDescriptorSet> m_descriptorSet;
2945 de::MovePtr<Pipeline> m_pipeline;
2948 //! Prepare indirect buffer for a draw/dispatch call.
2949 class WriteImplementation : public Operation
2952 WriteImplementation (OperationContext& context, Resource& resource)
2953 : m_context (context)
2954 , m_resource (resource)
2956 switch (m_resource.getType())
2958 case RESOURCE_TYPE_INDIRECT_BUFFER_DRAW:
2960 m_drawIndirect.vertexCount = 6u;
2961 m_drawIndirect.instanceCount = 1u;
2962 m_drawIndirect.firstVertex = 0u;
2963 m_drawIndirect.firstInstance = 0u;
2965 m_indirectData = reinterpret_cast<deUint32*>(&m_drawIndirect);
2966 m_expectedValue = 6u;
2970 case RESOURCE_TYPE_INDIRECT_BUFFER_DRAW_INDEXED:
2972 m_drawIndexedIndirect.indexCount = 6u;
2973 m_drawIndexedIndirect.instanceCount = 1u;
2974 m_drawIndexedIndirect.firstIndex = 0u;
2975 m_drawIndexedIndirect.vertexOffset = 0u;
2976 m_drawIndexedIndirect.firstInstance = 0u;
2978 m_indirectData = reinterpret_cast<deUint32*>(&m_drawIndexedIndirect);
2979 m_expectedValue = 6u;
2983 case RESOURCE_TYPE_INDIRECT_BUFFER_DISPATCH:
2985 m_dispatchIndirect.x = 7u;
2986 m_dispatchIndirect.y = 2u;
2987 m_dispatchIndirect.z = 1u;
2989 m_indirectData = reinterpret_cast<deUint32*>(&m_dispatchIndirect);
2990 m_expectedValue = 14u;
3000 void recordCommands (const VkCommandBuffer cmdBuffer)
3002 const DeviceInterface& vk = m_context.getDeviceInterface();
3004 vk.cmdUpdateBuffer(cmdBuffer, m_resource.getBuffer().handle, m_resource.getBuffer().offset, m_resource.getBuffer().size, m_indirectData);
3007 SyncInfo getSyncInfo (void) const
3009 const SyncInfo syncInfo =
3011 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
3012 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags accessMask;
3013 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
3018 Data getData (void) const
3022 sizeof(deUint32), // std::size_t size;
3023 reinterpret_cast<const deUint8*>(&m_expectedValue), // const deUint8* data;
3029 OperationContext& m_context;
3030 Resource& m_resource;
3031 VkDrawIndirectCommand m_drawIndirect;
3032 VkDrawIndexedIndirectCommand m_drawIndexedIndirect;
3033 VkDispatchIndirectCommand m_dispatchIndirect;
3034 deUint32* m_indirectData;
3035 deUint32 m_expectedValue; //! Side-effect value expected to be computed by a read (draw/dispatch) command.
3038 class ReadSupport : public OperationSupport
3041 ReadSupport (const ResourceDescription& resourceDesc)
3042 : m_resourceDesc (resourceDesc)
3044 DE_ASSERT(isIndirectBuffer(m_resourceDesc.type));
3047 void initPrograms (SourceCollections& programCollection) const
3049 std::ostringstream decl;
3050 decl << "layout(set = 0, binding = 0, std140) coherent buffer Data {\n"
3054 std::ostringstream main;
3055 main << " atomicAdd(sb_out.value, 1u);\n";
3059 std::ostringstream src;
3060 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
3062 << "layout(location = 0) in vec4 v_in_position;\n"
3064 << "out " << s_perVertexBlock << ";\n"
3068 << "void main (void)\n"
3070 << " gl_Position = v_in_position;\n"
3074 programCollection.glslSources.add("read_ib_vert") << glu::VertexSource(src.str());
3079 std::ostringstream src;
3080 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
3082 << "layout(location = 0) out vec4 o_color;\n"
3084 << "void main (void)\n"
3086 << " o_color = vec4(1.0);\n"
3089 programCollection.glslSources.add("read_ib_frag") << glu::FragmentSource(src.str());
3094 std::ostringstream src;
3095 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
3097 << "layout(local_size_x = 1) in;\n"
3101 << "void main (void)\n"
3106 programCollection.glslSources.add("read_ib_comp") << glu::ComputeSource(src.str());
3110 deUint32 getResourceUsageFlags (void) const
3112 return VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
3115 VkQueueFlags getQueueFlags (void) const
3117 return (m_resourceDesc.type == RESOURCE_TYPE_INDIRECT_BUFFER_DISPATCH ? VK_QUEUE_COMPUTE_BIT : VK_QUEUE_GRAPHICS_BIT);
3120 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
3122 return de::MovePtr<Operation>(new ReadImplementation(context, resource));
3126 const ResourceDescription m_resourceDesc;
3130 class WriteSupport : public OperationSupport
3133 WriteSupport (const ResourceDescription& resourceDesc)
3135 DE_ASSERT(isIndirectBuffer(resourceDesc.type));
3136 DE_UNREF(resourceDesc);
3139 deUint32 getResourceUsageFlags (void) const
3141 return VK_BUFFER_USAGE_TRANSFER_DST_BIT;
3144 VkQueueFlags getQueueFlags (void) const
3146 return VK_QUEUE_TRANSFER_BIT;
3149 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
3151 return de::MovePtr<Operation>(new WriteImplementation(context, resource));
3155 } // IndirectBuffer ns
3157 namespace VertexInput
3160 class Implementation : public Operation
3163 Implementation (OperationContext& context, Resource& resource)
3164 : m_context (context)
3165 , m_resource (resource)
3167 requireFeaturesForSSBOAccess (m_context, VK_SHADER_STAGE_VERTEX_BIT);
3169 const DeviceInterface& vk = context.getDeviceInterface();
3170 const VkDevice device = context.getDevice();
3171 Allocator& allocator = context.getAllocator();
3172 const VkDeviceSize dataSizeBytes = m_resource.getBuffer().size;
3174 m_outputBuffer = de::MovePtr<Buffer>(new Buffer(vk, device, allocator,
3175 makeBufferCreateInfo(dataSizeBytes, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible));
3178 const Allocation& alloc = m_outputBuffer->getAllocation();
3179 deMemset(alloc.getHostPtr(), 0, static_cast<size_t>(dataSizeBytes));
3180 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), dataSizeBytes);
3183 m_descriptorSetLayout = DescriptorSetLayoutBuilder()
3184 .addSingleBinding (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_VERTEX_BIT)
3185 .build (vk, device);
3187 m_descriptorPool = DescriptorPoolBuilder()
3188 .addType (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
3189 .build (vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
3191 m_descriptorSet = makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout);
3193 const VkDescriptorBufferInfo outputBufferDescriptorInfo = makeDescriptorBufferInfo(m_outputBuffer->get(), 0ull, dataSizeBytes);
3194 DescriptorSetUpdateBuilder()
3195 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outputBufferDescriptorInfo)
3196 .update (vk, device);
3199 m_colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
3200 m_colorImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
3201 m_colorImageExtent = makeExtent3D(16u, 16u, 1u);
3202 m_colorAttachmentImage = de::MovePtr<Image>(new Image(vk, device, allocator,
3203 makeImageCreateInfo(VK_IMAGE_TYPE_2D, m_colorImageExtent, m_colorFormat, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT),
3204 MemoryRequirement::Any));
3207 m_colorAttachmentView = makeImageView (vk, device, **m_colorAttachmentImage, VK_IMAGE_VIEW_TYPE_2D, m_colorFormat, m_colorImageSubresourceRange);
3208 m_renderPass = makeRenderPass (vk, device, m_colorFormat);
3209 m_framebuffer = makeFramebuffer (vk, device, *m_renderPass, *m_colorAttachmentView, m_colorImageExtent.width, m_colorImageExtent.height, 1u);
3210 m_pipelineLayout = makePipelineLayout(vk, device, *m_descriptorSetLayout);
3212 m_pipeline = GraphicsPipelineBuilder()
3213 .setPrimitiveTopology (VK_PRIMITIVE_TOPOLOGY_POINT_LIST)
3214 .setRenderSize (tcu::IVec2(static_cast<int>(m_colorImageExtent.width), static_cast<int>(m_colorImageExtent.height)))
3215 .setVertexInputSingleAttribute (VK_FORMAT_R32G32B32A32_UINT, tcu::getPixelSize(mapVkFormat(VK_FORMAT_R32G32B32A32_UINT)))
3216 .setShader (vk, device, VK_SHADER_STAGE_VERTEX_BIT, context.getBinaryCollection().get("input_vert"), DE_NULL)
3217 .setShader (vk, device, VK_SHADER_STAGE_FRAGMENT_BIT, context.getBinaryCollection().get("input_frag"), DE_NULL)
3218 .build (vk, device, *m_pipelineLayout, *m_renderPass, context.getPipelineCacheData());
3221 void recordCommands (const VkCommandBuffer cmdBuffer)
3223 const DeviceInterface& vk = m_context.getDeviceInterface();
3224 const VkDeviceSize dataSizeBytes = m_resource.getBuffer().size;
3226 // Change color attachment image layout
3228 const VkImageMemoryBarrier colorAttachmentLayoutBarrier = makeImageMemoryBarrier(
3229 (VkAccessFlags)0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
3230 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
3231 **m_colorAttachmentImage, m_colorImageSubresourceRange);
3233 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0,
3234 0u, DE_NULL, 0u, DE_NULL, 1u, &colorAttachmentLayoutBarrier);
3238 const VkRect2D renderArea = {
3240 makeExtent2D(m_colorImageExtent.width, m_colorImageExtent.height),
3242 const tcu::Vec4 clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
3244 beginRenderPass(vk, cmdBuffer, *m_renderPass, *m_framebuffer, renderArea, clearColor);
3247 vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
3248 vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &m_descriptorSet.get(), 0u, DE_NULL);
3250 const VkDeviceSize vertexBufferOffset = 0ull;
3251 vk.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &m_resource.getBuffer().handle, &vertexBufferOffset);
3254 vk.cmdDraw(cmdBuffer, static_cast<deUint32>(dataSizeBytes / sizeof(tcu::UVec4)), 1u, 0u, 0u);
3256 const VkBufferMemoryBarrier barrier = makeBufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, **m_outputBuffer, 0u, m_resource.getBuffer().size);
3257 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
3259 endRenderPass(vk, cmdBuffer);
3262 SyncInfo getSyncInfo (void) const
3264 const SyncInfo syncInfo =
3266 VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, // VkPipelineStageFlags stageMask;
3267 VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, // VkAccessFlags accessMask;
3268 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
3273 Data getData (void) const
3275 return getHostBufferData(m_context, *m_outputBuffer, m_resource.getBuffer().size);
3279 OperationContext& m_context;
3280 Resource& m_resource;
3281 de::MovePtr<Buffer> m_outputBuffer;
3282 de::MovePtr<Buffer> m_indexBuffer;
3283 de::MovePtr<Buffer> m_indirectBuffer;
3284 Move<VkRenderPass> m_renderPass;
3285 Move<VkFramebuffer> m_framebuffer;
3286 Move<VkPipelineLayout> m_pipelineLayout;
3287 Move<VkPipeline> m_pipeline;
3288 VkFormat m_colorFormat;
3289 de::MovePtr<Image> m_colorAttachmentImage;
3290 Move<VkImageView> m_colorAttachmentView;
3291 VkExtent3D m_colorImageExtent;
3292 VkImageSubresourceRange m_colorImageSubresourceRange;
3293 Move<VkDescriptorPool> m_descriptorPool;
3294 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
3295 Move<VkDescriptorSet> m_descriptorSet;
3298 class Support : public OperationSupport
3301 Support (const ResourceDescription& resourceDesc)
3302 : m_resourceDesc (resourceDesc)
3304 DE_ASSERT(m_resourceDesc.type == RESOURCE_TYPE_BUFFER);
3307 void initPrograms (SourceCollections& programCollection) const
3311 int vertexStride = sizeof(tcu::UVec4);
3312 std::ostringstream src;
3313 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
3315 << "layout(location = 0) in uvec4 v_in_data;\n"
3316 << "layout(set = 0, binding = 0, std140) writeonly buffer Output {\n"
3317 << " uvec4 data[" << m_resourceDesc.size.x()/vertexStride << "];\n"
3320 << "void main (void)\n"
3322 << " b_out.data[gl_VertexIndex] = v_in_data;\n"
3324 programCollection.glslSources.add("input_vert") << glu::VertexSource(src.str());
3329 std::ostringstream src;
3330 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
3332 << "layout(location = 0) out vec4 o_color;\n"
3334 << "void main (void)\n"
3336 << " o_color = vec4(1.0);\n"
3338 programCollection.glslSources.add("input_frag") << glu::FragmentSource(src.str());
3342 deUint32 getResourceUsageFlags (void) const
3344 return VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
3347 VkQueueFlags getQueueFlags (void) const
3349 return VK_QUEUE_GRAPHICS_BIT;
3352 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
3354 return de::MovePtr<Operation>(new Implementation(context, resource));
3358 const ResourceDescription m_resourceDesc;
3365 OperationContext::OperationContext (Context& context, PipelineCacheData& pipelineCacheData)
3366 : m_vki (context.getInstanceInterface())
3367 , m_vk (context.getDeviceInterface())
3368 , m_physicalDevice (context.getPhysicalDevice())
3369 , m_device (context.getDevice())
3370 , m_allocator (context.getDefaultAllocator())
3371 , m_progCollection (context.getBinaryCollection())
3372 , m_pipelineCacheData (pipelineCacheData)
3376 OperationContext::OperationContext (Context& context, PipelineCacheData& pipelineCacheData, const DeviceInterface& vk, const VkDevice device, vk::Allocator& allocator)
3377 : m_vki (context.getInstanceInterface())
3379 , m_physicalDevice (context.getPhysicalDevice())
3381 , m_allocator (allocator)
3382 , m_progCollection (context.getBinaryCollection())
3383 , m_pipelineCacheData (pipelineCacheData)
3387 Resource::Resource (OperationContext& context, const ResourceDescription& desc, const deUint32 usage, const vk::VkSharingMode sharingMode, const std::vector<deUint32>& queueFamilyIndex)
3388 : m_type (desc.type)
3390 const DeviceInterface& vk = context.getDeviceInterface();
3391 const InstanceInterface& vki = context.getInstanceInterface();
3392 const VkDevice device = context.getDevice();
3393 const VkPhysicalDevice physDevice = context.getPhysicalDevice();
3394 Allocator& allocator = context.getAllocator();
3396 if (m_type == RESOURCE_TYPE_BUFFER || isIndirectBuffer(m_type))
3398 m_bufferData.offset = 0u;
3399 m_bufferData.size = static_cast<VkDeviceSize>(desc.size.x());
3400 VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(m_bufferData.size, usage);
3401 bufferCreateInfo.sharingMode = sharingMode;
3402 if (queueFamilyIndex.size() > 0)
3404 bufferCreateInfo.queueFamilyIndexCount = static_cast<deUint32>(queueFamilyIndex.size());
3405 bufferCreateInfo.pQueueFamilyIndices = &queueFamilyIndex[0];
3407 m_buffer = de::MovePtr<Buffer>(new Buffer(vk, device, allocator, bufferCreateInfo, MemoryRequirement::Any));
3408 m_bufferData.handle = **m_buffer;
3410 else if (m_type == RESOURCE_TYPE_IMAGE)
3412 m_imageData.extent = makeExtent3D(desc.size.x(), std::max(1, desc.size.y()), std::max(1, desc.size.z()));
3413 m_imageData.imageType = desc.imageType;
3414 m_imageData.format = desc.imageFormat;
3415 m_imageData.subresourceRange = makeImageSubresourceRange(desc.imageAspect, 0u, 1u, 0u, 1u);
3416 m_imageData.subresourceLayers = makeImageSubresourceLayers(desc.imageAspect, 0u, 0u, 1u);
3417 VkImageCreateInfo imageInfo = makeImageCreateInfo(m_imageData.imageType, m_imageData.extent, m_imageData.format, usage);
3418 imageInfo.sharingMode = sharingMode;
3419 if (queueFamilyIndex.size() > 0)
3421 imageInfo.queueFamilyIndexCount = static_cast<deUint32>(queueFamilyIndex.size());
3422 imageInfo.pQueueFamilyIndices = &queueFamilyIndex[0];
3425 VkImageFormatProperties imageFormatProperties;
3426 const VkResult formatResult = vki.getPhysicalDeviceImageFormatProperties(physDevice, imageInfo.format, imageInfo.imageType, imageInfo.tiling, imageInfo.usage, imageInfo.flags, &imageFormatProperties);
3428 if (formatResult != VK_SUCCESS)
3429 TCU_THROW(NotSupportedError, "Image format is not supported");
3431 m_image = de::MovePtr<Image>(new Image(vk, device, allocator, imageInfo, MemoryRequirement::Any));
3432 m_imageData.handle = **m_image;
3438 //! \note This function exists for performance reasons. We're creating a lot of tests and checking requirements here
3439 //! before creating an OperationSupport object is faster.
3440 bool isResourceSupported (const OperationName opName, const ResourceDescription& resourceDesc)
3444 case OPERATION_NAME_WRITE_FILL_BUFFER:
3445 case OPERATION_NAME_WRITE_COPY_BUFFER:
3446 case OPERATION_NAME_WRITE_COPY_IMAGE_TO_BUFFER:
3447 case OPERATION_NAME_WRITE_SSBO_VERTEX:
3448 case OPERATION_NAME_WRITE_SSBO_TESSELLATION_CONTROL:
3449 case OPERATION_NAME_WRITE_SSBO_TESSELLATION_EVALUATION:
3450 case OPERATION_NAME_WRITE_SSBO_GEOMETRY:
3451 case OPERATION_NAME_WRITE_SSBO_FRAGMENT:
3452 case OPERATION_NAME_WRITE_SSBO_COMPUTE:
3453 case OPERATION_NAME_WRITE_SSBO_COMPUTE_INDIRECT:
3454 case OPERATION_NAME_READ_COPY_BUFFER:
3455 case OPERATION_NAME_READ_COPY_BUFFER_TO_IMAGE:
3456 case OPERATION_NAME_READ_SSBO_VERTEX:
3457 case OPERATION_NAME_READ_SSBO_TESSELLATION_CONTROL:
3458 case OPERATION_NAME_READ_SSBO_TESSELLATION_EVALUATION:
3459 case OPERATION_NAME_READ_SSBO_GEOMETRY:
3460 case OPERATION_NAME_READ_SSBO_FRAGMENT:
3461 case OPERATION_NAME_READ_SSBO_COMPUTE:
3462 case OPERATION_NAME_READ_SSBO_COMPUTE_INDIRECT:
3463 case OPERATION_NAME_READ_VERTEX_INPUT:
3464 return resourceDesc.type == RESOURCE_TYPE_BUFFER;
3466 case OPERATION_NAME_WRITE_INDIRECT_BUFFER_DRAW:
3467 case OPERATION_NAME_READ_INDIRECT_BUFFER_DRAW:
3468 return resourceDesc.type == RESOURCE_TYPE_INDIRECT_BUFFER_DRAW;
3470 case OPERATION_NAME_WRITE_INDIRECT_BUFFER_DRAW_INDEXED:
3471 case OPERATION_NAME_READ_INDIRECT_BUFFER_DRAW_INDEXED:
3472 return resourceDesc.type == RESOURCE_TYPE_INDIRECT_BUFFER_DRAW_INDEXED;
3474 case OPERATION_NAME_WRITE_INDIRECT_BUFFER_DISPATCH:
3475 case OPERATION_NAME_READ_INDIRECT_BUFFER_DISPATCH:
3476 return resourceDesc.type == RESOURCE_TYPE_INDIRECT_BUFFER_DISPATCH;
3478 case OPERATION_NAME_WRITE_UPDATE_BUFFER:
3479 return resourceDesc.type == RESOURCE_TYPE_BUFFER && resourceDesc.size.x() <= MAX_UPDATE_BUFFER_SIZE;
3481 case OPERATION_NAME_WRITE_COPY_IMAGE:
3482 case OPERATION_NAME_WRITE_COPY_BUFFER_TO_IMAGE:
3483 case OPERATION_NAME_READ_COPY_IMAGE:
3484 case OPERATION_NAME_READ_COPY_IMAGE_TO_BUFFER:
3485 return resourceDesc.type == RESOURCE_TYPE_IMAGE;
3487 case OPERATION_NAME_WRITE_CLEAR_ATTACHMENTS:
3488 return resourceDesc.type == RESOURCE_TYPE_IMAGE && resourceDesc.imageType != VK_IMAGE_TYPE_3D;
3490 case OPERATION_NAME_WRITE_BLIT_IMAGE:
3491 case OPERATION_NAME_READ_BLIT_IMAGE:
3492 case OPERATION_NAME_WRITE_IMAGE_VERTEX:
3493 case OPERATION_NAME_WRITE_IMAGE_TESSELLATION_CONTROL:
3494 case OPERATION_NAME_WRITE_IMAGE_TESSELLATION_EVALUATION:
3495 case OPERATION_NAME_WRITE_IMAGE_GEOMETRY:
3496 case OPERATION_NAME_WRITE_IMAGE_FRAGMENT:
3497 case OPERATION_NAME_WRITE_IMAGE_COMPUTE:
3498 case OPERATION_NAME_WRITE_IMAGE_COMPUTE_INDIRECT:
3499 case OPERATION_NAME_READ_IMAGE_VERTEX:
3500 case OPERATION_NAME_READ_IMAGE_TESSELLATION_CONTROL:
3501 case OPERATION_NAME_READ_IMAGE_TESSELLATION_EVALUATION:
3502 case OPERATION_NAME_READ_IMAGE_GEOMETRY:
3503 case OPERATION_NAME_READ_IMAGE_FRAGMENT:
3504 case OPERATION_NAME_READ_IMAGE_COMPUTE:
3505 case OPERATION_NAME_READ_IMAGE_COMPUTE_INDIRECT:
3506 return resourceDesc.type == RESOURCE_TYPE_IMAGE && resourceDesc.imageAspect == VK_IMAGE_ASPECT_COLOR_BIT;
3508 case OPERATION_NAME_READ_UBO_VERTEX:
3509 case OPERATION_NAME_READ_UBO_TESSELLATION_CONTROL:
3510 case OPERATION_NAME_READ_UBO_TESSELLATION_EVALUATION:
3511 case OPERATION_NAME_READ_UBO_GEOMETRY:
3512 case OPERATION_NAME_READ_UBO_FRAGMENT:
3513 case OPERATION_NAME_READ_UBO_COMPUTE:
3514 case OPERATION_NAME_READ_UBO_COMPUTE_INDIRECT:
3515 return resourceDesc.type == RESOURCE_TYPE_BUFFER && resourceDesc.size.x() <= MAX_UBO_RANGE;
3517 case OPERATION_NAME_WRITE_CLEAR_COLOR_IMAGE:
3518 return resourceDesc.type == RESOURCE_TYPE_IMAGE && resourceDesc.imageAspect == VK_IMAGE_ASPECT_COLOR_BIT;
3520 case OPERATION_NAME_WRITE_CLEAR_DEPTH_STENCIL_IMAGE:
3521 return resourceDesc.type == RESOURCE_TYPE_IMAGE && (resourceDesc.imageAspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT));
3523 case OPERATION_NAME_WRITE_DRAW:
3524 case OPERATION_NAME_WRITE_DRAW_INDEXED:
3525 case OPERATION_NAME_WRITE_DRAW_INDIRECT:
3526 case OPERATION_NAME_WRITE_DRAW_INDEXED_INDIRECT:
3527 return resourceDesc.type == RESOURCE_TYPE_IMAGE && resourceDesc.imageType == VK_IMAGE_TYPE_2D
3528 && (resourceDesc.imageAspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) == 0;
3536 std::string getOperationName (const OperationName opName)
3540 case OPERATION_NAME_WRITE_FILL_BUFFER: return "write_fill_buffer";
3541 case OPERATION_NAME_WRITE_UPDATE_BUFFER: return "write_update_buffer";
3542 case OPERATION_NAME_WRITE_COPY_BUFFER: return "write_copy_buffer";
3543 case OPERATION_NAME_WRITE_COPY_BUFFER_TO_IMAGE: return "write_copy_buffer_to_image";
3544 case OPERATION_NAME_WRITE_COPY_IMAGE_TO_BUFFER: return "write_copy_image_to_buffer";
3545 case OPERATION_NAME_WRITE_COPY_IMAGE: return "write_copy_image";
3546 case OPERATION_NAME_WRITE_BLIT_IMAGE: return "write_blit_image";
3547 case OPERATION_NAME_WRITE_SSBO_VERTEX: return "write_ssbo_vertex";
3548 case OPERATION_NAME_WRITE_SSBO_TESSELLATION_CONTROL: return "write_ssbo_tess_control";
3549 case OPERATION_NAME_WRITE_SSBO_TESSELLATION_EVALUATION: return "write_ssbo_tess_eval";
3550 case OPERATION_NAME_WRITE_SSBO_GEOMETRY: return "write_ssbo_geometry";
3551 case OPERATION_NAME_WRITE_SSBO_FRAGMENT: return "write_ssbo_fragment";
3552 case OPERATION_NAME_WRITE_SSBO_COMPUTE: return "write_ssbo_compute";
3553 case OPERATION_NAME_WRITE_SSBO_COMPUTE_INDIRECT: return "write_ssbo_compute_indirect";
3554 case OPERATION_NAME_WRITE_IMAGE_VERTEX: return "write_image_vertex";
3555 case OPERATION_NAME_WRITE_IMAGE_TESSELLATION_CONTROL: return "write_image_tess_control";
3556 case OPERATION_NAME_WRITE_IMAGE_TESSELLATION_EVALUATION: return "write_image_tess_eval";
3557 case OPERATION_NAME_WRITE_IMAGE_GEOMETRY: return "write_image_geometry";
3558 case OPERATION_NAME_WRITE_IMAGE_FRAGMENT: return "write_image_fragment";
3559 case OPERATION_NAME_WRITE_IMAGE_COMPUTE: return "write_image_compute";
3560 case OPERATION_NAME_WRITE_IMAGE_COMPUTE_INDIRECT: return "write_image_compute_indirect";
3561 case OPERATION_NAME_WRITE_CLEAR_COLOR_IMAGE: return "write_clear_color_image";
3562 case OPERATION_NAME_WRITE_CLEAR_DEPTH_STENCIL_IMAGE: return "write_clear_depth_stencil_image";
3563 case OPERATION_NAME_WRITE_DRAW: return "write_draw";
3564 case OPERATION_NAME_WRITE_DRAW_INDEXED: return "write_draw_indexed";
3565 case OPERATION_NAME_WRITE_DRAW_INDIRECT: return "write_draw_indirect";
3566 case OPERATION_NAME_WRITE_DRAW_INDEXED_INDIRECT: return "write_draw_indexed_indirect";
3567 case OPERATION_NAME_WRITE_CLEAR_ATTACHMENTS: return "write_clear_attachments";
3568 case OPERATION_NAME_WRITE_INDIRECT_BUFFER_DRAW: return "write_indirect_buffer_draw";
3569 case OPERATION_NAME_WRITE_INDIRECT_BUFFER_DRAW_INDEXED: return "write_indirect_buffer_draw_indexed";
3570 case OPERATION_NAME_WRITE_INDIRECT_BUFFER_DISPATCH: return "write_indirect_buffer_dispatch";
3572 case OPERATION_NAME_READ_COPY_BUFFER: return "read_copy_buffer";
3573 case OPERATION_NAME_READ_COPY_BUFFER_TO_IMAGE: return "read_copy_buffer_to_image";
3574 case OPERATION_NAME_READ_COPY_IMAGE_TO_BUFFER: return "read_copy_image_to_buffer";
3575 case OPERATION_NAME_READ_COPY_IMAGE: return "read_copy_image";
3576 case OPERATION_NAME_READ_BLIT_IMAGE: return "read_blit_image";
3577 case OPERATION_NAME_READ_UBO_VERTEX: return "read_ubo_vertex";
3578 case OPERATION_NAME_READ_UBO_TESSELLATION_CONTROL: return "read_ubo_tess_control";
3579 case OPERATION_NAME_READ_UBO_TESSELLATION_EVALUATION: return "read_ubo_tess_eval";
3580 case OPERATION_NAME_READ_UBO_GEOMETRY: return "read_ubo_geometry";
3581 case OPERATION_NAME_READ_UBO_FRAGMENT: return "read_ubo_fragment";
3582 case OPERATION_NAME_READ_UBO_COMPUTE: return "read_ubo_compute";
3583 case OPERATION_NAME_READ_UBO_COMPUTE_INDIRECT: return "read_ubo_compute_indirect";
3584 case OPERATION_NAME_READ_SSBO_VERTEX: return "read_ssbo_vertex";
3585 case OPERATION_NAME_READ_SSBO_TESSELLATION_CONTROL: return "read_ssbo_tess_control";
3586 case OPERATION_NAME_READ_SSBO_TESSELLATION_EVALUATION: return "read_ssbo_tess_eval";
3587 case OPERATION_NAME_READ_SSBO_GEOMETRY: return "read_ssbo_geometry";
3588 case OPERATION_NAME_READ_SSBO_FRAGMENT: return "read_ssbo_fragment";
3589 case OPERATION_NAME_READ_SSBO_COMPUTE: return "read_ssbo_compute";
3590 case OPERATION_NAME_READ_SSBO_COMPUTE_INDIRECT: return "read_ssbo_compute_indirect";
3591 case OPERATION_NAME_READ_IMAGE_VERTEX: return "read_image_vertex";
3592 case OPERATION_NAME_READ_IMAGE_TESSELLATION_CONTROL: return "read_image_tess_control";
3593 case OPERATION_NAME_READ_IMAGE_TESSELLATION_EVALUATION: return "read_image_tess_eval";
3594 case OPERATION_NAME_READ_IMAGE_GEOMETRY: return "read_image_geometry";
3595 case OPERATION_NAME_READ_IMAGE_FRAGMENT: return "read_image_fragment";
3596 case OPERATION_NAME_READ_IMAGE_COMPUTE: return "read_image_compute";
3597 case OPERATION_NAME_READ_IMAGE_COMPUTE_INDIRECT: return "read_image_compute_indirect";
3598 case OPERATION_NAME_READ_INDIRECT_BUFFER_DRAW: return "read_indirect_buffer_draw";
3599 case OPERATION_NAME_READ_INDIRECT_BUFFER_DRAW_INDEXED: return "read_indirect_buffer_draw_indexed";
3600 case OPERATION_NAME_READ_INDIRECT_BUFFER_DISPATCH: return "read_indirect_buffer_dispatch";
3601 case OPERATION_NAME_READ_VERTEX_INPUT: return "read_vertex_input";
3609 de::MovePtr<OperationSupport> makeOperationSupport (const OperationName opName, const ResourceDescription& resourceDesc)
3613 case OPERATION_NAME_WRITE_FILL_BUFFER: return de::MovePtr<OperationSupport>(new FillUpdateBuffer ::Support (resourceDesc, FillUpdateBuffer::BUFFER_OP_FILL));
3614 case OPERATION_NAME_WRITE_UPDATE_BUFFER: return de::MovePtr<OperationSupport>(new FillUpdateBuffer ::Support (resourceDesc, FillUpdateBuffer::BUFFER_OP_UPDATE));
3615 case OPERATION_NAME_WRITE_COPY_BUFFER: return de::MovePtr<OperationSupport>(new CopyBuffer ::Support (resourceDesc, ACCESS_MODE_WRITE));
3616 case OPERATION_NAME_WRITE_COPY_BUFFER_TO_IMAGE: return de::MovePtr<OperationSupport>(new CopyBufferToImage ::Support (resourceDesc, ACCESS_MODE_WRITE));
3617 case OPERATION_NAME_WRITE_COPY_IMAGE_TO_BUFFER: return de::MovePtr<OperationSupport>(new CopyImageToBuffer ::Support (resourceDesc, ACCESS_MODE_WRITE));
3618 case OPERATION_NAME_WRITE_COPY_IMAGE: return de::MovePtr<OperationSupport>(new CopyBlitImage ::Support (resourceDesc, CopyBlitImage::TYPE_COPY, ACCESS_MODE_WRITE));
3619 case OPERATION_NAME_WRITE_BLIT_IMAGE: return de::MovePtr<OperationSupport>(new CopyBlitImage ::Support (resourceDesc, CopyBlitImage::TYPE_BLIT, ACCESS_MODE_WRITE));
3620 case OPERATION_NAME_WRITE_SSBO_VERTEX: return de::MovePtr<OperationSupport>(new ShaderAccess ::BufferSupport (resourceDesc, BUFFER_TYPE_STORAGE, ACCESS_MODE_WRITE, VK_SHADER_STAGE_VERTEX_BIT));
3621 case OPERATION_NAME_WRITE_SSBO_TESSELLATION_CONTROL: return de::MovePtr<OperationSupport>(new ShaderAccess ::BufferSupport (resourceDesc, BUFFER_TYPE_STORAGE, ACCESS_MODE_WRITE, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT));
3622 case OPERATION_NAME_WRITE_SSBO_TESSELLATION_EVALUATION: return de::MovePtr<OperationSupport>(new ShaderAccess ::BufferSupport (resourceDesc, BUFFER_TYPE_STORAGE, ACCESS_MODE_WRITE, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT));
3623 case OPERATION_NAME_WRITE_SSBO_GEOMETRY: return de::MovePtr<OperationSupport>(new ShaderAccess ::BufferSupport (resourceDesc, BUFFER_TYPE_STORAGE, ACCESS_MODE_WRITE, VK_SHADER_STAGE_GEOMETRY_BIT));
3624 case OPERATION_NAME_WRITE_SSBO_FRAGMENT: return de::MovePtr<OperationSupport>(new ShaderAccess ::BufferSupport (resourceDesc, BUFFER_TYPE_STORAGE, ACCESS_MODE_WRITE, VK_SHADER_STAGE_FRAGMENT_BIT));
3625 case OPERATION_NAME_WRITE_SSBO_COMPUTE: return de::MovePtr<OperationSupport>(new ShaderAccess ::BufferSupport (resourceDesc, BUFFER_TYPE_STORAGE, ACCESS_MODE_WRITE, VK_SHADER_STAGE_COMPUTE_BIT));
3626 case OPERATION_NAME_WRITE_SSBO_COMPUTE_INDIRECT: return de::MovePtr<OperationSupport>(new ShaderAccess ::BufferSupport (resourceDesc, BUFFER_TYPE_STORAGE, ACCESS_MODE_WRITE, VK_SHADER_STAGE_COMPUTE_BIT, ShaderAccess::DISPATCH_CALL_DISPATCH_INDIRECT));
3627 case OPERATION_NAME_WRITE_IMAGE_VERTEX: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_WRITE, VK_SHADER_STAGE_VERTEX_BIT));
3628 case OPERATION_NAME_WRITE_IMAGE_TESSELLATION_CONTROL: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_WRITE, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT));
3629 case OPERATION_NAME_WRITE_IMAGE_TESSELLATION_EVALUATION: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_WRITE, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT));
3630 case OPERATION_NAME_WRITE_IMAGE_GEOMETRY: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_WRITE, VK_SHADER_STAGE_GEOMETRY_BIT));
3631 case OPERATION_NAME_WRITE_IMAGE_FRAGMENT: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_WRITE, VK_SHADER_STAGE_FRAGMENT_BIT));
3632 case OPERATION_NAME_WRITE_IMAGE_COMPUTE: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_WRITE, VK_SHADER_STAGE_COMPUTE_BIT));
3633 case OPERATION_NAME_WRITE_IMAGE_COMPUTE_INDIRECT: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_WRITE, VK_SHADER_STAGE_COMPUTE_BIT, ShaderAccess::DISPATCH_CALL_DISPATCH_INDIRECT));
3634 case OPERATION_NAME_WRITE_CLEAR_COLOR_IMAGE: return de::MovePtr<OperationSupport>(new ClearImage ::Support (resourceDesc, ClearImage::CLEAR_MODE_COLOR));
3635 case OPERATION_NAME_WRITE_CLEAR_DEPTH_STENCIL_IMAGE: return de::MovePtr<OperationSupport>(new ClearImage ::Support (resourceDesc, ClearImage::CLEAR_MODE_DEPTH_STENCIL));
3636 case OPERATION_NAME_WRITE_DRAW: return de::MovePtr<OperationSupport>(new Draw ::Support (resourceDesc, Draw::DRAW_CALL_DRAW));
3637 case OPERATION_NAME_WRITE_DRAW_INDEXED: return de::MovePtr<OperationSupport>(new Draw ::Support (resourceDesc, Draw::DRAW_CALL_DRAW_INDEXED));
3638 case OPERATION_NAME_WRITE_DRAW_INDIRECT: return de::MovePtr<OperationSupport>(new Draw ::Support (resourceDesc, Draw::DRAW_CALL_DRAW_INDIRECT));
3639 case OPERATION_NAME_WRITE_DRAW_INDEXED_INDIRECT: return de::MovePtr<OperationSupport>(new Draw ::Support (resourceDesc, Draw::DRAW_CALL_DRAW_INDEXED_INDIRECT));
3640 case OPERATION_NAME_WRITE_CLEAR_ATTACHMENTS: return de::MovePtr<OperationSupport>(new ClearAttachments ::Support (resourceDesc));
3641 case OPERATION_NAME_WRITE_INDIRECT_BUFFER_DRAW: return de::MovePtr<OperationSupport>(new IndirectBuffer ::WriteSupport (resourceDesc));
3642 case OPERATION_NAME_WRITE_INDIRECT_BUFFER_DRAW_INDEXED: return de::MovePtr<OperationSupport>(new IndirectBuffer ::WriteSupport (resourceDesc));
3643 case OPERATION_NAME_WRITE_INDIRECT_BUFFER_DISPATCH: return de::MovePtr<OperationSupport>(new IndirectBuffer ::WriteSupport (resourceDesc));
3645 case OPERATION_NAME_READ_COPY_BUFFER: return de::MovePtr<OperationSupport>(new CopyBuffer ::Support (resourceDesc, ACCESS_MODE_READ));
3646 case OPERATION_NAME_READ_COPY_BUFFER_TO_IMAGE: return de::MovePtr<OperationSupport>(new CopyBufferToImage ::Support (resourceDesc, ACCESS_MODE_READ));
3647 case OPERATION_NAME_READ_COPY_IMAGE_TO_BUFFER: return de::MovePtr<OperationSupport>(new CopyImageToBuffer ::Support (resourceDesc, ACCESS_MODE_READ));
3648 case OPERATION_NAME_READ_COPY_IMAGE: return de::MovePtr<OperationSupport>(new CopyBlitImage ::Support (resourceDesc, CopyBlitImage::TYPE_COPY, ACCESS_MODE_READ));
3649 case OPERATION_NAME_READ_BLIT_IMAGE: return de::MovePtr<OperationSupport>(new CopyBlitImage ::Support (resourceDesc, CopyBlitImage::TYPE_BLIT, ACCESS_MODE_READ));
3650 case OPERATION_NAME_READ_UBO_VERTEX: return de::MovePtr<OperationSupport>(new ShaderAccess ::BufferSupport (resourceDesc, BUFFER_TYPE_UNIFORM, ACCESS_MODE_READ, VK_SHADER_STAGE_VERTEX_BIT));
3651 case OPERATION_NAME_READ_UBO_TESSELLATION_CONTROL: return de::MovePtr<OperationSupport>(new ShaderAccess ::BufferSupport (resourceDesc, BUFFER_TYPE_UNIFORM, ACCESS_MODE_READ, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT));
3652 case OPERATION_NAME_READ_UBO_TESSELLATION_EVALUATION: return de::MovePtr<OperationSupport>(new ShaderAccess ::BufferSupport (resourceDesc, BUFFER_TYPE_UNIFORM, ACCESS_MODE_READ, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT));
3653 case OPERATION_NAME_READ_UBO_GEOMETRY: return de::MovePtr<OperationSupport>(new ShaderAccess ::BufferSupport (resourceDesc, BUFFER_TYPE_UNIFORM, ACCESS_MODE_READ, VK_SHADER_STAGE_GEOMETRY_BIT));
3654 case OPERATION_NAME_READ_UBO_FRAGMENT: return de::MovePtr<OperationSupport>(new ShaderAccess ::BufferSupport (resourceDesc, BUFFER_TYPE_UNIFORM, ACCESS_MODE_READ, VK_SHADER_STAGE_FRAGMENT_BIT));
3655 case OPERATION_NAME_READ_UBO_COMPUTE: return de::MovePtr<OperationSupport>(new ShaderAccess ::BufferSupport (resourceDesc, BUFFER_TYPE_UNIFORM, ACCESS_MODE_READ, VK_SHADER_STAGE_COMPUTE_BIT));
3656 case OPERATION_NAME_READ_UBO_COMPUTE_INDIRECT: return de::MovePtr<OperationSupport>(new ShaderAccess ::BufferSupport (resourceDesc, BUFFER_TYPE_UNIFORM, ACCESS_MODE_READ, VK_SHADER_STAGE_COMPUTE_BIT, ShaderAccess::DISPATCH_CALL_DISPATCH_INDIRECT));
3657 case OPERATION_NAME_READ_SSBO_VERTEX: return de::MovePtr<OperationSupport>(new ShaderAccess ::BufferSupport (resourceDesc, BUFFER_TYPE_STORAGE, ACCESS_MODE_READ, VK_SHADER_STAGE_VERTEX_BIT));
3658 case OPERATION_NAME_READ_SSBO_TESSELLATION_CONTROL: return de::MovePtr<OperationSupport>(new ShaderAccess ::BufferSupport (resourceDesc, BUFFER_TYPE_STORAGE, ACCESS_MODE_READ, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT));
3659 case OPERATION_NAME_READ_SSBO_TESSELLATION_EVALUATION: return de::MovePtr<OperationSupport>(new ShaderAccess ::BufferSupport (resourceDesc, BUFFER_TYPE_STORAGE, ACCESS_MODE_READ, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT));
3660 case OPERATION_NAME_READ_SSBO_GEOMETRY: return de::MovePtr<OperationSupport>(new ShaderAccess ::BufferSupport (resourceDesc, BUFFER_TYPE_STORAGE, ACCESS_MODE_READ, VK_SHADER_STAGE_GEOMETRY_BIT));
3661 case OPERATION_NAME_READ_SSBO_FRAGMENT: return de::MovePtr<OperationSupport>(new ShaderAccess ::BufferSupport (resourceDesc, BUFFER_TYPE_STORAGE, ACCESS_MODE_READ, VK_SHADER_STAGE_FRAGMENT_BIT));
3662 case OPERATION_NAME_READ_SSBO_COMPUTE: return de::MovePtr<OperationSupport>(new ShaderAccess ::BufferSupport (resourceDesc, BUFFER_TYPE_STORAGE, ACCESS_MODE_READ, VK_SHADER_STAGE_COMPUTE_BIT));
3663 case OPERATION_NAME_READ_SSBO_COMPUTE_INDIRECT: return de::MovePtr<OperationSupport>(new ShaderAccess ::BufferSupport (resourceDesc, BUFFER_TYPE_STORAGE, ACCESS_MODE_READ, VK_SHADER_STAGE_COMPUTE_BIT, ShaderAccess::DISPATCH_CALL_DISPATCH_INDIRECT));
3664 case OPERATION_NAME_READ_IMAGE_VERTEX: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_READ, VK_SHADER_STAGE_VERTEX_BIT));
3665 case OPERATION_NAME_READ_IMAGE_TESSELLATION_CONTROL: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_READ, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT));
3666 case OPERATION_NAME_READ_IMAGE_TESSELLATION_EVALUATION: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_READ, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT));
3667 case OPERATION_NAME_READ_IMAGE_GEOMETRY: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_READ, VK_SHADER_STAGE_GEOMETRY_BIT));
3668 case OPERATION_NAME_READ_IMAGE_FRAGMENT: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_READ, VK_SHADER_STAGE_FRAGMENT_BIT));
3669 case OPERATION_NAME_READ_IMAGE_COMPUTE: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_READ, VK_SHADER_STAGE_COMPUTE_BIT));
3670 case OPERATION_NAME_READ_IMAGE_COMPUTE_INDIRECT: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_READ, VK_SHADER_STAGE_COMPUTE_BIT, ShaderAccess::DISPATCH_CALL_DISPATCH_INDIRECT));
3671 case OPERATION_NAME_READ_INDIRECT_BUFFER_DRAW: return de::MovePtr<OperationSupport>(new IndirectBuffer ::ReadSupport (resourceDesc));
3672 case OPERATION_NAME_READ_INDIRECT_BUFFER_DRAW_INDEXED: return de::MovePtr<OperationSupport>(new IndirectBuffer ::ReadSupport (resourceDesc));
3673 case OPERATION_NAME_READ_INDIRECT_BUFFER_DISPATCH: return de::MovePtr<OperationSupport>(new IndirectBuffer ::ReadSupport (resourceDesc));
3674 case OPERATION_NAME_READ_VERTEX_INPUT: return de::MovePtr<OperationSupport>(new VertexInput ::Support (resourceDesc));
3678 return de::MovePtr<OperationSupport>();
3682 } // synchronization