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)
91 : m_vertexFormat (VK_FORMAT_R32G32B32A32_SFLOAT)
92 , m_vertexStride (tcu::getPixelSize(mapVkFormat(m_vertexFormat)))
94 const DeviceInterface& vk = context.getDeviceInterface();
95 const VkDevice device = context.getDevice();
96 Allocator& allocator = context.getAllocator();
100 m_vertexData.push_back(tcu::Vec4( 1.0f, 1.0f, 0.0f, 1.0f));
101 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));
104 m_vertexData.push_back(tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f));
105 m_vertexData.push_back(tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f));
106 m_vertexData.push_back(tcu::Vec4( 1.0f, 1.0f, 0.0f, 1.0f));
110 const VkDeviceSize vertexDataSizeBytes = m_vertexData.size() * sizeof(m_vertexData[0]);
112 m_vertexBuffer = de::MovePtr<Buffer>(new Buffer(vk, device, allocator, 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();
118 deMemcpy(alloc.getHostPtr(), &m_vertexData[0], static_cast<std::size_t>(vertexDataSizeBytes));
119 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), vertexDataSizeBytes);
125 const VkDeviceSize indexBufferSizeBytes = sizeof(deUint32) * m_vertexData.size();
126 const deUint32 numIndices = static_cast<deUint32>(m_vertexData.size());
128 m_indexBuffer = de::MovePtr<Buffer>(new Buffer(vk, device, allocator, makeBufferCreateInfo(indexBufferSizeBytes, VK_BUFFER_USAGE_INDEX_BUFFER_BIT), MemoryRequirement::HostVisible));
131 const Allocation& alloc = m_indexBuffer->getAllocation();
132 deUint32* const pData = static_cast<deUint32*>(alloc.getHostPtr());
134 for (deUint32 i = 0; i < numIndices; ++i)
137 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), indexBufferSizeBytes);
142 VkFormat getVertexFormat (void) const { return m_vertexFormat; }
143 deUint32 getVertexStride (void) const { return m_vertexStride; }
144 VkIndexType getIndexType (void) const { return VK_INDEX_TYPE_UINT32; }
145 deUint32 getNumVertices (void) const { return static_cast<deUint32>(m_vertexData.size()); }
146 deUint32 getNumIndices (void) const { return getNumVertices(); }
147 VkBuffer getVertexBuffer (void) const { return **m_vertexBuffer; }
148 VkBuffer getIndexBuffer (void) const { return **m_indexBuffer; }
151 const VkFormat m_vertexFormat;
152 const deUint32 m_vertexStride;
153 std::vector<tcu::Vec4> m_vertexData;
154 de::MovePtr<Buffer> m_vertexBuffer;
155 de::MovePtr<Buffer> m_indexBuffer;
158 //! Add flags for all shader stages required to support a particular stage (e.g. fragment requires vertex as well).
159 VkShaderStageFlags getRequiredStages (const VkShaderStageFlagBits stage)
161 VkShaderStageFlags flags = 0;
163 DE_ASSERT(stage == VK_SHADER_STAGE_COMPUTE_BIT || (stage & VK_SHADER_STAGE_COMPUTE_BIT) == 0);
165 if (stage & VK_SHADER_STAGE_ALL_GRAPHICS)
166 flags |= VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
168 if (stage & (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT))
169 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;
174 if (stage & VK_SHADER_STAGE_COMPUTE_BIT)
175 flags |= VK_SHADER_STAGE_COMPUTE_BIT;
180 //! Check that SSBO read/write is available and that all shader stages are supported.
181 void requireFeaturesForSSBOAccess (OperationContext& context, const VkShaderStageFlags usedStages)
183 const InstanceInterface& vki = context.getInstanceInterface();
184 const VkPhysicalDevice physDevice = context.getPhysicalDevice();
185 FeatureFlags flags = (FeatureFlags)0;
187 if (usedStages & VK_SHADER_STAGE_FRAGMENT_BIT)
188 flags |= FEATURE_FRAGMENT_STORES_AND_ATOMICS;
190 if (usedStages & (VK_SHADER_STAGE_ALL_GRAPHICS & (~VK_SHADER_STAGE_FRAGMENT_BIT)))
191 flags |= FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS;
193 if (usedStages & VK_SHADER_STAGE_GEOMETRY_BIT)
194 flags |= FEATURE_GEOMETRY_SHADER;
196 if (usedStages & (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT))
197 flags |= FEATURE_TESSELLATION_SHADER;
199 requireFeatures(vki, physDevice, flags);
202 Data getHostBufferData (const OperationContext& context, const Buffer& hostBuffer, const VkDeviceSize size)
204 const DeviceInterface& vk = context.getDeviceInterface();
205 const VkDevice device = context.getDevice();
206 const Allocation& alloc = hostBuffer.getAllocation();
209 static_cast<std::size_t>(size), // std::size_t size;
210 static_cast<deUint8*>(alloc.getHostPtr()), // const deUint8* data;
213 invalidateMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), size);
218 void assertValidShaderStage (const VkShaderStageFlagBits stage)
222 case VK_SHADER_STAGE_VERTEX_BIT:
223 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
224 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
225 case VK_SHADER_STAGE_GEOMETRY_BIT:
226 case VK_SHADER_STAGE_FRAGMENT_BIT:
227 case VK_SHADER_STAGE_COMPUTE_BIT:
232 DE_FATAL("Invalid shader stage");
237 VkPipelineStageFlags pipelineStageFlagsFromShaderStageFlagBits (const VkShaderStageFlagBits shaderStage)
241 case VK_SHADER_STAGE_VERTEX_BIT: return VK_PIPELINE_STAGE_VERTEX_SHADER_BIT;
242 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: return VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT;
243 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: return VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT;
244 case VK_SHADER_STAGE_GEOMETRY_BIT: return VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT;
245 case VK_SHADER_STAGE_FRAGMENT_BIT: return VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
246 case VK_SHADER_STAGE_COMPUTE_BIT: return VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
248 // Other usages are probably an error, so flag that.
250 DE_FATAL("Invalid shader stage");
251 return (VkPipelineStageFlags)0;
255 //! Fill destination buffer with a repeating pattern.
256 void fillPattern (void* const pData, const VkDeviceSize size)
258 static const deUint8 pattern[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31 };
259 deUint8* const pBytes = static_cast<deUint8*>(pData);
261 for (deUint32 i = 0; i < size; ++i)
262 pBytes[i] = pattern[i % DE_LENGTH_OF_ARRAY(pattern)];
265 //! Get size in bytes of a pixel buffer with given extent.
266 VkDeviceSize getPixelBufferSize (const VkFormat format, const VkExtent3D& extent)
268 const int pixelSize = tcu::getPixelSize(mapVkFormat(format));
269 return (pixelSize * extent.width * extent.height * extent.depth);
272 //! Determine the size of a 2D image that can hold sizeBytes data.
273 VkExtent3D get2DImageExtentWithSize (const VkDeviceSize sizeBytes, const deUint32 pixelSize)
275 const deUint32 size = static_cast<deUint32>(sizeBytes / pixelSize);
277 DE_ASSERT(size <= MAX_IMAGE_DIMENSION_2D * MAX_IMAGE_DIMENSION_2D);
280 std::min(size, static_cast<deUint32>(MAX_IMAGE_DIMENSION_2D)),
281 (size / MAX_IMAGE_DIMENSION_2D) + (size % MAX_IMAGE_DIMENSION_2D != 0 ? 1u : 0u),
285 VkClearValue makeClearValue (const VkFormat format)
287 if (isDepthStencilFormat(format))
288 return makeClearValueDepthStencil(0.4f, 21u);
291 if (isIntFormat(format) || isUintFormat(format))
292 return makeClearValueColorU32(8u, 16u, 24u, 32u);
294 return makeClearValueColorF32(0.25f, 0.49f, 0.75f, 1.0f);
298 void clearPixelBuffer (tcu::PixelBufferAccess& pixels, const VkClearValue& clearValue)
300 const tcu::TextureFormat format = pixels.getFormat();
301 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
303 if (format.order == tcu::TextureFormat::D)
305 for (int z = 0; z < pixels.getDepth(); z++)
306 for (int y = 0; y < pixels.getHeight(); y++)
307 for (int x = 0; x < pixels.getWidth(); x++)
308 pixels.setPixDepth(clearValue.depthStencil.depth, x, y, z);
310 else if (format.order == tcu::TextureFormat::S)
312 for (int z = 0; z < pixels.getDepth(); z++)
313 for (int y = 0; y < pixels.getHeight(); y++)
314 for (int x = 0; x < pixels.getWidth(); x++)
315 pixels.setPixStencil(clearValue.depthStencil.stencil, x, y, z);
317 else if (format.order == tcu::TextureFormat::DS)
319 for (int z = 0; z < pixels.getDepth(); z++)
320 for (int y = 0; y < pixels.getHeight(); y++)
321 for (int x = 0; x < pixels.getWidth(); x++)
323 pixels.setPixDepth(clearValue.depthStencil.depth, x, y, z);
324 pixels.setPixStencil(clearValue.depthStencil.stencil, x, y, z);
327 else if (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
329 const tcu::UVec4 color (clearValue.color.uint32);
331 for (int z = 0; z < pixels.getDepth(); z++)
332 for (int y = 0; y < pixels.getHeight(); y++)
333 for (int x = 0; x < pixels.getWidth(); x++)
334 pixels.setPixel(color, x, y, z);
338 const tcu::Vec4 color (clearValue.color.float32);
340 for (int z = 0; z < pixels.getDepth(); z++)
341 for (int y = 0; y < pixels.getHeight(); y++)
342 for (int x = 0; x < pixels.getWidth(); x++)
343 pixels.setPixel(color, x, y, z);
347 //! Storage image format that requires StorageImageExtendedFormats SPIR-V capability (listed only Vulkan-defined formats).
348 bool isStorageImageExtendedFormat (const VkFormat format)
352 case VK_FORMAT_R32G32_SFLOAT:
353 case VK_FORMAT_R32G32_SINT:
354 case VK_FORMAT_R32G32_UINT:
355 case VK_FORMAT_R16G16B16A16_UNORM:
356 case VK_FORMAT_R16G16B16A16_SNORM:
357 case VK_FORMAT_R16G16_SFLOAT:
358 case VK_FORMAT_R16G16_UNORM:
359 case VK_FORMAT_R16G16_SNORM:
360 case VK_FORMAT_R16G16_SINT:
361 case VK_FORMAT_R16G16_UINT:
362 case VK_FORMAT_R16_SFLOAT:
363 case VK_FORMAT_R16_UNORM:
364 case VK_FORMAT_R16_SNORM:
365 case VK_FORMAT_R16_SINT:
366 case VK_FORMAT_R16_UINT:
367 case VK_FORMAT_R8G8_UNORM:
368 case VK_FORMAT_R8G8_SNORM:
369 case VK_FORMAT_R8G8_SINT:
370 case VK_FORMAT_R8G8_UINT:
371 case VK_FORMAT_R8_UNORM:
372 case VK_FORMAT_R8_SNORM:
373 case VK_FORMAT_R8_SINT:
374 case VK_FORMAT_R8_UINT:
382 VkImageViewType getImageViewType (const VkImageType imageType)
386 case VK_IMAGE_TYPE_1D: return VK_IMAGE_VIEW_TYPE_1D;
387 case VK_IMAGE_TYPE_2D: return VK_IMAGE_VIEW_TYPE_2D;
388 case VK_IMAGE_TYPE_3D: return VK_IMAGE_VIEW_TYPE_3D;
391 DE_FATAL("Unknown image type");
392 return VK_IMAGE_VIEW_TYPE_LAST;
396 std::string getShaderImageType (const VkFormat format, const VkImageType imageType)
398 const tcu::TextureFormat texFormat = mapVkFormat(format);
399 const std::string formatPart = tcu::getTextureChannelClass(texFormat.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ? "u" :
400 tcu::getTextureChannelClass(texFormat.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ? "i" : "";
403 case VK_IMAGE_TYPE_1D: return formatPart + "image1D";
404 case VK_IMAGE_TYPE_2D: return formatPart + "image2D";
405 case VK_IMAGE_TYPE_3D: return formatPart + "image3D";
408 DE_FATAL("Unknown image type");
413 std::string getShaderImageFormatQualifier (const VkFormat format)
415 const tcu::TextureFormat texFormat = mapVkFormat(format);
416 const char* orderPart = DE_NULL;
417 const char* typePart = DE_NULL;
419 switch (texFormat.order)
421 case tcu::TextureFormat::R: orderPart = "r"; break;
422 case tcu::TextureFormat::RG: orderPart = "rg"; break;
423 case tcu::TextureFormat::RGB: orderPart = "rgb"; break;
424 case tcu::TextureFormat::RGBA: orderPart = "rgba"; break;
427 DE_FATAL("Unksupported texture channel order");
431 switch (texFormat.type)
433 case tcu::TextureFormat::FLOAT: typePart = "32f"; break;
434 case tcu::TextureFormat::HALF_FLOAT: typePart = "16f"; break;
436 case tcu::TextureFormat::UNSIGNED_INT32: typePart = "32ui"; break;
437 case tcu::TextureFormat::UNSIGNED_INT16: typePart = "16ui"; break;
438 case tcu::TextureFormat::UNSIGNED_INT8: typePart = "8ui"; break;
440 case tcu::TextureFormat::SIGNED_INT32: typePart = "32i"; break;
441 case tcu::TextureFormat::SIGNED_INT16: typePart = "16i"; break;
442 case tcu::TextureFormat::SIGNED_INT8: typePart = "8i"; break;
444 case tcu::TextureFormat::UNORM_INT16: typePart = "16"; break;
445 case tcu::TextureFormat::UNORM_INT8: typePart = "8"; break;
447 case tcu::TextureFormat::SNORM_INT16: typePart = "16_snorm"; break;
448 case tcu::TextureFormat::SNORM_INT8: typePart = "8_snorm"; break;
451 DE_FATAL("Unksupported texture channel type");
455 return std::string(orderPart) + typePart;
458 namespace FillUpdateBuffer
467 class Implementation : public Operation
470 Implementation (OperationContext& context, Resource& resource, const BufferOp bufferOp)
471 : m_context (context)
472 , m_resource (resource)
474 , m_bufferOp (bufferOp)
476 DE_ASSERT((m_resource.getBuffer().size % sizeof(deUint32)) == 0);
477 DE_ASSERT(m_bufferOp == BUFFER_OP_FILL || m_resource.getBuffer().size <= MAX_UPDATE_BUFFER_SIZE);
479 m_data.resize(static_cast<size_t>(m_resource.getBuffer().size));
481 if (m_bufferOp == BUFFER_OP_FILL)
483 const std::size_t size = m_data.size() / sizeof(m_fillValue);
484 deUint32* const pData = reinterpret_cast<deUint32*>(&m_data[0]);
486 for (deUint32 i = 0; i < size; ++i)
487 pData[i] = m_fillValue;
489 else if (m_bufferOp == BUFFER_OP_UPDATE)
491 fillPattern(&m_data[0], m_data.size());
500 void recordCommands (const VkCommandBuffer cmdBuffer)
502 const DeviceInterface& vk = m_context.getDeviceInterface();
504 if (m_bufferOp == BUFFER_OP_FILL)
505 vk.cmdFillBuffer(cmdBuffer, m_resource.getBuffer().handle, m_resource.getBuffer().offset, m_resource.getBuffer().size, m_fillValue);
506 else if (m_bufferOp == BUFFER_OP_UPDATE)
507 vk.cmdUpdateBuffer(cmdBuffer, m_resource.getBuffer().handle, m_resource.getBuffer().offset, m_resource.getBuffer().size, reinterpret_cast<deUint32*>(&m_data[0]));
515 SyncInfo getSyncInfo (void) const
517 const SyncInfo syncInfo =
519 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
520 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags accessMask;
521 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
527 Data getData (void) const
531 m_data.size(), // std::size_t size;
532 &m_data[0], // const deUint8* data;
538 OperationContext& m_context;
539 Resource& m_resource;
540 std::vector<deUint8> m_data;
541 const deUint32 m_fillValue;
542 const BufferOp m_bufferOp;
545 class Support : public OperationSupport
548 Support (const ResourceDescription& resourceDesc, const BufferOp bufferOp)
549 : m_resourceDesc (resourceDesc)
550 , m_bufferOp (bufferOp)
552 DE_ASSERT(m_bufferOp == BUFFER_OP_FILL || m_bufferOp == BUFFER_OP_UPDATE);
553 DE_ASSERT(m_resourceDesc.type == RESOURCE_TYPE_BUFFER);
556 deUint32 getResourceUsageFlags (void) const
558 return VK_BUFFER_USAGE_TRANSFER_DST_BIT;
561 VkQueueFlags getQueueFlags (const OperationContext& context) const
563 if (m_bufferOp == BUFFER_OP_FILL &&
564 !de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_KHR_maintenance1"))
566 return VK_QUEUE_COMPUTE_BIT | VK_QUEUE_GRAPHICS_BIT;
569 return VK_QUEUE_TRANSFER_BIT;
572 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
574 return de::MovePtr<Operation>(new Implementation(context, resource, m_bufferOp));
578 const ResourceDescription m_resourceDesc;
579 const BufferOp m_bufferOp;
582 } // FillUpdateBuffer ns
587 class Implementation : public Operation
590 Implementation (OperationContext& context, Resource& resource, const AccessMode mode)
591 : m_context (context)
592 , m_resource (resource)
595 const DeviceInterface& vk = m_context.getDeviceInterface();
596 const VkDevice device = m_context.getDevice();
597 Allocator& allocator = m_context.getAllocator();
598 const VkBufferUsageFlags hostBufferUsage = (m_mode == ACCESS_MODE_READ ? VK_BUFFER_USAGE_TRANSFER_DST_BIT : VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
600 m_hostBuffer = de::MovePtr<Buffer>(new Buffer(vk, device, allocator, makeBufferCreateInfo(m_resource.getBuffer().size, hostBufferUsage), MemoryRequirement::HostVisible));
602 const Allocation& alloc = m_hostBuffer->getAllocation();
604 if (m_mode == ACCESS_MODE_READ)
605 deMemset(alloc.getHostPtr(), 0, static_cast<size_t>(m_resource.getBuffer().size));
607 fillPattern(alloc.getHostPtr(), m_resource.getBuffer().size);
609 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), m_resource.getBuffer().size);
612 void recordCommands (const VkCommandBuffer cmdBuffer)
614 const DeviceInterface& vk = m_context.getDeviceInterface();
615 const VkBufferCopy copyRegion = makeBufferCopy(0u, 0u, m_resource.getBuffer().size);
617 if (m_mode == ACCESS_MODE_READ)
619 vk.cmdCopyBuffer(cmdBuffer, m_resource.getBuffer().handle, **m_hostBuffer, 1u, ©Region);
621 // Insert a barrier so copied data is available to the host
622 const VkBufferMemoryBarrier barrier = makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, **m_hostBuffer, 0u, m_resource.getBuffer().size);
623 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
626 vk.cmdCopyBuffer(cmdBuffer, **m_hostBuffer, m_resource.getBuffer().handle, 1u, ©Region);
629 SyncInfo getSyncInfo (void) const
631 const VkAccessFlags access = (m_mode == ACCESS_MODE_READ ? VK_ACCESS_TRANSFER_READ_BIT : VK_ACCESS_TRANSFER_WRITE_BIT);
632 const SyncInfo syncInfo =
634 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
635 access, // VkAccessFlags accessMask;
636 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
641 Data getData (void) const
643 return getHostBufferData(m_context, *m_hostBuffer, m_resource.getBuffer().size);
647 OperationContext& m_context;
648 Resource& m_resource;
649 const AccessMode m_mode;
650 de::MovePtr<Buffer> m_hostBuffer;
653 class Support : public OperationSupport
656 Support (const ResourceDescription& resourceDesc, const AccessMode mode)
659 DE_ASSERT(resourceDesc.type == RESOURCE_TYPE_BUFFER);
660 DE_UNREF(resourceDesc);
663 deUint32 getResourceUsageFlags (void) const
665 return (m_mode == ACCESS_MODE_READ ? VK_BUFFER_USAGE_TRANSFER_SRC_BIT : VK_BUFFER_USAGE_TRANSFER_DST_BIT);
668 VkQueueFlags getQueueFlags (const OperationContext& context) const
671 return VK_QUEUE_TRANSFER_BIT;
674 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
676 return de::MovePtr<Operation>(new Implementation(context, resource, m_mode));
680 const AccessMode m_mode;
685 namespace CopyBlitImage
688 class ImplementationBase : public Operation
691 //! Copy/Blit/Resolve etc. operation
692 virtual void recordCopyCommand (const VkCommandBuffer cmdBuffer) = 0;
694 ImplementationBase (OperationContext& context, Resource& resource, const AccessMode mode)
695 : m_context (context)
696 , m_resource (resource)
698 , m_bufferSize (getPixelBufferSize(m_resource.getImage().format, m_resource.getImage().extent))
700 const DeviceInterface& vk = m_context.getDeviceInterface();
701 const VkDevice device = m_context.getDevice();
702 Allocator& allocator = m_context.getAllocator();
704 m_hostBuffer = de::MovePtr<Buffer>(new Buffer(
705 vk, device, allocator, makeBufferCreateInfo(m_bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT),
706 MemoryRequirement::HostVisible));
708 const Allocation& alloc = m_hostBuffer->getAllocation();
709 if (m_mode == ACCESS_MODE_READ)
710 deMemset(alloc.getHostPtr(), 0, static_cast<size_t>(m_bufferSize));
712 fillPattern(alloc.getHostPtr(), m_bufferSize);
713 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), m_bufferSize);
716 m_image = de::MovePtr<Image>(new Image(
717 vk, device, allocator,
718 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),
719 MemoryRequirement::Any));
722 void recordCommands (const VkCommandBuffer cmdBuffer)
724 const DeviceInterface& vk = m_context.getDeviceInterface();
725 const VkBufferImageCopy bufferCopyRegion = makeBufferImageCopy(m_resource.getImage().subresourceLayers, m_resource.getImage().extent);
727 const VkImageMemoryBarrier stagingImageTransferSrcLayoutBarrier = makeImageMemoryBarrier(
728 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
729 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
730 **m_image, m_resource.getImage().subresourceRange);
732 // Staging image layout
734 const VkImageMemoryBarrier layoutBarrier = makeImageMemoryBarrier(
735 (VkAccessFlags)0, VK_ACCESS_TRANSFER_WRITE_BIT,
736 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
737 **m_image, m_resource.getImage().subresourceRange);
739 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
740 0u, DE_NULL, 0u, DE_NULL, 1u, &layoutBarrier);
743 if (m_mode == ACCESS_MODE_READ)
745 // Resource Image -> Staging image
746 recordCopyCommand(cmdBuffer);
748 // Staging image layout
749 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
750 0u, DE_NULL, 0u, DE_NULL, 1u, &stagingImageTransferSrcLayoutBarrier);
752 // Image -> Host buffer
753 vk.cmdCopyImageToBuffer(cmdBuffer, **m_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_hostBuffer, 1u, &bufferCopyRegion);
755 // Insert a barrier so copied data is available to the host
756 const VkBufferMemoryBarrier barrier = makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, **m_hostBuffer, 0u, m_bufferSize);
757 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
761 // Host buffer -> Staging image
762 vk.cmdCopyBufferToImage(cmdBuffer, **m_hostBuffer, **m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &bufferCopyRegion);
764 // Staging image layout
765 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
766 0u, DE_NULL, 0u, DE_NULL, 1u, &stagingImageTransferSrcLayoutBarrier);
768 // Resource image layout
770 const VkImageMemoryBarrier layoutBarrier = makeImageMemoryBarrier(
771 (VkAccessFlags)0, VK_ACCESS_TRANSFER_WRITE_BIT,
772 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
773 m_resource.getImage().handle, m_resource.getImage().subresourceRange);
775 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
776 0u, DE_NULL, 0u, DE_NULL, 1u, &layoutBarrier);
779 // Staging image -> Resource Image
780 recordCopyCommand(cmdBuffer);
784 SyncInfo getSyncInfo (void) const
786 const VkAccessFlags access = (m_mode == ACCESS_MODE_READ ? VK_ACCESS_TRANSFER_READ_BIT : VK_ACCESS_TRANSFER_WRITE_BIT);
787 const VkImageLayout layout = (m_mode == ACCESS_MODE_READ ? VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL : VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
788 const SyncInfo syncInfo =
790 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
791 access, // VkAccessFlags accessMask;
792 layout, // VkImageLayout imageLayout;
797 Data getData (void) const
799 return getHostBufferData(m_context, *m_hostBuffer, m_bufferSize);
803 OperationContext& m_context;
804 Resource& m_resource;
805 const AccessMode m_mode;
806 const VkDeviceSize m_bufferSize;
807 de::MovePtr<Buffer> m_hostBuffer;
808 de::MovePtr<Image> m_image;
811 VkOffset3D makeExtentOffset (const Resource& resource)
813 DE_ASSERT(resource.getType() == RESOURCE_TYPE_IMAGE);
814 const VkExtent3D extent = resource.getImage().extent;
816 switch (resource.getImage().imageType)
818 case VK_IMAGE_TYPE_1D: return makeOffset3D(extent.width, 1, 1);
819 case VK_IMAGE_TYPE_2D: return makeOffset3D(extent.width, extent.height, 1);
820 case VK_IMAGE_TYPE_3D: return makeOffset3D(extent.width, extent.height, extent.depth);
827 VkImageBlit makeBlitRegion (const Resource& resource)
829 const VkImageBlit blitRegion =
831 resource.getImage().subresourceLayers, // VkImageSubresourceLayers srcSubresource;
832 { makeOffset3D(0, 0, 0), makeExtentOffset(resource) }, // VkOffset3D srcOffsets[2];
833 resource.getImage().subresourceLayers, // VkImageSubresourceLayers dstSubresource;
834 { makeOffset3D(0, 0, 0), makeExtentOffset(resource) }, // VkOffset3D dstOffsets[2];
839 class BlitImplementation : public ImplementationBase
842 BlitImplementation (OperationContext& context, Resource& resource, const AccessMode mode)
843 : ImplementationBase (context, resource, mode)
844 , m_blitRegion (makeBlitRegion(m_resource))
846 const InstanceInterface& vki = m_context.getInstanceInterface();
847 const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
848 const VkFormatProperties formatProps = getPhysicalDeviceFormatProperties(vki, physDevice, m_resource.getImage().format);
849 const VkFormatFeatureFlags requiredFlags = (VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT);
851 // SRC and DST blit is required because both images are using the same format.
852 if ((formatProps.optimalTilingFeatures & requiredFlags) != requiredFlags)
853 TCU_THROW(NotSupportedError, "Format doesn't support blits");
856 void recordCopyCommand (const VkCommandBuffer cmdBuffer)
858 const DeviceInterface& vk = m_context.getDeviceInterface();
860 if (m_mode == ACCESS_MODE_READ)
862 // Resource Image -> Staging image
863 vk.cmdBlitImage(cmdBuffer, m_resource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
864 1u, &m_blitRegion, VK_FILTER_NEAREST);
868 // Staging image -> Resource Image
869 vk.cmdBlitImage(cmdBuffer, **m_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_resource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
870 1u, &m_blitRegion, VK_FILTER_NEAREST);
875 const VkImageBlit m_blitRegion;
878 VkImageCopy makeImageCopyRegion (const Resource& resource)
880 const VkImageCopy imageCopyRegion =
882 resource.getImage().subresourceLayers, // VkImageSubresourceLayers srcSubresource;
883 makeOffset3D(0, 0, 0), // VkOffset3D srcOffset;
884 resource.getImage().subresourceLayers, // VkImageSubresourceLayers dstSubresource;
885 makeOffset3D(0, 0, 0), // VkOffset3D dstOffset;
886 resource.getImage().extent, // VkExtent3D extent;
888 return imageCopyRegion;
891 class CopyImplementation : public ImplementationBase
894 CopyImplementation (OperationContext& context, Resource& resource, const AccessMode mode)
895 : ImplementationBase (context, resource, mode)
896 , m_imageCopyRegion (makeImageCopyRegion(m_resource))
900 void recordCopyCommand (const VkCommandBuffer cmdBuffer)
902 const DeviceInterface& vk = m_context.getDeviceInterface();
904 if (m_mode == ACCESS_MODE_READ)
906 // Resource Image -> Staging image
907 vk.cmdCopyImage(cmdBuffer, m_resource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &m_imageCopyRegion);
911 // Staging image -> Resource Image
912 vk.cmdCopyImage(cmdBuffer, **m_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_resource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &m_imageCopyRegion);
917 const VkImageCopy m_imageCopyRegion;
926 class Support : public OperationSupport
929 Support (const ResourceDescription& resourceDesc, const Type type, const AccessMode mode)
933 DE_ASSERT(resourceDesc.type == RESOURCE_TYPE_IMAGE);
935 const bool isDepthStencil = isDepthStencilFormat(resourceDesc.imageFormat);
936 m_requiredQueueFlags = (isDepthStencil || m_type == TYPE_BLIT ? VK_QUEUE_GRAPHICS_BIT : VK_QUEUE_TRANSFER_BIT);
938 // Don't blit depth/stencil images.
939 DE_ASSERT(m_type != TYPE_BLIT || !isDepthStencil);
942 deUint32 getResourceUsageFlags (void) const
944 return (m_mode == ACCESS_MODE_READ ? VK_BUFFER_USAGE_TRANSFER_SRC_BIT : VK_BUFFER_USAGE_TRANSFER_DST_BIT);
947 VkQueueFlags getQueueFlags (const OperationContext& context) const
950 return m_requiredQueueFlags;
953 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
955 if (m_type == TYPE_COPY)
956 return de::MovePtr<Operation>(new CopyImplementation(context, resource, m_mode));
958 return de::MovePtr<Operation>(new BlitImplementation(context, resource, m_mode));
963 const AccessMode m_mode;
964 VkQueueFlags m_requiredQueueFlags;
967 } // CopyBlitImage ns
969 namespace ShaderAccess
974 DISPATCH_CALL_DISPATCH,
975 DISPATCH_CALL_DISPATCH_INDIRECT,
978 class GraphicsPipeline : public Pipeline
981 GraphicsPipeline (OperationContext& context, const VkShaderStageFlagBits stage, const std::string& shaderPrefix, const VkDescriptorSetLayout descriptorSetLayout)
982 : m_vertices (context)
984 const DeviceInterface& vk = context.getDeviceInterface();
985 const VkDevice device = context.getDevice();
986 Allocator& allocator = context.getAllocator();
987 const VkShaderStageFlags requiredStages = getRequiredStages(stage);
991 m_colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
992 m_colorImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
993 m_colorImageExtent = makeExtent3D(16u, 16u, 1u);
994 m_colorAttachmentImage = de::MovePtr<Image>(new Image(vk, device, allocator,
995 makeImageCreateInfo(VK_IMAGE_TYPE_2D, m_colorImageExtent, m_colorFormat, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT),
996 MemoryRequirement::Any));
1000 m_colorAttachmentView = makeImageView (vk, device, **m_colorAttachmentImage, VK_IMAGE_VIEW_TYPE_2D, m_colorFormat, m_colorImageSubresourceRange);
1001 m_renderPass = makeRenderPass (vk, device, m_colorFormat);
1002 m_framebuffer = makeFramebuffer (vk, device, *m_renderPass, *m_colorAttachmentView, m_colorImageExtent.width, m_colorImageExtent.height, 1u);
1003 m_pipelineLayout = makePipelineLayout(vk, device, descriptorSetLayout);
1005 GraphicsPipelineBuilder pipelineBuilder;
1007 .setRenderSize (tcu::IVec2(m_colorImageExtent.width, m_colorImageExtent.height))
1008 .setVertexInputSingleAttribute (m_vertices.getVertexFormat(), m_vertices.getVertexStride())
1009 .setShader (vk, device, VK_SHADER_STAGE_VERTEX_BIT, context.getBinaryCollection().get(shaderPrefix + "vert"), DE_NULL)
1010 .setShader (vk, device, VK_SHADER_STAGE_FRAGMENT_BIT, context.getBinaryCollection().get(shaderPrefix + "frag"), DE_NULL);
1012 if (requiredStages & (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT))
1014 .setPatchControlPoints (m_vertices.getNumVertices())
1015 .setShader (vk, device, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, context.getBinaryCollection().get(shaderPrefix + "tesc"), DE_NULL)
1016 .setShader (vk, device, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, context.getBinaryCollection().get(shaderPrefix + "tese"), DE_NULL);
1018 if (requiredStages & VK_SHADER_STAGE_GEOMETRY_BIT)
1020 .setShader (vk, device, VK_SHADER_STAGE_GEOMETRY_BIT, context.getBinaryCollection().get(shaderPrefix + "geom"), DE_NULL);
1022 m_pipeline = pipelineBuilder.build(vk, device, *m_pipelineLayout, *m_renderPass, context.getPipelineCacheData());
1025 void recordCommands (OperationContext& context, const VkCommandBuffer cmdBuffer, const VkDescriptorSet descriptorSet)
1027 const DeviceInterface& vk = context.getDeviceInterface();
1029 // Change color attachment image layout
1031 const VkImageMemoryBarrier colorAttachmentLayoutBarrier = makeImageMemoryBarrier(
1032 (VkAccessFlags)0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1033 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
1034 **m_colorAttachmentImage, m_colorImageSubresourceRange);
1036 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0,
1037 0u, DE_NULL, 0u, DE_NULL, 1u, &colorAttachmentLayoutBarrier);
1041 const VkRect2D renderArea = {
1043 makeExtent2D(m_colorImageExtent.width, m_colorImageExtent.height),
1045 const tcu::Vec4 clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
1047 beginRenderPass(vk, cmdBuffer, *m_renderPass, *m_framebuffer, renderArea, clearColor);
1050 vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
1051 vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &descriptorSet, 0u, DE_NULL);
1053 const VkDeviceSize vertexBufferOffset = 0ull;
1054 const VkBuffer vertexBuffer = m_vertices.getVertexBuffer();
1055 vk.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer, &vertexBufferOffset);
1058 vk.cmdDraw(cmdBuffer, m_vertices.getNumVertices(), 1u, 0u, 0u);
1059 endRenderPass(vk, cmdBuffer);
1063 const VertexGrid m_vertices;
1064 VkFormat m_colorFormat;
1065 de::MovePtr<Image> m_colorAttachmentImage;
1066 Move<VkImageView> m_colorAttachmentView;
1067 VkExtent3D m_colorImageExtent;
1068 VkImageSubresourceRange m_colorImageSubresourceRange;
1069 Move<VkRenderPass> m_renderPass;
1070 Move<VkFramebuffer> m_framebuffer;
1071 Move<VkPipelineLayout> m_pipelineLayout;
1072 Move<VkPipeline> m_pipeline;
1075 class ComputePipeline : public Pipeline
1078 ComputePipeline (OperationContext& context, const DispatchCall dispatchCall, const std::string& shaderPrefix, const VkDescriptorSetLayout descriptorSetLayout)
1079 : m_dispatchCall (dispatchCall)
1081 const DeviceInterface& vk = context.getDeviceInterface();
1082 const VkDevice device = context.getDevice();
1083 Allocator& allocator = context.getAllocator();
1085 if (m_dispatchCall == DISPATCH_CALL_DISPATCH_INDIRECT)
1087 m_indirectBuffer = de::MovePtr<Buffer>(new Buffer(vk, device, allocator,
1088 makeBufferCreateInfo(sizeof(VkDispatchIndirectCommand), VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT), MemoryRequirement::HostVisible));
1090 const Allocation& alloc = m_indirectBuffer->getAllocation();
1091 VkDispatchIndirectCommand* const pIndirectCommand = static_cast<VkDispatchIndirectCommand*>(alloc.getHostPtr());
1093 pIndirectCommand->x = 1u;
1094 pIndirectCommand->y = 1u;
1095 pIndirectCommand->z = 1u;
1097 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), sizeof(VkDispatchIndirectCommand));
1100 const Unique<VkShaderModule> shaderModule(createShaderModule(vk, device, context.getBinaryCollection().get(shaderPrefix + "comp"), (VkShaderModuleCreateFlags)0));
1102 m_pipelineLayout = makePipelineLayout(vk, device, descriptorSetLayout);
1103 m_pipeline = makeComputePipeline(vk, device, *m_pipelineLayout, *shaderModule, DE_NULL, context.getPipelineCacheData());
1106 void recordCommands (OperationContext& context, const VkCommandBuffer cmdBuffer, const VkDescriptorSet descriptorSet)
1108 const DeviceInterface& vk = context.getDeviceInterface();
1110 vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipeline);
1111 vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0u, 1u, &descriptorSet, 0u, DE_NULL);
1113 if (m_dispatchCall == DISPATCH_CALL_DISPATCH_INDIRECT)
1114 vk.cmdDispatchIndirect(cmdBuffer, **m_indirectBuffer, 0u);
1116 vk.cmdDispatch(cmdBuffer, 1u, 1u, 1u);
1120 const DispatchCall m_dispatchCall;
1121 de::MovePtr<Buffer> m_indirectBuffer;
1122 Move<VkPipelineLayout> m_pipelineLayout;
1123 Move<VkPipeline> m_pipeline;
1126 //! Read/write operation on a UBO/SSBO in graphics/compute pipeline.
1127 class BufferImplementation : public Operation
1130 BufferImplementation (OperationContext& context,
1132 const VkShaderStageFlagBits stage,
1133 const BufferType bufferType,
1134 const std::string& shaderPrefix,
1135 const AccessMode mode,
1136 const PipelineType pipelineType,
1137 const DispatchCall dispatchCall)
1138 : m_context (context)
1139 , m_resource (resource)
1141 , m_pipelineStage (pipelineStageFlagsFromShaderStageFlagBits(m_stage))
1142 , m_bufferType (bufferType)
1144 , m_dispatchCall (dispatchCall)
1146 requireFeaturesForSSBOAccess (m_context, m_stage);
1148 const DeviceInterface& vk = m_context.getDeviceInterface();
1149 const VkDevice device = m_context.getDevice();
1150 Allocator& allocator = m_context.getAllocator();
1152 m_hostBuffer = de::MovePtr<Buffer>(new Buffer(
1153 vk, device, allocator, makeBufferCreateInfo(m_resource.getBuffer().size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible));
1155 // Init host buffer data
1157 const Allocation& alloc = m_hostBuffer->getAllocation();
1158 if (m_mode == ACCESS_MODE_READ)
1159 deMemset(alloc.getHostPtr(), 0, static_cast<size_t>(m_resource.getBuffer().size));
1161 fillPattern(alloc.getHostPtr(), m_resource.getBuffer().size);
1162 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), m_resource.getBuffer().size);
1165 // Prepare descriptors
1167 const VkDescriptorType bufferDescriptorType = (m_bufferType == BUFFER_TYPE_UNIFORM ? VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER : VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
1169 m_descriptorSetLayout = DescriptorSetLayoutBuilder()
1170 .addSingleBinding(bufferDescriptorType, m_stage)
1171 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, m_stage)
1174 m_descriptorPool = DescriptorPoolBuilder()
1175 .addType(bufferDescriptorType)
1176 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
1177 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1179 m_descriptorSet = makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout);
1181 const VkDescriptorBufferInfo bufferInfo = makeDescriptorBufferInfo(m_resource.getBuffer().handle, m_resource.getBuffer().offset, m_resource.getBuffer().size);
1182 const VkDescriptorBufferInfo hostBufferInfo = makeDescriptorBufferInfo(**m_hostBuffer, 0u, m_resource.getBuffer().size);
1184 if (m_mode == ACCESS_MODE_READ)
1186 DescriptorSetUpdateBuilder()
1187 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), bufferDescriptorType, &bufferInfo)
1188 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &hostBufferInfo)
1189 .update(vk, device);
1193 DescriptorSetUpdateBuilder()
1194 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &hostBufferInfo)
1195 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufferInfo)
1196 .update(vk, device);
1201 m_pipeline = (pipelineType == PIPELINE_TYPE_GRAPHICS ? de::MovePtr<Pipeline>(new GraphicsPipeline(context, stage, shaderPrefix, *m_descriptorSetLayout))
1202 : de::MovePtr<Pipeline>(new ComputePipeline(context, m_dispatchCall, shaderPrefix, *m_descriptorSetLayout)));
1205 void recordCommands (const VkCommandBuffer cmdBuffer)
1207 m_pipeline->recordCommands(m_context, cmdBuffer, *m_descriptorSet);
1209 // Post draw/dispatch commands
1211 if (m_mode == ACCESS_MODE_READ)
1213 const DeviceInterface& vk = m_context.getDeviceInterface();
1215 // Insert a barrier so data written by the shader is available to the host
1216 const VkBufferMemoryBarrier barrier = makeBufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, **m_hostBuffer, 0u, m_resource.getBuffer().size);
1217 vk.cmdPipelineBarrier(cmdBuffer, m_pipelineStage, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
1221 SyncInfo getSyncInfo (void) const
1223 const VkAccessFlags accessFlags = (m_mode == ACCESS_MODE_READ ? (m_bufferType == BUFFER_TYPE_UNIFORM ? VK_ACCESS_UNIFORM_READ_BIT
1224 : VK_ACCESS_SHADER_READ_BIT)
1225 : VK_ACCESS_SHADER_WRITE_BIT);
1226 const SyncInfo syncInfo =
1228 m_pipelineStage, // VkPipelineStageFlags stageMask;
1229 accessFlags, // VkAccessFlags accessMask;
1230 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
1235 Data getData (void) const
1237 return getHostBufferData(m_context, *m_hostBuffer, m_resource.getBuffer().size);
1241 OperationContext& m_context;
1242 Resource& m_resource;
1243 const VkShaderStageFlagBits m_stage;
1244 const VkPipelineStageFlags m_pipelineStage;
1245 const BufferType m_bufferType;
1246 const AccessMode m_mode;
1247 const DispatchCall m_dispatchCall;
1248 de::MovePtr<Buffer> m_hostBuffer;
1249 Move<VkDescriptorPool> m_descriptorPool;
1250 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
1251 Move<VkDescriptorSet> m_descriptorSet;
1252 de::MovePtr<Pipeline> m_pipeline;
1255 class ImageImplementation : public Operation
1258 ImageImplementation (OperationContext& context,
1260 const VkShaderStageFlagBits stage,
1261 const std::string& shaderPrefix,
1262 const AccessMode mode,
1263 const PipelineType pipelineType,
1264 const DispatchCall dispatchCall)
1265 : m_context (context)
1266 , m_resource (resource)
1268 , m_pipelineStage (pipelineStageFlagsFromShaderStageFlagBits(m_stage))
1270 , m_dispatchCall (dispatchCall)
1271 , m_hostBufferSizeBytes (getPixelBufferSize(m_resource.getImage().format, m_resource.getImage().extent))
1273 const DeviceInterface& vk = m_context.getDeviceInterface();
1274 const InstanceInterface& vki = m_context.getInstanceInterface();
1275 const VkDevice device = m_context.getDevice();
1276 const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
1277 Allocator& allocator = m_context.getAllocator();
1279 // Image stores are always required, in either access mode.
1280 requireFeaturesForSSBOAccess(m_context, m_stage);
1282 // Some storage image formats require additional capability.
1283 if (isStorageImageExtendedFormat(m_resource.getImage().format))
1284 requireFeatures(vki, physDevice, FEATURE_SHADER_STORAGE_IMAGE_EXTENDED_FORMATS);
1286 m_hostBuffer = de::MovePtr<Buffer>(new Buffer(
1287 vk, device, allocator, makeBufferCreateInfo(m_hostBufferSizeBytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT),
1288 MemoryRequirement::HostVisible));
1290 // Init host buffer data
1292 const Allocation& alloc = m_hostBuffer->getAllocation();
1293 if (m_mode == ACCESS_MODE_READ)
1294 deMemset(alloc.getHostPtr(), 0, static_cast<size_t>(m_hostBufferSizeBytes));
1296 fillPattern(alloc.getHostPtr(), m_hostBufferSizeBytes);
1297 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), m_hostBufferSizeBytes);
1302 m_image = de::MovePtr<Image>(new Image(vk, device, allocator,
1303 makeImageCreateInfo(m_resource.getImage().imageType, m_resource.getImage().extent, m_resource.getImage().format,
1304 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_STORAGE_BIT),
1305 MemoryRequirement::Any));
1307 if (m_mode == ACCESS_MODE_READ)
1309 m_srcImage = &m_resource.getImage().handle;
1310 m_dstImage = &(**m_image);
1314 m_srcImage = &(**m_image);
1315 m_dstImage = &m_resource.getImage().handle;
1318 const VkImageViewType viewType = getImageViewType(m_resource.getImage().imageType);
1320 m_srcImageView = makeImageView(vk, device, *m_srcImage, viewType, m_resource.getImage().format, m_resource.getImage().subresourceRange);
1321 m_dstImageView = makeImageView(vk, device, *m_dstImage, viewType, m_resource.getImage().format, m_resource.getImage().subresourceRange);
1324 // Prepare descriptors
1326 m_descriptorSetLayout = DescriptorSetLayoutBuilder()
1327 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, m_stage)
1328 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, m_stage)
1331 m_descriptorPool = DescriptorPoolBuilder()
1332 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1333 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1334 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1336 m_descriptorSet = makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout);
1338 const VkDescriptorImageInfo srcImageInfo = makeDescriptorImageInfo(DE_NULL, *m_srcImageView, VK_IMAGE_LAYOUT_GENERAL);
1339 const VkDescriptorImageInfo dstImageInfo = makeDescriptorImageInfo(DE_NULL, *m_dstImageView, VK_IMAGE_LAYOUT_GENERAL);
1341 DescriptorSetUpdateBuilder()
1342 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &srcImageInfo)
1343 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &dstImageInfo)
1344 .update(vk, device);
1348 m_pipeline = (pipelineType == PIPELINE_TYPE_GRAPHICS ? de::MovePtr<Pipeline>(new GraphicsPipeline(context, stage, shaderPrefix, *m_descriptorSetLayout))
1349 : de::MovePtr<Pipeline>(new ComputePipeline(context, m_dispatchCall, shaderPrefix, *m_descriptorSetLayout)));
1352 void recordCommands (const VkCommandBuffer cmdBuffer)
1354 const DeviceInterface& vk = m_context.getDeviceInterface();
1355 const VkBufferImageCopy bufferCopyRegion = makeBufferImageCopy(m_resource.getImage().subresourceLayers, m_resource.getImage().extent);
1357 // Destination image layout
1359 const VkImageMemoryBarrier barrier = makeImageMemoryBarrier(
1360 (VkAccessFlags)0, VK_ACCESS_SHADER_WRITE_BIT,
1361 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
1362 *m_dstImage, m_resource.getImage().subresourceRange);
1364 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, m_pipelineStage, (VkDependencyFlags)0,
1365 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
1368 // In write mode, source image must be filled with data.
1369 if (m_mode == ACCESS_MODE_WRITE)
1371 // Layout for transfer
1373 const VkImageMemoryBarrier barrier = makeImageMemoryBarrier(
1374 (VkAccessFlags)0, VK_ACCESS_TRANSFER_WRITE_BIT,
1375 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1376 *m_srcImage, m_resource.getImage().subresourceRange);
1378 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
1379 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
1382 // Host buffer -> Src image
1383 vk.cmdCopyBufferToImage(cmdBuffer, **m_hostBuffer, *m_srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &bufferCopyRegion);
1385 // Layout for shader reading
1387 const VkImageMemoryBarrier barrier = makeImageMemoryBarrier(
1388 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT,
1389 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
1390 *m_srcImage, m_resource.getImage().subresourceRange);
1392 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, m_pipelineStage, (VkDependencyFlags)0,
1393 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
1399 m_pipeline->recordCommands(m_context, cmdBuffer, *m_descriptorSet);
1401 // Post draw/dispatch commands
1403 if (m_mode == ACCESS_MODE_READ)
1405 // Layout for transfer
1407 const VkImageMemoryBarrier barrier = makeImageMemoryBarrier(
1408 VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
1409 VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1410 *m_dstImage, m_resource.getImage().subresourceRange);
1412 vk.cmdPipelineBarrier(cmdBuffer, m_pipelineStage, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
1413 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
1416 // Dst image -> Host buffer
1417 vk.cmdCopyImageToBuffer(cmdBuffer, *m_dstImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_hostBuffer, 1u, &bufferCopyRegion);
1419 // Insert a barrier so data written by the shader is available to the host
1421 const VkBufferMemoryBarrier barrier = makeBufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, **m_hostBuffer, 0u, m_hostBufferSizeBytes);
1422 vk.cmdPipelineBarrier(cmdBuffer, m_pipelineStage, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
1427 SyncInfo getSyncInfo (void) const
1429 const VkAccessFlags accessFlags = (m_mode == ACCESS_MODE_READ ? VK_ACCESS_SHADER_READ_BIT : VK_ACCESS_SHADER_WRITE_BIT);
1430 const SyncInfo syncInfo =
1432 m_pipelineStage, // VkPipelineStageFlags stageMask;
1433 accessFlags, // VkAccessFlags accessMask;
1434 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout;
1439 Data getData (void) const
1441 return getHostBufferData(m_context, *m_hostBuffer, m_hostBufferSizeBytes);
1445 OperationContext& m_context;
1446 Resource& m_resource;
1447 const VkShaderStageFlagBits m_stage;
1448 const VkPipelineStageFlags m_pipelineStage;
1449 const AccessMode m_mode;
1450 const DispatchCall m_dispatchCall;
1451 const VkDeviceSize m_hostBufferSizeBytes;
1452 de::MovePtr<Buffer> m_hostBuffer;
1453 de::MovePtr<Image> m_image; //! Additional image used as src or dst depending on operation mode.
1454 const VkImage* m_srcImage;
1455 const VkImage* m_dstImage;
1456 Move<VkImageView> m_srcImageView;
1457 Move<VkImageView> m_dstImageView;
1458 Move<VkDescriptorPool> m_descriptorPool;
1459 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
1460 Move<VkDescriptorSet> m_descriptorSet;
1461 de::MovePtr<Pipeline> m_pipeline;
1464 //! Create generic passthrough shaders with bits of custom code inserted in a specific shader stage.
1465 void initPassthroughPrograms (SourceCollections& programCollection,
1466 const std::string& shaderPrefix,
1467 const std::string& declCode,
1468 const std::string& mainCode,
1469 const VkShaderStageFlagBits stage)
1471 const VkShaderStageFlags requiredStages = getRequiredStages(stage);
1473 if (requiredStages & VK_SHADER_STAGE_VERTEX_BIT)
1475 std::ostringstream src;
1476 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
1478 << "layout(location = 0) in vec4 v_in_position;\n"
1480 << "out " << s_perVertexBlock << ";\n"
1482 << (stage & VK_SHADER_STAGE_VERTEX_BIT ? declCode + "\n" : "")
1483 << "void main (void)\n"
1485 << " gl_Position = v_in_position;\n"
1486 << (stage & VK_SHADER_STAGE_VERTEX_BIT ? mainCode : "")
1489 programCollection.glslSources.add(shaderPrefix + "vert") << glu::VertexSource(src.str());
1492 if (requiredStages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
1494 std::ostringstream src;
1495 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
1497 << "layout(vertices = 3) out;\n"
1499 << "in " << s_perVertexBlock << " gl_in[gl_MaxPatchVertices];\n"
1501 << "out " << s_perVertexBlock << " gl_out[];\n"
1503 << (stage & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ? declCode + "\n" : "")
1504 << "void main (void)\n"
1506 << " gl_TessLevelInner[0] = 1.0;\n"
1507 << " gl_TessLevelInner[1] = 1.0;\n"
1509 << " gl_TessLevelOuter[0] = 1.0;\n"
1510 << " gl_TessLevelOuter[1] = 1.0;\n"
1511 << " gl_TessLevelOuter[2] = 1.0;\n"
1512 << " gl_TessLevelOuter[3] = 1.0;\n"
1514 << " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1515 << (stage & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ? "\n" + mainCode : "")
1518 programCollection.glslSources.add(shaderPrefix + "tesc") << glu::TessellationControlSource(src.str());
1521 if (requiredStages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
1523 std::ostringstream src;
1524 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
1526 << "layout(triangles, equal_spacing, ccw) in;\n"
1528 << "in " << s_perVertexBlock << " gl_in[gl_MaxPatchVertices];\n"
1530 << "out " << s_perVertexBlock << ";\n"
1532 << (stage & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT ? declCode + "\n" : "")
1533 << "void main (void)\n"
1535 << " vec3 px = gl_TessCoord.x * gl_in[0].gl_Position.xyz;\n"
1536 << " vec3 py = gl_TessCoord.y * gl_in[1].gl_Position.xyz;\n"
1537 << " vec3 pz = gl_TessCoord.z * gl_in[2].gl_Position.xyz;\n"
1538 << " gl_Position = vec4(px + py + pz, 1.0);\n"
1539 << (stage & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT ? mainCode : "")
1542 programCollection.glslSources.add(shaderPrefix + "tese") << glu::TessellationEvaluationSource(src.str());
1545 if (requiredStages & VK_SHADER_STAGE_GEOMETRY_BIT)
1547 std::ostringstream src;
1548 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
1550 << "layout(triangles) in;\n"
1551 << "layout(triangle_strip, max_vertices = 3) out;\n"
1553 << "in " << s_perVertexBlock << " gl_in[];\n"
1555 << "out " << s_perVertexBlock << ";\n"
1557 << (stage & VK_SHADER_STAGE_GEOMETRY_BIT ? declCode + "\n" : "")
1558 << "void main (void)\n"
1560 << " gl_Position = gl_in[0].gl_Position;\n"
1561 << " EmitVertex();\n"
1563 << " gl_Position = gl_in[1].gl_Position;\n"
1564 << " EmitVertex();\n"
1566 << " gl_Position = gl_in[2].gl_Position;\n"
1567 << " EmitVertex();\n"
1568 << (stage & VK_SHADER_STAGE_GEOMETRY_BIT ? "\n" + mainCode : "")
1571 programCollection.glslSources.add(shaderPrefix + "geom") << glu::GeometrySource(src.str());
1574 if (requiredStages & VK_SHADER_STAGE_FRAGMENT_BIT)
1576 std::ostringstream src;
1577 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
1579 << "layout(location = 0) out vec4 o_color;\n"
1581 << (stage & VK_SHADER_STAGE_FRAGMENT_BIT ? declCode + "\n" : "")
1582 << "void main (void)\n"
1584 << " o_color = vec4(1.0);\n"
1585 << (stage & VK_SHADER_STAGE_FRAGMENT_BIT ? "\n" + mainCode : "")
1588 programCollection.glslSources.add(shaderPrefix + "frag") << glu::FragmentSource(src.str());
1591 if (requiredStages & VK_SHADER_STAGE_COMPUTE_BIT)
1593 std::ostringstream src;
1594 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
1596 << "layout(local_size_x = 1) in;\n"
1598 << (stage & VK_SHADER_STAGE_COMPUTE_BIT ? declCode + "\n" : "")
1599 << "void main (void)\n"
1601 << (stage & VK_SHADER_STAGE_COMPUTE_BIT ? mainCode : "")
1604 programCollection.glslSources.add(shaderPrefix + "comp") << glu::ComputeSource(src.str());
1608 class BufferSupport : public OperationSupport
1611 BufferSupport (const ResourceDescription& resourceDesc,
1612 const BufferType bufferType,
1613 const AccessMode mode,
1614 const VkShaderStageFlagBits stage,
1615 const DispatchCall dispatchCall = DISPATCH_CALL_DISPATCH)
1616 : m_resourceDesc (resourceDesc)
1617 , m_bufferType (bufferType)
1620 , m_shaderPrefix (std::string(m_mode == ACCESS_MODE_READ ? "read_" : "write_") + (m_bufferType == BUFFER_TYPE_UNIFORM ? "ubo_" : "ssbo_"))
1621 , m_dispatchCall (dispatchCall)
1623 DE_ASSERT(m_resourceDesc.type == RESOURCE_TYPE_BUFFER);
1624 DE_ASSERT(m_bufferType == BUFFER_TYPE_UNIFORM || m_bufferType == BUFFER_TYPE_STORAGE);
1625 DE_ASSERT(m_mode == ACCESS_MODE_READ || m_mode == ACCESS_MODE_WRITE);
1626 DE_ASSERT(m_mode == ACCESS_MODE_READ || m_bufferType == BUFFER_TYPE_STORAGE);
1627 DE_ASSERT(m_bufferType != BUFFER_TYPE_UNIFORM || m_resourceDesc.size.x() <= MAX_UBO_RANGE);
1628 DE_ASSERT(m_dispatchCall == DISPATCH_CALL_DISPATCH || m_dispatchCall == DISPATCH_CALL_DISPATCH_INDIRECT);
1630 assertValidShaderStage(m_stage);
1633 void initPrograms (SourceCollections& programCollection) const
1635 DE_ASSERT((m_resourceDesc.size.x() % sizeof(tcu::UVec4)) == 0);
1637 const std::string bufferTypeStr = (m_bufferType == BUFFER_TYPE_UNIFORM ? "uniform" : "buffer");
1638 const int numVecElements = static_cast<int>(m_resourceDesc.size.x() / sizeof(tcu::UVec4)); // std140 must be aligned to a multiple of 16
1640 std::ostringstream declSrc;
1641 declSrc << "layout(set = 0, binding = 0, std140) readonly " << bufferTypeStr << " Input {\n"
1642 << " uvec4 data[" << numVecElements << "];\n"
1645 << "layout(set = 0, binding = 1, std140) writeonly buffer Output {\n"
1646 << " uvec4 data[" << numVecElements << "];\n"
1649 std::ostringstream copySrc;
1650 copySrc << " for (int i = 0; i < " << numVecElements << "; ++i) {\n"
1651 << " b_out.data[i] = b_in.data[i];\n"
1654 initPassthroughPrograms(programCollection, m_shaderPrefix, declSrc.str(), copySrc.str(), m_stage);
1657 deUint32 getResourceUsageFlags (void) const
1659 return (m_bufferType == BUFFER_TYPE_UNIFORM ? VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT : VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1662 VkQueueFlags getQueueFlags (const OperationContext& context) const
1665 return (m_stage == VK_SHADER_STAGE_COMPUTE_BIT ? VK_QUEUE_COMPUTE_BIT : VK_QUEUE_GRAPHICS_BIT);
1668 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
1670 if (m_stage & VK_SHADER_STAGE_COMPUTE_BIT)
1671 return de::MovePtr<Operation>(new BufferImplementation(context, resource, m_stage, m_bufferType, m_shaderPrefix, m_mode, PIPELINE_TYPE_COMPUTE, m_dispatchCall));
1673 return de::MovePtr<Operation>(new BufferImplementation(context, resource, m_stage, m_bufferType, m_shaderPrefix, m_mode, PIPELINE_TYPE_GRAPHICS, m_dispatchCall));
1677 const ResourceDescription m_resourceDesc;
1678 const BufferType m_bufferType;
1679 const AccessMode m_mode;
1680 const VkShaderStageFlagBits m_stage;
1681 const std::string m_shaderPrefix;
1682 const DispatchCall m_dispatchCall;
1685 class ImageSupport : public OperationSupport
1688 ImageSupport (const ResourceDescription& resourceDesc,
1689 const AccessMode mode,
1690 const VkShaderStageFlagBits stage,
1691 const DispatchCall dispatchCall = DISPATCH_CALL_DISPATCH)
1692 : m_resourceDesc (resourceDesc)
1695 , m_shaderPrefix (m_mode == ACCESS_MODE_READ ? "read_image_" : "write_image_")
1696 , m_dispatchCall (dispatchCall)
1698 DE_ASSERT(m_resourceDesc.type == RESOURCE_TYPE_IMAGE);
1699 DE_ASSERT(m_mode == ACCESS_MODE_READ || m_mode == ACCESS_MODE_WRITE);
1700 DE_ASSERT(m_dispatchCall == DISPATCH_CALL_DISPATCH || m_dispatchCall == DISPATCH_CALL_DISPATCH_INDIRECT);
1702 assertValidShaderStage(m_stage);
1705 void initPrograms (SourceCollections& programCollection) const
1707 const std::string imageFormat = getShaderImageFormatQualifier(m_resourceDesc.imageFormat);
1708 const std::string imageType = getShaderImageType(m_resourceDesc.imageFormat, m_resourceDesc.imageType);
1710 std::ostringstream declSrc;
1711 declSrc << "layout(set = 0, binding = 0, " << imageFormat << ") readonly uniform " << imageType << " srcImg;\n"
1712 << "layout(set = 0, binding = 1, " << imageFormat << ") writeonly uniform " << imageType << " dstImg;\n";
1714 std::ostringstream mainSrc;
1715 if (m_resourceDesc.imageType == VK_IMAGE_TYPE_1D)
1716 mainSrc << " for (int x = 0; x < " << m_resourceDesc.size.x() << "; ++x)\n"
1717 << " imageStore(dstImg, x, imageLoad(srcImg, x));\n";
1718 else if (m_resourceDesc.imageType == VK_IMAGE_TYPE_2D)
1719 mainSrc << " for (int y = 0; y < " << m_resourceDesc.size.y() << "; ++y)\n"
1720 << " for (int x = 0; x < " << m_resourceDesc.size.x() << "; ++x)\n"
1721 << " imageStore(dstImg, ivec2(x, y), imageLoad(srcImg, ivec2(x, y)));\n";
1722 else if (m_resourceDesc.imageType == VK_IMAGE_TYPE_3D)
1723 mainSrc << " for (int z = 0; z < " << m_resourceDesc.size.z() << "; ++z)\n"
1724 << " for (int y = 0; y < " << m_resourceDesc.size.y() << "; ++y)\n"
1725 << " for (int x = 0; x < " << m_resourceDesc.size.x() << "; ++x)\n"
1726 << " imageStore(dstImg, ivec3(x, y, z), imageLoad(srcImg, ivec3(x, y, z)));\n";
1730 initPassthroughPrograms(programCollection, m_shaderPrefix, declSrc.str(), mainSrc.str(), m_stage);
1733 deUint32 getResourceUsageFlags (void) const
1735 return VK_IMAGE_USAGE_STORAGE_BIT;
1738 VkQueueFlags getQueueFlags (const OperationContext& context) const
1741 return (m_stage == VK_SHADER_STAGE_COMPUTE_BIT ? VK_QUEUE_COMPUTE_BIT : VK_QUEUE_GRAPHICS_BIT);
1744 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
1746 if (m_stage & VK_SHADER_STAGE_COMPUTE_BIT)
1747 return de::MovePtr<Operation>(new ImageImplementation(context, resource, m_stage, m_shaderPrefix, m_mode, PIPELINE_TYPE_COMPUTE, m_dispatchCall));
1749 return de::MovePtr<Operation>(new ImageImplementation(context, resource, m_stage, m_shaderPrefix, m_mode, PIPELINE_TYPE_GRAPHICS, m_dispatchCall));
1753 const ResourceDescription m_resourceDesc;
1754 const AccessMode m_mode;
1755 const VkShaderStageFlagBits m_stage;
1756 const std::string m_shaderPrefix;
1757 const DispatchCall m_dispatchCall;
1760 } // ShaderAccess ns
1762 namespace CopyBufferToImage
1765 class WriteImplementation : public Operation
1768 WriteImplementation (OperationContext& context, Resource& resource)
1769 : m_context (context)
1770 , m_resource (resource)
1771 , m_bufferSize (getPixelBufferSize(m_resource.getImage().format, m_resource.getImage().extent))
1773 DE_ASSERT(m_resource.getType() == RESOURCE_TYPE_IMAGE);
1775 const DeviceInterface& vk = m_context.getDeviceInterface();
1776 const VkDevice device = m_context.getDevice();
1777 Allocator& allocator = m_context.getAllocator();
1779 m_hostBuffer = de::MovePtr<Buffer>(new Buffer(
1780 vk, device, allocator, makeBufferCreateInfo(m_bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT), MemoryRequirement::HostVisible));
1782 const Allocation& alloc = m_hostBuffer->getAllocation();
1783 fillPattern(alloc.getHostPtr(), m_bufferSize);
1784 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), m_bufferSize);
1787 void recordCommands (const VkCommandBuffer cmdBuffer)
1789 const DeviceInterface& vk = m_context.getDeviceInterface();
1790 const VkBufferImageCopy copyRegion = makeBufferImageCopy(m_resource.getImage().subresourceLayers, m_resource.getImage().extent);
1792 const VkImageMemoryBarrier layoutBarrier = makeImageMemoryBarrier(
1793 (VkAccessFlags)0, VK_ACCESS_TRANSFER_WRITE_BIT,
1794 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1795 m_resource.getImage().handle, m_resource.getImage().subresourceRange);
1796 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);
1798 vk.cmdCopyBufferToImage(cmdBuffer, **m_hostBuffer, m_resource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ©Region);
1801 SyncInfo getSyncInfo (void) const
1803 const SyncInfo syncInfo =
1805 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
1806 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags accessMask;
1807 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout imageLayout;
1812 Data getData (void) const
1814 return getHostBufferData(m_context, *m_hostBuffer, m_bufferSize);
1818 OperationContext& m_context;
1819 Resource& m_resource;
1820 de::MovePtr<Buffer> m_hostBuffer;
1821 const VkDeviceSize m_bufferSize;
1824 class ReadImplementation : public Operation
1827 ReadImplementation (OperationContext& context, Resource& resource)
1828 : m_context (context)
1829 , m_resource (resource)
1830 , m_subresourceRange (makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u))
1831 , m_subresourceLayers (makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u))
1833 DE_ASSERT(m_resource.getType() == RESOURCE_TYPE_BUFFER);
1835 const DeviceInterface& vk = m_context.getDeviceInterface();
1836 const VkDevice device = m_context.getDevice();
1837 Allocator& allocator = m_context.getAllocator();
1838 const VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
1839 const deUint32 pixelSize = tcu::getPixelSize(mapVkFormat(format));
1841 DE_ASSERT((m_resource.getBuffer().size % pixelSize) == 0);
1842 m_imageExtent = get2DImageExtentWithSize(m_resource.getBuffer().size, pixelSize); // there may be some unused space at the end
1844 // Copy destination image.
1845 m_image = de::MovePtr<Image>(new Image(
1846 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));
1848 // Image data will be copied here, so it can be read on the host.
1849 m_hostBuffer = de::MovePtr<Buffer>(new Buffer(
1850 vk, device, allocator, makeBufferCreateInfo(m_resource.getBuffer().size, VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible));
1853 void recordCommands (const VkCommandBuffer cmdBuffer)
1855 const DeviceInterface& vk = m_context.getDeviceInterface();
1856 const VkBufferImageCopy copyRegion = makeBufferImageCopy(m_subresourceLayers, m_imageExtent);
1858 // Resource -> Image
1860 const VkImageMemoryBarrier layoutBarrier = makeImageMemoryBarrier(
1861 (VkAccessFlags)0, VK_ACCESS_TRANSFER_WRITE_BIT,
1862 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1863 **m_image, m_subresourceRange);
1864 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);
1866 vk.cmdCopyBufferToImage(cmdBuffer, m_resource.getBuffer().handle, **m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ©Region);
1868 // Image -> Host buffer
1870 const VkImageMemoryBarrier layoutBarrier = makeImageMemoryBarrier(
1871 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
1872 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1873 **m_image, m_subresourceRange);
1874 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 0u, DE_NULL, 1u, &layoutBarrier);
1876 vk.cmdCopyImageToBuffer(cmdBuffer, **m_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_hostBuffer, 1u, ©Region);
1878 const VkBufferMemoryBarrier barrier = makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, **m_hostBuffer, 0u, m_resource.getBuffer().size);
1879 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
1883 SyncInfo getSyncInfo (void) const
1885 const SyncInfo syncInfo =
1887 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
1888 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags accessMask;
1889 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
1894 Data getData (void) const
1896 return getHostBufferData(m_context, *m_hostBuffer, m_resource.getBuffer().size);
1900 OperationContext& m_context;
1901 Resource& m_resource;
1902 const VkImageSubresourceRange m_subresourceRange;
1903 const VkImageSubresourceLayers m_subresourceLayers;
1904 de::MovePtr<Buffer> m_hostBuffer;
1905 de::MovePtr<Image> m_image;
1906 VkExtent3D m_imageExtent;
1909 class Support : public OperationSupport
1912 Support (const ResourceDescription& resourceDesc, const AccessMode mode)
1914 , m_requiredQueueFlags (resourceDesc.type == RESOURCE_TYPE_IMAGE && isDepthStencilFormat(resourceDesc.imageFormat) ? VK_QUEUE_GRAPHICS_BIT : VK_QUEUE_TRANSFER_BIT)
1917 // Because depth or stencil aspect buffer to image copies may require format conversions on some implementations,
1918 // they are not supported on queues that do not support graphics.
1920 DE_ASSERT(m_mode == ACCESS_MODE_READ || m_mode == ACCESS_MODE_WRITE);
1921 DE_ASSERT(m_mode == ACCESS_MODE_READ || resourceDesc.type != RESOURCE_TYPE_BUFFER);
1922 DE_ASSERT(m_mode == ACCESS_MODE_WRITE || resourceDesc.type != RESOURCE_TYPE_IMAGE);
1925 deUint32 getResourceUsageFlags (void) const
1927 if (m_mode == ACCESS_MODE_READ)
1928 return VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
1930 return VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1933 VkQueueFlags getQueueFlags (const OperationContext& context) const
1936 return m_requiredQueueFlags;
1939 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
1941 if (m_mode == ACCESS_MODE_READ)
1942 return de::MovePtr<Operation>(new ReadImplementation(context, resource));
1944 return de::MovePtr<Operation>(new WriteImplementation(context, resource));
1948 const AccessMode m_mode;
1949 const VkQueueFlags m_requiredQueueFlags;
1952 } // CopyBufferToImage ns
1954 namespace CopyImageToBuffer
1957 class WriteImplementation : public Operation
1960 WriteImplementation (OperationContext& context, Resource& resource)
1961 : m_context (context)
1962 , m_resource (resource)
1963 , m_subresourceRange (makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u))
1964 , m_subresourceLayers (makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u))
1966 DE_ASSERT(m_resource.getType() == RESOURCE_TYPE_BUFFER);
1968 const DeviceInterface& vk = m_context.getDeviceInterface();
1969 const VkDevice device = m_context.getDevice();
1970 Allocator& allocator = m_context.getAllocator();
1971 const VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
1972 const deUint32 pixelSize = tcu::getPixelSize(mapVkFormat(format));
1974 DE_ASSERT((m_resource.getBuffer().size % pixelSize) == 0);
1975 m_imageExtent = get2DImageExtentWithSize(m_resource.getBuffer().size, pixelSize);
1977 // Source data staging buffer
1978 m_hostBuffer = de::MovePtr<Buffer>(new Buffer(
1979 vk, device, allocator, makeBufferCreateInfo(m_resource.getBuffer().size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT), MemoryRequirement::HostVisible));
1981 const Allocation& alloc = m_hostBuffer->getAllocation();
1982 fillPattern(alloc.getHostPtr(), m_resource.getBuffer().size);
1983 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), m_resource.getBuffer().size);
1985 // Source data image
1986 m_image = de::MovePtr<Image>(new Image(
1987 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));
1990 void recordCommands (const VkCommandBuffer cmdBuffer)
1992 const DeviceInterface& vk = m_context.getDeviceInterface();
1993 const VkBufferImageCopy copyRegion = makeBufferImageCopy(m_subresourceLayers, m_imageExtent);
1995 // Host buffer -> Image
1997 const VkImageMemoryBarrier layoutBarrier = makeImageMemoryBarrier(
1998 (VkAccessFlags)0, VK_ACCESS_TRANSFER_WRITE_BIT,
1999 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
2000 **m_image, m_subresourceRange);
2001 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);
2003 vk.cmdCopyBufferToImage(cmdBuffer, **m_hostBuffer, **m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ©Region);
2005 // Image -> Resource
2007 const VkImageMemoryBarrier layoutBarrier = makeImageMemoryBarrier(
2008 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
2009 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
2010 **m_image, m_subresourceRange);
2011 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 0u, DE_NULL, 1u, &layoutBarrier);
2013 vk.cmdCopyImageToBuffer(cmdBuffer, **m_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_resource.getBuffer().handle, 1u, ©Region);
2017 SyncInfo getSyncInfo (void) const
2019 const SyncInfo syncInfo =
2021 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
2022 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags accessMask;
2023 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
2028 Data getData (void) const
2030 return getHostBufferData(m_context, *m_hostBuffer, m_resource.getBuffer().size);
2034 OperationContext& m_context;
2035 Resource& m_resource;
2036 const VkImageSubresourceRange m_subresourceRange;
2037 const VkImageSubresourceLayers m_subresourceLayers;
2038 de::MovePtr<Buffer> m_hostBuffer;
2039 de::MovePtr<Image> m_image;
2040 VkExtent3D m_imageExtent;
2043 class ReadImplementation : public Operation
2046 ReadImplementation (OperationContext& context, Resource& resource)
2047 : m_context (context)
2048 , m_resource (resource)
2049 , m_bufferSize (getPixelBufferSize(m_resource.getImage().format, m_resource.getImage().extent))
2051 DE_ASSERT(m_resource.getType() == RESOURCE_TYPE_IMAGE);
2053 const DeviceInterface& vk = m_context.getDeviceInterface();
2054 const VkDevice device = m_context.getDevice();
2055 Allocator& allocator = m_context.getAllocator();
2057 m_hostBuffer = de::MovePtr<Buffer>(new Buffer(
2058 vk, device, allocator, makeBufferCreateInfo(m_bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible));
2060 const Allocation& alloc = m_hostBuffer->getAllocation();
2061 deMemset(alloc.getHostPtr(), 0, static_cast<size_t>(m_bufferSize));
2062 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), m_bufferSize);
2065 void recordCommands (const VkCommandBuffer cmdBuffer)
2067 const DeviceInterface& vk = m_context.getDeviceInterface();
2068 const VkBufferImageCopy copyRegion = makeBufferImageCopy(m_resource.getImage().subresourceLayers, m_resource.getImage().extent);
2070 vk.cmdCopyImageToBuffer(cmdBuffer, m_resource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_hostBuffer, 1u, ©Region);
2073 SyncInfo getSyncInfo (void) const
2075 const SyncInfo syncInfo =
2077 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
2078 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags accessMask;
2079 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout imageLayout;
2084 Data getData (void) const
2086 return getHostBufferData(m_context, *m_hostBuffer, m_bufferSize);
2090 OperationContext& m_context;
2091 Resource& m_resource;
2092 de::MovePtr<Buffer> m_hostBuffer;
2093 const VkDeviceSize m_bufferSize;
2096 class Support : public OperationSupport
2099 Support (const ResourceDescription& resourceDesc, const AccessMode mode)
2101 , m_requiredQueueFlags (resourceDesc.type == RESOURCE_TYPE_IMAGE && isDepthStencilFormat(resourceDesc.imageFormat) ? VK_QUEUE_GRAPHICS_BIT : VK_QUEUE_TRANSFER_BIT)
2103 DE_ASSERT(m_mode == ACCESS_MODE_READ || m_mode == ACCESS_MODE_WRITE);
2104 DE_ASSERT(m_mode == ACCESS_MODE_READ || resourceDesc.type != RESOURCE_TYPE_IMAGE);
2105 DE_ASSERT(m_mode == ACCESS_MODE_WRITE || resourceDesc.type != RESOURCE_TYPE_BUFFER);
2108 deUint32 getResourceUsageFlags (void) const
2110 if (m_mode == ACCESS_MODE_READ)
2111 return VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
2113 return VK_BUFFER_USAGE_TRANSFER_DST_BIT;
2116 VkQueueFlags getQueueFlags (const OperationContext& context) const
2119 return m_requiredQueueFlags;
2122 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
2124 if (m_mode == ACCESS_MODE_READ)
2125 return de::MovePtr<Operation>(new ReadImplementation(context, resource));
2127 return de::MovePtr<Operation>(new WriteImplementation(context, resource));
2131 const AccessMode m_mode;
2132 const VkQueueFlags m_requiredQueueFlags;
2135 } // CopyImageToBuffer ns
2137 namespace ClearImage
2143 CLEAR_MODE_DEPTH_STENCIL,
2146 class Implementation : public Operation
2149 Implementation (OperationContext& context, Resource& resource, const ClearMode mode)
2150 : m_context (context)
2151 , m_resource (resource)
2152 , m_clearValue (makeClearValue(m_resource.getImage().format))
2155 const VkDeviceSize size = getPixelBufferSize(m_resource.getImage().format, m_resource.getImage().extent);
2156 const VkExtent3D& extent = m_resource.getImage().extent;
2157 const VkFormat format = m_resource.getImage().format;
2158 const tcu::TextureFormat texFormat = mapVkFormat(format);
2160 m_data.resize(static_cast<std::size_t>(size));
2161 tcu::PixelBufferAccess imagePixels(texFormat, extent.width, extent.height, extent.depth, &m_data[0]);
2162 clearPixelBuffer(imagePixels, m_clearValue);
2165 void recordCommands (const VkCommandBuffer cmdBuffer)
2167 const DeviceInterface& vk = m_context.getDeviceInterface();
2169 const VkImageMemoryBarrier layoutBarrier = makeImageMemoryBarrier(
2170 (VkAccessFlags)0, VK_ACCESS_TRANSFER_WRITE_BIT,
2171 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
2172 m_resource.getImage().handle, m_resource.getImage().subresourceRange);
2174 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);
2176 if (m_mode == CLEAR_MODE_COLOR)
2177 vk.cmdClearColorImage(cmdBuffer, m_resource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &m_clearValue.color, 1u, &m_resource.getImage().subresourceRange);
2179 vk.cmdClearDepthStencilImage(cmdBuffer, m_resource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &m_clearValue.depthStencil, 1u, &m_resource.getImage().subresourceRange);
2182 SyncInfo getSyncInfo (void) const
2184 const SyncInfo syncInfo =
2186 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
2187 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags accessMask;
2188 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout imageLayout;
2193 Data getData (void) const
2197 m_data.size(), // std::size_t size;
2198 &m_data[0], // const deUint8* data;
2204 OperationContext& m_context;
2205 Resource& m_resource;
2206 std::vector<deUint8> m_data;
2207 const VkClearValue m_clearValue;
2208 const ClearMode m_mode;
2211 class Support : public OperationSupport
2214 Support (const ResourceDescription& resourceDesc, const ClearMode mode)
2215 : m_resourceDesc (resourceDesc)
2218 DE_ASSERT(m_mode == CLEAR_MODE_COLOR || m_mode == CLEAR_MODE_DEPTH_STENCIL);
2219 DE_ASSERT(m_resourceDesc.type == RESOURCE_TYPE_IMAGE);
2220 DE_ASSERT(m_resourceDesc.imageAspect == VK_IMAGE_ASPECT_COLOR_BIT || (m_mode != CLEAR_MODE_COLOR));
2221 DE_ASSERT((m_resourceDesc.imageAspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) || (m_mode != CLEAR_MODE_DEPTH_STENCIL));
2224 deUint32 getResourceUsageFlags (void) const
2226 return VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2229 VkQueueFlags getQueueFlags (const OperationContext& context) const
2232 if (m_mode == CLEAR_MODE_COLOR)
2233 return VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT;
2235 return VK_QUEUE_GRAPHICS_BIT;
2238 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
2240 return de::MovePtr<Operation>(new Implementation(context, resource, m_mode));
2244 const ResourceDescription m_resourceDesc;
2245 const ClearMode m_mode;
2256 DRAW_CALL_DRAW_INDEXED,
2257 DRAW_CALL_DRAW_INDIRECT,
2258 DRAW_CALL_DRAW_INDEXED_INDIRECT,
2261 //! A write operation that is a result of drawing to an image.
2262 //! \todo Add support for depth/stencil too?
2263 class Implementation : public Operation
2266 Implementation (OperationContext& context, Resource& resource, const DrawCall drawCall)
2267 : m_context (context)
2268 , m_resource (resource)
2269 , m_drawCall (drawCall)
2270 , m_vertices (context)
2272 const DeviceInterface& vk = context.getDeviceInterface();
2273 const VkDevice device = context.getDevice();
2274 Allocator& allocator = context.getAllocator();
2278 if (m_drawCall == DRAW_CALL_DRAW_INDIRECT)
2280 m_indirectBuffer = de::MovePtr<Buffer>(new Buffer(vk, device, allocator,
2281 makeBufferCreateInfo(sizeof(VkDrawIndirectCommand), VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT), MemoryRequirement::HostVisible));
2283 const Allocation& alloc = m_indirectBuffer->getAllocation();
2284 VkDrawIndirectCommand* const pIndirectCommand = static_cast<VkDrawIndirectCommand*>(alloc.getHostPtr());
2286 pIndirectCommand->vertexCount = m_vertices.getNumVertices();
2287 pIndirectCommand->instanceCount = 1u;
2288 pIndirectCommand->firstVertex = 0u;
2289 pIndirectCommand->firstInstance = 0u;
2291 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), sizeof(VkDrawIndirectCommand));
2293 else if (m_drawCall == DRAW_CALL_DRAW_INDEXED_INDIRECT)
2295 m_indirectBuffer = de::MovePtr<Buffer>(new Buffer(vk, device, allocator,
2296 makeBufferCreateInfo(sizeof(VkDrawIndexedIndirectCommand), VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT), MemoryRequirement::HostVisible));
2298 const Allocation& alloc = m_indirectBuffer->getAllocation();
2299 VkDrawIndexedIndirectCommand* const pIndirectCommand = static_cast<VkDrawIndexedIndirectCommand*>(alloc.getHostPtr());
2301 pIndirectCommand->indexCount = m_vertices.getNumIndices();
2302 pIndirectCommand->instanceCount = 1u;
2303 pIndirectCommand->firstIndex = 0u;
2304 pIndirectCommand->vertexOffset = 0u;
2305 pIndirectCommand->firstInstance = 0u;
2307 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), sizeof(VkDrawIndexedIndirectCommand));
2310 // Resource image is the color attachment
2312 m_colorFormat = m_resource.getImage().format;
2313 m_colorSubresourceRange = m_resource.getImage().subresourceRange;
2314 m_colorImage = m_resource.getImage().handle;
2315 m_attachmentExtent = m_resource.getImage().extent;
2319 m_colorAttachmentView = makeImageView (vk, device, m_colorImage, VK_IMAGE_VIEW_TYPE_2D, m_colorFormat, m_colorSubresourceRange);
2320 m_renderPass = makeRenderPass (vk, device, m_colorFormat);
2321 m_framebuffer = makeFramebuffer (vk, device, *m_renderPass, *m_colorAttachmentView, m_attachmentExtent.width, m_attachmentExtent.height, 1u);
2322 m_pipelineLayout = makePipelineLayoutWithoutDescriptors(vk, device);
2324 GraphicsPipelineBuilder pipelineBuilder;
2326 .setRenderSize (tcu::IVec2(m_attachmentExtent.width, m_attachmentExtent.height))
2327 .setVertexInputSingleAttribute (m_vertices.getVertexFormat(), m_vertices.getVertexStride())
2328 .setShader (vk, device, VK_SHADER_STAGE_VERTEX_BIT, context.getBinaryCollection().get("draw_vert"), DE_NULL)
2329 .setShader (vk, device, VK_SHADER_STAGE_FRAGMENT_BIT, context.getBinaryCollection().get("draw_frag"), DE_NULL);
2331 m_pipeline = pipelineBuilder.build(vk, device, *m_pipelineLayout, *m_renderPass, context.getPipelineCacheData());
2333 // Set expected draw values
2335 m_expectedData.resize(static_cast<size_t>(getPixelBufferSize(m_resource.getImage().format, m_resource.getImage().extent)));
2336 tcu::PixelBufferAccess imagePixels(mapVkFormat(m_colorFormat), m_attachmentExtent.width, m_attachmentExtent.height, m_attachmentExtent.depth, &m_expectedData[0]);
2337 clearPixelBuffer(imagePixels, makeClearValue(m_colorFormat));
2340 void recordCommands (const VkCommandBuffer cmdBuffer)
2342 const DeviceInterface& vk = m_context.getDeviceInterface();
2344 // Change color attachment image layout
2346 const VkImageMemoryBarrier colorAttachmentLayoutBarrier = makeImageMemoryBarrier(
2347 (VkAccessFlags)0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2348 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
2349 m_colorImage, m_colorSubresourceRange);
2351 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0,
2352 0u, DE_NULL, 0u, DE_NULL, 1u, &colorAttachmentLayoutBarrier);
2356 const VkRect2D renderArea = {
2358 makeExtent2D(m_attachmentExtent.width, m_attachmentExtent.height),
2360 const tcu::Vec4 clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
2362 beginRenderPass(vk, cmdBuffer, *m_renderPass, *m_framebuffer, renderArea, clearColor);
2365 vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
2367 const VkDeviceSize vertexBufferOffset = 0ull;
2368 const VkBuffer vertexBuffer = m_vertices.getVertexBuffer();
2369 vk.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer, &vertexBufferOffset);
2372 if (m_drawCall == DRAW_CALL_DRAW_INDEXED || m_drawCall == DRAW_CALL_DRAW_INDEXED_INDIRECT)
2373 vk.cmdBindIndexBuffer(cmdBuffer, m_vertices.getIndexBuffer(), 0u, m_vertices.getIndexType());
2377 case DRAW_CALL_DRAW:
2378 vk.cmdDraw(cmdBuffer, m_vertices.getNumVertices(), 1u, 0u, 0u);
2381 case DRAW_CALL_DRAW_INDEXED:
2382 vk.cmdDrawIndexed(cmdBuffer, m_vertices.getNumIndices(), 1u, 0u, 0, 0u);
2385 case DRAW_CALL_DRAW_INDIRECT:
2386 vk.cmdDrawIndirect(cmdBuffer, **m_indirectBuffer, 0u, 1u, 0u);
2389 case DRAW_CALL_DRAW_INDEXED_INDIRECT:
2390 vk.cmdDrawIndexedIndirect(cmdBuffer, **m_indirectBuffer, 0u, 1u, 0u);
2394 endRenderPass(vk, cmdBuffer);
2397 SyncInfo getSyncInfo (void) const
2399 const SyncInfo syncInfo =
2401 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags stageMask;
2402 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags accessMask;
2403 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout imageLayout;
2408 Data getData (void) const
2412 m_expectedData.size(), // std::size_t size;
2413 &m_expectedData[0], // const deUint8* data;
2419 OperationContext& m_context;
2420 Resource& m_resource;
2421 const DrawCall m_drawCall;
2422 const VertexGrid m_vertices;
2423 std::vector<deUint8> m_expectedData;
2424 de::MovePtr<Buffer> m_indirectBuffer;
2425 VkFormat m_colorFormat;
2426 VkImage m_colorImage;
2427 Move<VkImageView> m_colorAttachmentView;
2428 VkImageSubresourceRange m_colorSubresourceRange;
2429 VkExtent3D m_attachmentExtent;
2430 Move<VkRenderPass> m_renderPass;
2431 Move<VkFramebuffer> m_framebuffer;
2432 Move<VkPipelineLayout> m_pipelineLayout;
2433 Move<VkPipeline> m_pipeline;
2436 template<typename T, std::size_t N>
2437 std::string toString (const T (&values)[N])
2439 std::ostringstream str;
2440 for (std::size_t i = 0; i < N; ++i)
2441 str << (i != 0 ? ", " : "") << values[i];
2445 class Support : public OperationSupport
2448 Support (const ResourceDescription& resourceDesc, const DrawCall drawCall)
2449 : m_resourceDesc (resourceDesc)
2450 , m_drawCall (drawCall)
2452 DE_ASSERT(m_resourceDesc.type == RESOURCE_TYPE_IMAGE && m_resourceDesc.imageType == VK_IMAGE_TYPE_2D);
2453 DE_ASSERT(!isDepthStencilFormat(m_resourceDesc.imageFormat));
2456 void initPrograms (SourceCollections& programCollection) const
2460 std::ostringstream src;
2461 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
2463 << "layout(location = 0) in vec4 v_in_position;\n"
2465 << "out " << s_perVertexBlock << ";\n"
2467 << "void main (void)\n"
2469 << " gl_Position = v_in_position;\n"
2472 programCollection.glslSources.add("draw_vert") << glu::VertexSource(src.str());
2477 const VkClearValue clearValue = makeClearValue(m_resourceDesc.imageFormat);
2478 const bool isIntegerFormat = isIntFormat(m_resourceDesc.imageFormat) || isUintFormat(m_resourceDesc.imageFormat);
2479 const std::string colorType = (isIntegerFormat ? "uvec4" : "vec4");
2481 std::ostringstream src;
2482 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
2484 << "layout(location = 0) out " << colorType << " o_color;\n"
2486 << "void main (void)\n"
2488 << " o_color = " << colorType << "(" << (isIntegerFormat ? toString(clearValue.color.uint32) : toString(clearValue.color.float32)) << ");\n"
2491 programCollection.glslSources.add("draw_frag") << glu::FragmentSource(src.str());
2495 deUint32 getResourceUsageFlags (void) const
2497 return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
2500 VkQueueFlags getQueueFlags (const OperationContext& context) const
2503 return VK_QUEUE_GRAPHICS_BIT;
2506 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
2508 return de::MovePtr<Operation>(new Implementation(context, resource, m_drawCall));
2512 const ResourceDescription m_resourceDesc;
2513 const DrawCall m_drawCall;
2518 namespace ClearAttachments
2521 class Implementation : public Operation
2524 Implementation (OperationContext& context, Resource& resource)
2525 : m_context (context)
2526 , m_resource (resource)
2527 , m_clearValue (makeClearValue(m_resource.getImage().format))
2529 const DeviceInterface& vk = context.getDeviceInterface();
2530 const VkDevice device = context.getDevice();
2532 const VkDeviceSize size = getPixelBufferSize(m_resource.getImage().format, m_resource.getImage().extent);
2533 const VkExtent3D& extent = m_resource.getImage().extent;
2534 const VkFormat format = m_resource.getImage().format;
2535 const tcu::TextureFormat texFormat = mapVkFormat(format);
2536 const SyncInfo syncInfo = getSyncInfo();
2538 m_data.resize(static_cast<std::size_t>(size));
2539 tcu::PixelBufferAccess imagePixels(texFormat, extent.width, extent.height, extent.depth, &m_data[0]);
2540 clearPixelBuffer(imagePixels, m_clearValue);
2542 m_attachmentView = makeImageView(vk, device, m_resource.getImage().handle, getImageViewType(m_resource.getImage().imageType), m_resource.getImage().format, m_resource.getImage().subresourceRange);
2544 const VkAttachmentDescription colorAttachmentDescription =
2546 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
2547 m_resource.getImage().format, // VkFormat format;
2548 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
2549 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp;
2550 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
2551 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
2552 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp stencilStoreOp;
2553 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
2554 syncInfo.imageLayout // VkImageLayout finalLayout;
2557 const VkAttachmentReference colorAttachmentReference =
2559 0u, // deUint32 attachment;
2560 syncInfo.imageLayout // VkImageLayout layout;
2563 const VkAttachmentReference depthStencilAttachmentReference =
2565 0u, // deUint32 attachment;
2566 syncInfo.imageLayout // VkImageLayout layout;
2569 VkSubpassDescription subpassDescription =
2571 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags;
2572 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
2573 0u, // deUint32 inputAttachmentCount;
2574 DE_NULL, // const VkAttachmentReference* pInputAttachments;
2575 0u, // deUint32 colorAttachmentCount;
2576 DE_NULL, // const VkAttachmentReference* pColorAttachments;
2577 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
2578 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
2579 0u, // deUint32 preserveAttachmentCount;
2580 DE_NULL // const deUint32* pPreserveAttachments;
2583 switch (m_resource.getImage().subresourceRange.aspectMask)
2585 case VK_IMAGE_ASPECT_COLOR_BIT:
2586 subpassDescription.colorAttachmentCount = 1u;
2587 subpassDescription.pColorAttachments = &colorAttachmentReference;
2589 case VK_IMAGE_ASPECT_STENCIL_BIT:
2590 case VK_IMAGE_ASPECT_DEPTH_BIT:
2591 subpassDescription.pDepthStencilAttachment = &depthStencilAttachmentReference;
2598 const VkRenderPassCreateInfo renderPassInfo =
2600 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
2601 DE_NULL, // const void* pNext;
2602 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags;
2603 1u, // deUint32 attachmentCount;
2604 &colorAttachmentDescription, // const VkAttachmentDescription* pAttachments;
2605 1u, // deUint32 subpassCount;
2606 &subpassDescription, // const VkSubpassDescription* pSubpasses;
2607 0u, // deUint32 dependencyCount;
2608 DE_NULL // const VkSubpassDependency* pDependencies;
2611 m_renderPass = createRenderPass(vk, device, &renderPassInfo);
2612 m_frameBuffer = makeFramebuffer(vk, device, *m_renderPass, *m_attachmentView, m_resource.getImage().extent.width, m_resource.getImage().extent.height, 1u);
2615 void recordCommands (const VkCommandBuffer cmdBuffer)
2617 const DeviceInterface& vk = m_context.getDeviceInterface();
2618 const VkRenderPassBeginInfo renderPassBeginInfo =
2620 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
2621 DE_NULL, // const void* pNext;
2622 *m_renderPass, // VkRenderPass renderPass;
2623 *m_frameBuffer, // VkFramebuffer framebuffer;
2625 { 0, 0 }, // VkOffset2D offset;
2627 m_resource.getImage().extent.width, // deUint32 width;
2628 m_resource.getImage().extent.height // deUint32 height;
2629 } // VkExtent2D extent;
2630 }, // VkRect2D renderArea;
2631 1u, // deUint32 clearValueCount;
2632 &m_clearValue // const VkClearValue* pClearValues;
2635 vk.cmdBeginRenderPass(cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
2637 const VkClearAttachment clearAttachment =
2639 m_resource.getImage().subresourceRange.aspectMask, // VkImageAspectFlags aspectMask;
2640 0, // deUint32 colorAttachment;
2641 m_clearValue // VkClearValue clearValue;
2644 const VkRect2D rect2D =
2646 { 0u, 0u, }, // VkOffset2D offset;
2647 { m_resource.getImage().extent.width, m_resource.getImage().extent.height }, // VkExtent2D extent;
2650 const VkClearRect clearRect =
2652 rect2D, // VkRect2D rect;
2653 0u, // deUint32 baseArrayLayer;
2654 m_resource.getImage().subresourceLayers.layerCount // deUint32 layerCount;
2657 vk.cmdClearAttachments(cmdBuffer, 1, &clearAttachment, 1, &clearRect);
2659 vk.cmdEndRenderPass(cmdBuffer);
2662 SyncInfo getSyncInfo (void) const
2665 syncInfo.stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
2667 switch (m_resource.getImage().subresourceRange.aspectMask)
2669 case VK_IMAGE_ASPECT_COLOR_BIT:
2670 syncInfo.accessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
2671 syncInfo.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
2673 case VK_IMAGE_ASPECT_STENCIL_BIT:
2674 case VK_IMAGE_ASPECT_DEPTH_BIT:
2675 syncInfo.accessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
2676 syncInfo.imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
2686 Data getData (void) const
2690 m_data.size(), // std::size_t size;
2691 &m_data[0], // const deUint8* data;
2697 OperationContext& m_context;
2698 Resource& m_resource;
2699 std::vector<deUint8> m_data;
2700 const VkClearValue m_clearValue;
2701 Move<VkImageView> m_attachmentView;
2702 Move<VkRenderPass> m_renderPass;
2703 Move<VkFramebuffer> m_frameBuffer;
2706 class Support : public OperationSupport
2709 Support (const ResourceDescription& resourceDesc)
2710 : m_resourceDesc (resourceDesc)
2712 DE_ASSERT(m_resourceDesc.type == RESOURCE_TYPE_IMAGE);
2715 deUint32 getResourceUsageFlags (void) const
2717 switch (m_resourceDesc.imageAspect)
2719 case VK_IMAGE_ASPECT_COLOR_BIT:
2720 return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
2721 case VK_IMAGE_ASPECT_STENCIL_BIT:
2722 case VK_IMAGE_ASPECT_DEPTH_BIT:
2723 return VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
2730 VkQueueFlags getQueueFlags (const OperationContext& context) const
2733 return VK_QUEUE_GRAPHICS_BIT;
2736 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
2738 return de::MovePtr<Operation>(new Implementation(context, resource));
2742 const ResourceDescription m_resourceDesc;
2745 } // ClearAttachments
2747 namespace IndirectBuffer
2750 class GraphicsPipeline : public Pipeline
2753 GraphicsPipeline (OperationContext& context,
2754 const ResourceType resourceType,
2755 const VkBuffer indirectBuffer,
2756 const std::string& shaderPrefix,
2757 const VkDescriptorSetLayout descriptorSetLayout)
2758 : m_resourceType (resourceType)
2759 , m_indirectBuffer (indirectBuffer)
2760 , m_vertices (context)
2762 const DeviceInterface& vk = context.getDeviceInterface();
2763 const VkDevice device = context.getDevice();
2764 Allocator& allocator = context.getAllocator();
2768 m_colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
2769 m_colorImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
2770 m_colorImageExtent = makeExtent3D(16u, 16u, 1u);
2771 m_colorAttachmentImage = de::MovePtr<Image>(new Image(vk, device, allocator,
2772 makeImageCreateInfo(VK_IMAGE_TYPE_2D, m_colorImageExtent, m_colorFormat, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT),
2773 MemoryRequirement::Any));
2777 m_colorAttachmentView = makeImageView (vk, device, **m_colorAttachmentImage, VK_IMAGE_VIEW_TYPE_2D, m_colorFormat, m_colorImageSubresourceRange);
2778 m_renderPass = makeRenderPass (vk, device, m_colorFormat);
2779 m_framebuffer = makeFramebuffer (vk, device, *m_renderPass, *m_colorAttachmentView, m_colorImageExtent.width, m_colorImageExtent.height, 1u);
2780 m_pipelineLayout = makePipelineLayout(vk, device, descriptorSetLayout);
2782 GraphicsPipelineBuilder pipelineBuilder;
2784 .setRenderSize (tcu::IVec2(m_colorImageExtent.width, m_colorImageExtent.height))
2785 .setVertexInputSingleAttribute (m_vertices.getVertexFormat(), m_vertices.getVertexStride())
2786 .setShader (vk, device, VK_SHADER_STAGE_VERTEX_BIT, context.getBinaryCollection().get(shaderPrefix + "vert"), DE_NULL)
2787 .setShader (vk, device, VK_SHADER_STAGE_FRAGMENT_BIT, context.getBinaryCollection().get(shaderPrefix + "frag"), DE_NULL);
2789 m_pipeline = pipelineBuilder.build(vk, device, *m_pipelineLayout, *m_renderPass, context.getPipelineCacheData());
2792 void recordCommands (OperationContext& context, const VkCommandBuffer cmdBuffer, const VkDescriptorSet descriptorSet)
2794 const DeviceInterface& vk = context.getDeviceInterface();
2796 // Change color attachment image layout
2798 const VkImageMemoryBarrier colorAttachmentLayoutBarrier = makeImageMemoryBarrier(
2799 (VkAccessFlags)0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2800 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
2801 **m_colorAttachmentImage, m_colorImageSubresourceRange);
2803 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0,
2804 0u, DE_NULL, 0u, DE_NULL, 1u, &colorAttachmentLayoutBarrier);
2808 const VkRect2D renderArea = {
2810 makeExtent2D(m_colorImageExtent.width, m_colorImageExtent.height),
2812 const tcu::Vec4 clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
2814 beginRenderPass(vk, cmdBuffer, *m_renderPass, *m_framebuffer, renderArea, clearColor);
2817 vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
2818 vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &descriptorSet, 0u, DE_NULL);
2820 const VkDeviceSize vertexBufferOffset = 0ull;
2821 const VkBuffer vertexBuffer = m_vertices.getVertexBuffer();
2822 vk.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer, &vertexBufferOffset);
2825 switch (m_resourceType)
2827 case RESOURCE_TYPE_INDIRECT_BUFFER_DRAW:
2828 vk.cmdDrawIndirect(cmdBuffer, m_indirectBuffer, 0u, 1u, 0u);
2831 case RESOURCE_TYPE_INDIRECT_BUFFER_DRAW_INDEXED:
2832 vk.cmdBindIndexBuffer(cmdBuffer, m_vertices.getIndexBuffer(), 0u, m_vertices.getIndexType());
2833 vk.cmdDrawIndexedIndirect(cmdBuffer, m_indirectBuffer, 0u, 1u, 0u);
2840 endRenderPass(vk, cmdBuffer);
2844 const ResourceType m_resourceType;
2845 const VkBuffer m_indirectBuffer;
2846 const VertexGrid m_vertices;
2847 VkFormat m_colorFormat;
2848 de::MovePtr<Image> m_colorAttachmentImage;
2849 Move<VkImageView> m_colorAttachmentView;
2850 VkExtent3D m_colorImageExtent;
2851 VkImageSubresourceRange m_colorImageSubresourceRange;
2852 Move<VkRenderPass> m_renderPass;
2853 Move<VkFramebuffer> m_framebuffer;
2854 Move<VkPipelineLayout> m_pipelineLayout;
2855 Move<VkPipeline> m_pipeline;
2858 class ComputePipeline : public Pipeline
2861 ComputePipeline (OperationContext& context,
2862 const VkBuffer indirectBuffer,
2863 const std::string& shaderPrefix,
2864 const VkDescriptorSetLayout descriptorSetLayout)
2865 : m_indirectBuffer (indirectBuffer)
2867 const DeviceInterface& vk = context.getDeviceInterface();
2868 const VkDevice device = context.getDevice();
2870 const Unique<VkShaderModule> shaderModule(createShaderModule(vk, device, context.getBinaryCollection().get(shaderPrefix + "comp"), (VkShaderModuleCreateFlags)0));
2872 m_pipelineLayout = makePipelineLayout(vk, device, descriptorSetLayout);
2873 m_pipeline = makeComputePipeline(vk, device, *m_pipelineLayout, *shaderModule, DE_NULL, context.getPipelineCacheData());
2876 void recordCommands (OperationContext& context, const VkCommandBuffer cmdBuffer, const VkDescriptorSet descriptorSet)
2878 const DeviceInterface& vk = context.getDeviceInterface();
2880 vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipeline);
2881 vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0u, 1u, &descriptorSet, 0u, DE_NULL);
2882 vk.cmdDispatchIndirect(cmdBuffer, m_indirectBuffer, 0u);
2886 const VkBuffer m_indirectBuffer;
2887 Move<VkPipelineLayout> m_pipelineLayout;
2888 Move<VkPipeline> m_pipeline;
2891 //! Read indirect buffer by executing an indirect draw or dispatch command.
2892 class ReadImplementation : public Operation
2895 ReadImplementation (OperationContext& context, Resource& resource)
2896 : m_context (context)
2897 , m_resource (resource)
2898 , m_stage (resource.getType() == RESOURCE_TYPE_INDIRECT_BUFFER_DISPATCH ? VK_SHADER_STAGE_COMPUTE_BIT : VK_SHADER_STAGE_VERTEX_BIT)
2899 , m_pipelineStage (pipelineStageFlagsFromShaderStageFlagBits(m_stage))
2900 , m_hostBufferSizeBytes (sizeof(deUint32))
2902 requireFeaturesForSSBOAccess (m_context, m_stage);
2904 const DeviceInterface& vk = m_context.getDeviceInterface();
2905 const VkDevice device = m_context.getDevice();
2906 Allocator& allocator = m_context.getAllocator();
2908 m_hostBuffer = de::MovePtr<Buffer>(new Buffer(
2909 vk, device, allocator, makeBufferCreateInfo(m_hostBufferSizeBytes, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible));
2911 // Init host buffer data
2913 const Allocation& alloc = m_hostBuffer->getAllocation();
2914 deMemset(alloc.getHostPtr(), 0, static_cast<size_t>(m_hostBufferSizeBytes));
2915 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), static_cast<size_t>(m_hostBufferSizeBytes));
2918 // Prepare descriptors
2920 m_descriptorSetLayout = DescriptorSetLayoutBuilder()
2921 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, m_stage)
2924 m_descriptorPool = DescriptorPoolBuilder()
2925 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
2926 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
2928 m_descriptorSet = makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout);
2930 const VkDescriptorBufferInfo hostBufferInfo = makeDescriptorBufferInfo(**m_hostBuffer, 0u, m_hostBufferSizeBytes);
2932 DescriptorSetUpdateBuilder()
2933 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &hostBufferInfo)
2934 .update(vk, device);
2938 m_pipeline = (m_resource.getType() == RESOURCE_TYPE_INDIRECT_BUFFER_DISPATCH
2939 ? de::MovePtr<Pipeline>(new ComputePipeline(context, m_resource.getBuffer().handle, "read_ib_", *m_descriptorSetLayout))
2940 : de::MovePtr<Pipeline>(new GraphicsPipeline(context, m_resource.getType(), m_resource.getBuffer().handle, "read_ib_", *m_descriptorSetLayout)));
2943 void recordCommands (const VkCommandBuffer cmdBuffer)
2945 const DeviceInterface& vk = m_context.getDeviceInterface();
2947 m_pipeline->recordCommands(m_context, cmdBuffer, *m_descriptorSet);
2949 // Insert a barrier so data written by the shader is available to the host
2950 const VkBufferMemoryBarrier barrier = makeBufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, **m_hostBuffer, 0u, m_hostBufferSizeBytes);
2951 vk.cmdPipelineBarrier(cmdBuffer, m_pipelineStage, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
2954 SyncInfo getSyncInfo (void) const
2956 const SyncInfo syncInfo =
2958 VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, // VkPipelineStageFlags stageMask;
2959 VK_ACCESS_INDIRECT_COMMAND_READ_BIT, // VkAccessFlags accessMask;
2960 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
2965 Data getData (void) const
2967 return getHostBufferData(m_context, *m_hostBuffer, m_hostBufferSizeBytes);
2971 OperationContext& m_context;
2972 Resource& m_resource;
2973 const VkShaderStageFlagBits m_stage;
2974 const VkPipelineStageFlags m_pipelineStage;
2975 const VkDeviceSize m_hostBufferSizeBytes;
2976 de::MovePtr<Buffer> m_hostBuffer;
2977 Move<VkDescriptorPool> m_descriptorPool;
2978 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
2979 Move<VkDescriptorSet> m_descriptorSet;
2980 de::MovePtr<Pipeline> m_pipeline;
2983 //! Prepare indirect buffer for a draw/dispatch call.
2984 class WriteImplementation : public Operation
2987 WriteImplementation (OperationContext& context, Resource& resource)
2988 : m_context (context)
2989 , m_resource (resource)
2991 switch (m_resource.getType())
2993 case RESOURCE_TYPE_INDIRECT_BUFFER_DRAW:
2995 m_drawIndirect.vertexCount = 6u;
2996 m_drawIndirect.instanceCount = 1u;
2997 m_drawIndirect.firstVertex = 0u;
2998 m_drawIndirect.firstInstance = 0u;
3000 m_indirectData = reinterpret_cast<deUint32*>(&m_drawIndirect);
3001 m_expectedValue = 6u;
3005 case RESOURCE_TYPE_INDIRECT_BUFFER_DRAW_INDEXED:
3007 m_drawIndexedIndirect.indexCount = 6u;
3008 m_drawIndexedIndirect.instanceCount = 1u;
3009 m_drawIndexedIndirect.firstIndex = 0u;
3010 m_drawIndexedIndirect.vertexOffset = 0u;
3011 m_drawIndexedIndirect.firstInstance = 0u;
3013 m_indirectData = reinterpret_cast<deUint32*>(&m_drawIndexedIndirect);
3014 m_expectedValue = 6u;
3018 case RESOURCE_TYPE_INDIRECT_BUFFER_DISPATCH:
3020 m_dispatchIndirect.x = 7u;
3021 m_dispatchIndirect.y = 2u;
3022 m_dispatchIndirect.z = 1u;
3024 m_indirectData = reinterpret_cast<deUint32*>(&m_dispatchIndirect);
3025 m_expectedValue = 14u;
3035 void recordCommands (const VkCommandBuffer cmdBuffer)
3037 const DeviceInterface& vk = m_context.getDeviceInterface();
3039 vk.cmdUpdateBuffer(cmdBuffer, m_resource.getBuffer().handle, m_resource.getBuffer().offset, m_resource.getBuffer().size, m_indirectData);
3042 SyncInfo getSyncInfo (void) const
3044 const SyncInfo syncInfo =
3046 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
3047 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags accessMask;
3048 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
3053 Data getData (void) const
3057 sizeof(deUint32), // std::size_t size;
3058 reinterpret_cast<const deUint8*>(&m_expectedValue), // const deUint8* data;
3064 OperationContext& m_context;
3065 Resource& m_resource;
3066 VkDrawIndirectCommand m_drawIndirect;
3067 VkDrawIndexedIndirectCommand m_drawIndexedIndirect;
3068 VkDispatchIndirectCommand m_dispatchIndirect;
3069 deUint32* m_indirectData;
3070 deUint32 m_expectedValue; //! Side-effect value expected to be computed by a read (draw/dispatch) command.
3073 class ReadSupport : public OperationSupport
3076 ReadSupport (const ResourceDescription& resourceDesc)
3077 : m_resourceDesc (resourceDesc)
3079 DE_ASSERT(isIndirectBuffer(m_resourceDesc.type));
3082 void initPrograms (SourceCollections& programCollection) const
3084 std::ostringstream decl;
3085 decl << "layout(set = 0, binding = 0, std140) coherent buffer Data {\n"
3089 std::ostringstream main;
3090 main << " atomicAdd(sb_out.value, 1u);\n";
3094 std::ostringstream src;
3095 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
3097 << "layout(location = 0) in vec4 v_in_position;\n"
3099 << "out " << s_perVertexBlock << ";\n"
3103 << "void main (void)\n"
3105 << " gl_Position = v_in_position;\n"
3109 programCollection.glslSources.add("read_ib_vert") << glu::VertexSource(src.str());
3114 std::ostringstream src;
3115 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
3117 << "layout(location = 0) out vec4 o_color;\n"
3119 << "void main (void)\n"
3121 << " o_color = vec4(1.0);\n"
3124 programCollection.glslSources.add("read_ib_frag") << glu::FragmentSource(src.str());
3129 std::ostringstream src;
3130 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
3132 << "layout(local_size_x = 1) in;\n"
3136 << "void main (void)\n"
3141 programCollection.glslSources.add("read_ib_comp") << glu::ComputeSource(src.str());
3145 deUint32 getResourceUsageFlags (void) const
3147 return VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
3150 VkQueueFlags getQueueFlags (const OperationContext& context) const
3153 return (m_resourceDesc.type == RESOURCE_TYPE_INDIRECT_BUFFER_DISPATCH ? VK_QUEUE_COMPUTE_BIT : VK_QUEUE_GRAPHICS_BIT);
3156 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
3158 return de::MovePtr<Operation>(new ReadImplementation(context, resource));
3162 const ResourceDescription m_resourceDesc;
3166 class WriteSupport : public OperationSupport
3169 WriteSupport (const ResourceDescription& resourceDesc)
3171 DE_ASSERT(isIndirectBuffer(resourceDesc.type));
3172 DE_UNREF(resourceDesc);
3175 deUint32 getResourceUsageFlags (void) const
3177 return VK_BUFFER_USAGE_TRANSFER_DST_BIT;
3180 VkQueueFlags getQueueFlags (const OperationContext& context) const
3183 return VK_QUEUE_TRANSFER_BIT;
3186 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
3188 return de::MovePtr<Operation>(new WriteImplementation(context, resource));
3192 } // IndirectBuffer ns
3194 namespace VertexInput
3197 class Implementation : public Operation
3200 Implementation (OperationContext& context, Resource& resource)
3201 : m_context (context)
3202 , m_resource (resource)
3204 requireFeaturesForSSBOAccess (m_context, VK_SHADER_STAGE_VERTEX_BIT);
3206 const DeviceInterface& vk = context.getDeviceInterface();
3207 const VkDevice device = context.getDevice();
3208 Allocator& allocator = context.getAllocator();
3209 const VkDeviceSize dataSizeBytes = m_resource.getBuffer().size;
3211 m_outputBuffer = de::MovePtr<Buffer>(new Buffer(vk, device, allocator,
3212 makeBufferCreateInfo(dataSizeBytes, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible));
3215 const Allocation& alloc = m_outputBuffer->getAllocation();
3216 deMemset(alloc.getHostPtr(), 0, static_cast<size_t>(dataSizeBytes));
3217 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), dataSizeBytes);
3220 m_descriptorSetLayout = DescriptorSetLayoutBuilder()
3221 .addSingleBinding (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_VERTEX_BIT)
3222 .build (vk, device);
3224 m_descriptorPool = DescriptorPoolBuilder()
3225 .addType (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
3226 .build (vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
3228 m_descriptorSet = makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout);
3230 const VkDescriptorBufferInfo outputBufferDescriptorInfo = makeDescriptorBufferInfo(m_outputBuffer->get(), 0ull, dataSizeBytes);
3231 DescriptorSetUpdateBuilder()
3232 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outputBufferDescriptorInfo)
3233 .update (vk, device);
3236 m_colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
3237 m_colorImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
3238 m_colorImageExtent = makeExtent3D(16u, 16u, 1u);
3239 m_colorAttachmentImage = de::MovePtr<Image>(new Image(vk, device, allocator,
3240 makeImageCreateInfo(VK_IMAGE_TYPE_2D, m_colorImageExtent, m_colorFormat, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT),
3241 MemoryRequirement::Any));
3244 m_colorAttachmentView = makeImageView (vk, device, **m_colorAttachmentImage, VK_IMAGE_VIEW_TYPE_2D, m_colorFormat, m_colorImageSubresourceRange);
3245 m_renderPass = makeRenderPass (vk, device, m_colorFormat);
3246 m_framebuffer = makeFramebuffer (vk, device, *m_renderPass, *m_colorAttachmentView, m_colorImageExtent.width, m_colorImageExtent.height, 1u);
3247 m_pipelineLayout = makePipelineLayout(vk, device, *m_descriptorSetLayout);
3249 m_pipeline = GraphicsPipelineBuilder()
3250 .setPrimitiveTopology (VK_PRIMITIVE_TOPOLOGY_POINT_LIST)
3251 .setRenderSize (tcu::IVec2(static_cast<int>(m_colorImageExtent.width), static_cast<int>(m_colorImageExtent.height)))
3252 .setVertexInputSingleAttribute (VK_FORMAT_R32G32B32A32_UINT, tcu::getPixelSize(mapVkFormat(VK_FORMAT_R32G32B32A32_UINT)))
3253 .setShader (vk, device, VK_SHADER_STAGE_VERTEX_BIT, context.getBinaryCollection().get("input_vert"), DE_NULL)
3254 .setShader (vk, device, VK_SHADER_STAGE_FRAGMENT_BIT, context.getBinaryCollection().get("input_frag"), DE_NULL)
3255 .build (vk, device, *m_pipelineLayout, *m_renderPass, context.getPipelineCacheData());
3258 void recordCommands (const VkCommandBuffer cmdBuffer)
3260 const DeviceInterface& vk = m_context.getDeviceInterface();
3261 const VkDeviceSize dataSizeBytes = m_resource.getBuffer().size;
3263 // Change color attachment image layout
3265 const VkImageMemoryBarrier colorAttachmentLayoutBarrier = makeImageMemoryBarrier(
3266 (VkAccessFlags)0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
3267 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
3268 **m_colorAttachmentImage, m_colorImageSubresourceRange);
3270 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0,
3271 0u, DE_NULL, 0u, DE_NULL, 1u, &colorAttachmentLayoutBarrier);
3275 const VkRect2D renderArea = {
3277 makeExtent2D(m_colorImageExtent.width, m_colorImageExtent.height),
3279 const tcu::Vec4 clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
3281 beginRenderPass(vk, cmdBuffer, *m_renderPass, *m_framebuffer, renderArea, clearColor);
3284 vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
3285 vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &m_descriptorSet.get(), 0u, DE_NULL);
3287 const VkDeviceSize vertexBufferOffset = 0ull;
3288 vk.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &m_resource.getBuffer().handle, &vertexBufferOffset);
3291 vk.cmdDraw(cmdBuffer, static_cast<deUint32>(dataSizeBytes / sizeof(tcu::UVec4)), 1u, 0u, 0u);
3293 endRenderPass(vk, cmdBuffer);
3295 // Insert a barrier so data written by the shader is available to the host
3297 const VkBufferMemoryBarrier barrier = makeBufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, **m_outputBuffer, 0u, m_resource.getBuffer().size);
3298 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
3302 SyncInfo getSyncInfo (void) const
3304 const SyncInfo syncInfo =
3306 VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, // VkPipelineStageFlags stageMask;
3307 VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, // VkAccessFlags accessMask;
3308 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
3313 Data getData (void) const
3315 return getHostBufferData(m_context, *m_outputBuffer, m_resource.getBuffer().size);
3319 OperationContext& m_context;
3320 Resource& m_resource;
3321 de::MovePtr<Buffer> m_outputBuffer;
3322 de::MovePtr<Buffer> m_indexBuffer;
3323 de::MovePtr<Buffer> m_indirectBuffer;
3324 Move<VkRenderPass> m_renderPass;
3325 Move<VkFramebuffer> m_framebuffer;
3326 Move<VkPipelineLayout> m_pipelineLayout;
3327 Move<VkPipeline> m_pipeline;
3328 VkFormat m_colorFormat;
3329 de::MovePtr<Image> m_colorAttachmentImage;
3330 Move<VkImageView> m_colorAttachmentView;
3331 VkExtent3D m_colorImageExtent;
3332 VkImageSubresourceRange m_colorImageSubresourceRange;
3333 Move<VkDescriptorPool> m_descriptorPool;
3334 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
3335 Move<VkDescriptorSet> m_descriptorSet;
3338 class Support : public OperationSupport
3341 Support (const ResourceDescription& resourceDesc)
3342 : m_resourceDesc (resourceDesc)
3344 DE_ASSERT(m_resourceDesc.type == RESOURCE_TYPE_BUFFER);
3347 void initPrograms (SourceCollections& programCollection) const
3351 int vertexStride = sizeof(tcu::UVec4);
3352 std::ostringstream src;
3353 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
3355 << "layout(location = 0) in uvec4 v_in_data;\n"
3356 << "layout(set = 0, binding = 0, std140) writeonly buffer Output {\n"
3357 << " uvec4 data[" << m_resourceDesc.size.x()/vertexStride << "];\n"
3360 << "void main (void)\n"
3362 << " b_out.data[gl_VertexIndex] = v_in_data;\n"
3364 programCollection.glslSources.add("input_vert") << glu::VertexSource(src.str());
3369 std::ostringstream src;
3370 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
3372 << "layout(location = 0) out vec4 o_color;\n"
3374 << "void main (void)\n"
3376 << " o_color = vec4(1.0);\n"
3378 programCollection.glslSources.add("input_frag") << glu::FragmentSource(src.str());
3382 deUint32 getResourceUsageFlags (void) const
3384 return VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
3387 VkQueueFlags getQueueFlags (const OperationContext& context) const
3390 return VK_QUEUE_GRAPHICS_BIT;
3393 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
3395 return de::MovePtr<Operation>(new Implementation(context, resource));
3399 const ResourceDescription m_resourceDesc;
3406 OperationContext::OperationContext (Context& context, PipelineCacheData& pipelineCacheData)
3407 : m_vki (context.getInstanceInterface())
3408 , m_vk (context.getDeviceInterface())
3409 , m_physicalDevice (context.getPhysicalDevice())
3410 , m_device (context.getDevice())
3411 , m_allocator (context.getDefaultAllocator())
3412 , m_progCollection (context.getBinaryCollection())
3413 , m_pipelineCacheData (pipelineCacheData)
3414 , m_deviceExtensions (context.getDeviceExtensions())
3418 OperationContext::OperationContext (Context& context, PipelineCacheData& pipelineCacheData, const DeviceInterface& vk, const VkDevice device, vk::Allocator& allocator)
3419 : m_vki (context.getInstanceInterface())
3421 , m_physicalDevice (context.getPhysicalDevice())
3423 , m_allocator (allocator)
3424 , m_progCollection (context.getBinaryCollection())
3425 , m_pipelineCacheData (pipelineCacheData)
3426 , m_deviceExtensions (context.getDeviceExtensions())
3430 OperationContext::OperationContext (const vk::InstanceInterface& vki,
3431 const vk::DeviceInterface& vkd,
3432 vk::VkPhysicalDevice physicalDevice,
3433 vk::VkDevice device,
3434 vk::Allocator& allocator,
3435 const std::vector<std::string>& deviceExtensions,
3436 vk::ProgramCollection<vk::ProgramBinary>& programCollection,
3437 PipelineCacheData& pipelineCacheData)
3440 , m_physicalDevice (physicalDevice)
3442 , m_allocator (allocator)
3443 , m_progCollection (programCollection)
3444 , m_pipelineCacheData (pipelineCacheData)
3445 , m_deviceExtensions (deviceExtensions)
3449 Resource::Resource (OperationContext& context, const ResourceDescription& desc, const deUint32 usage, const vk::VkSharingMode sharingMode, const std::vector<deUint32>& queueFamilyIndex)
3450 : m_type (desc.type)
3452 const DeviceInterface& vk = context.getDeviceInterface();
3453 const InstanceInterface& vki = context.getInstanceInterface();
3454 const VkDevice device = context.getDevice();
3455 const VkPhysicalDevice physDevice = context.getPhysicalDevice();
3456 Allocator& allocator = context.getAllocator();
3458 if (m_type == RESOURCE_TYPE_BUFFER || isIndirectBuffer(m_type))
3460 m_bufferData.offset = 0u;
3461 m_bufferData.size = static_cast<VkDeviceSize>(desc.size.x());
3462 VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(m_bufferData.size, usage);
3463 bufferCreateInfo.sharingMode = sharingMode;
3464 if (queueFamilyIndex.size() > 0)
3466 bufferCreateInfo.queueFamilyIndexCount = static_cast<deUint32>(queueFamilyIndex.size());
3467 bufferCreateInfo.pQueueFamilyIndices = &queueFamilyIndex[0];
3469 m_buffer = de::MovePtr<Buffer>(new Buffer(vk, device, allocator, bufferCreateInfo, MemoryRequirement::Any));
3470 m_bufferData.handle = **m_buffer;
3472 else if (m_type == RESOURCE_TYPE_IMAGE)
3474 m_imageData.extent = makeExtent3D(desc.size.x(), std::max(1, desc.size.y()), std::max(1, desc.size.z()));
3475 m_imageData.imageType = desc.imageType;
3476 m_imageData.format = desc.imageFormat;
3477 m_imageData.subresourceRange = makeImageSubresourceRange(desc.imageAspect, 0u, 1u, 0u, 1u);
3478 m_imageData.subresourceLayers = makeImageSubresourceLayers(desc.imageAspect, 0u, 0u, 1u);
3479 VkImageCreateInfo imageInfo = makeImageCreateInfo(m_imageData.imageType, m_imageData.extent, m_imageData.format, usage);
3480 imageInfo.sharingMode = sharingMode;
3481 if (queueFamilyIndex.size() > 0)
3483 imageInfo.queueFamilyIndexCount = static_cast<deUint32>(queueFamilyIndex.size());
3484 imageInfo.pQueueFamilyIndices = &queueFamilyIndex[0];
3487 VkImageFormatProperties imageFormatProperties;
3488 const VkResult formatResult = vki.getPhysicalDeviceImageFormatProperties(physDevice, imageInfo.format, imageInfo.imageType, imageInfo.tiling, imageInfo.usage, imageInfo.flags, &imageFormatProperties);
3490 if (formatResult != VK_SUCCESS)
3491 TCU_THROW(NotSupportedError, "Image format is not supported");
3493 m_image = de::MovePtr<Image>(new Image(vk, device, allocator, imageInfo, MemoryRequirement::Any));
3494 m_imageData.handle = **m_image;
3500 Resource::Resource (ResourceType type,
3501 vk::Move<vk::VkBuffer> buffer,
3502 de::MovePtr<vk::Allocation> allocation,
3503 vk::VkDeviceSize offset,
3504 vk::VkDeviceSize size)
3506 , m_buffer (new Buffer(buffer, allocation))
3508 DE_ASSERT(type != RESOURCE_TYPE_IMAGE);
3510 m_bufferData.handle = m_buffer->get();
3511 m_bufferData.offset = offset;
3512 m_bufferData.size = size;
3515 Resource::Resource (vk::Move<vk::VkImage> image,
3516 de::MovePtr<vk::Allocation> allocation,
3517 const vk::VkExtent3D& extent,
3518 vk::VkImageType imageType,
3519 vk::VkFormat format,
3520 vk::VkImageSubresourceRange subresourceRange,
3521 vk::VkImageSubresourceLayers subresourceLayers)
3522 : m_type (RESOURCE_TYPE_IMAGE)
3523 , m_image (new Image(image, allocation))
3525 m_imageData.handle = m_image->get();
3526 m_imageData.extent = extent;
3527 m_imageData.imageType = imageType;
3528 m_imageData.format = format;
3529 m_imageData.subresourceRange = subresourceRange;
3530 m_imageData.subresourceLayers = subresourceLayers;
3533 vk::VkDeviceMemory Resource::getMemory (void) const
3535 if (m_type == RESOURCE_TYPE_IMAGE)
3536 return m_image->getAllocation().getMemory();
3538 return m_buffer->getAllocation().getMemory();
3541 //! \note This function exists for performance reasons. We're creating a lot of tests and checking requirements here
3542 //! before creating an OperationSupport object is faster.
3543 bool isResourceSupported (const OperationName opName, const ResourceDescription& resourceDesc)
3547 case OPERATION_NAME_WRITE_FILL_BUFFER:
3548 case OPERATION_NAME_WRITE_COPY_BUFFER:
3549 case OPERATION_NAME_WRITE_COPY_IMAGE_TO_BUFFER:
3550 case OPERATION_NAME_WRITE_SSBO_VERTEX:
3551 case OPERATION_NAME_WRITE_SSBO_TESSELLATION_CONTROL:
3552 case OPERATION_NAME_WRITE_SSBO_TESSELLATION_EVALUATION:
3553 case OPERATION_NAME_WRITE_SSBO_GEOMETRY:
3554 case OPERATION_NAME_WRITE_SSBO_FRAGMENT:
3555 case OPERATION_NAME_WRITE_SSBO_COMPUTE:
3556 case OPERATION_NAME_WRITE_SSBO_COMPUTE_INDIRECT:
3557 case OPERATION_NAME_READ_COPY_BUFFER:
3558 case OPERATION_NAME_READ_COPY_BUFFER_TO_IMAGE:
3559 case OPERATION_NAME_READ_SSBO_VERTEX:
3560 case OPERATION_NAME_READ_SSBO_TESSELLATION_CONTROL:
3561 case OPERATION_NAME_READ_SSBO_TESSELLATION_EVALUATION:
3562 case OPERATION_NAME_READ_SSBO_GEOMETRY:
3563 case OPERATION_NAME_READ_SSBO_FRAGMENT:
3564 case OPERATION_NAME_READ_SSBO_COMPUTE:
3565 case OPERATION_NAME_READ_SSBO_COMPUTE_INDIRECT:
3566 case OPERATION_NAME_READ_VERTEX_INPUT:
3567 return resourceDesc.type == RESOURCE_TYPE_BUFFER;
3569 case OPERATION_NAME_WRITE_INDIRECT_BUFFER_DRAW:
3570 case OPERATION_NAME_READ_INDIRECT_BUFFER_DRAW:
3571 return resourceDesc.type == RESOURCE_TYPE_INDIRECT_BUFFER_DRAW;
3573 case OPERATION_NAME_WRITE_INDIRECT_BUFFER_DRAW_INDEXED:
3574 case OPERATION_NAME_READ_INDIRECT_BUFFER_DRAW_INDEXED:
3575 return resourceDesc.type == RESOURCE_TYPE_INDIRECT_BUFFER_DRAW_INDEXED;
3577 case OPERATION_NAME_WRITE_INDIRECT_BUFFER_DISPATCH:
3578 case OPERATION_NAME_READ_INDIRECT_BUFFER_DISPATCH:
3579 return resourceDesc.type == RESOURCE_TYPE_INDIRECT_BUFFER_DISPATCH;
3581 case OPERATION_NAME_WRITE_UPDATE_BUFFER:
3582 return resourceDesc.type == RESOURCE_TYPE_BUFFER && resourceDesc.size.x() <= MAX_UPDATE_BUFFER_SIZE;
3584 case OPERATION_NAME_WRITE_COPY_IMAGE:
3585 case OPERATION_NAME_WRITE_COPY_BUFFER_TO_IMAGE:
3586 case OPERATION_NAME_READ_COPY_IMAGE:
3587 case OPERATION_NAME_READ_COPY_IMAGE_TO_BUFFER:
3588 return resourceDesc.type == RESOURCE_TYPE_IMAGE;
3590 case OPERATION_NAME_WRITE_CLEAR_ATTACHMENTS:
3591 return resourceDesc.type == RESOURCE_TYPE_IMAGE && resourceDesc.imageType != VK_IMAGE_TYPE_3D;
3593 case OPERATION_NAME_WRITE_BLIT_IMAGE:
3594 case OPERATION_NAME_READ_BLIT_IMAGE:
3595 case OPERATION_NAME_WRITE_IMAGE_VERTEX:
3596 case OPERATION_NAME_WRITE_IMAGE_TESSELLATION_CONTROL:
3597 case OPERATION_NAME_WRITE_IMAGE_TESSELLATION_EVALUATION:
3598 case OPERATION_NAME_WRITE_IMAGE_GEOMETRY:
3599 case OPERATION_NAME_WRITE_IMAGE_FRAGMENT:
3600 case OPERATION_NAME_WRITE_IMAGE_COMPUTE:
3601 case OPERATION_NAME_WRITE_IMAGE_COMPUTE_INDIRECT:
3602 case OPERATION_NAME_READ_IMAGE_VERTEX:
3603 case OPERATION_NAME_READ_IMAGE_TESSELLATION_CONTROL:
3604 case OPERATION_NAME_READ_IMAGE_TESSELLATION_EVALUATION:
3605 case OPERATION_NAME_READ_IMAGE_GEOMETRY:
3606 case OPERATION_NAME_READ_IMAGE_FRAGMENT:
3607 case OPERATION_NAME_READ_IMAGE_COMPUTE:
3608 case OPERATION_NAME_READ_IMAGE_COMPUTE_INDIRECT:
3609 return resourceDesc.type == RESOURCE_TYPE_IMAGE && resourceDesc.imageAspect == VK_IMAGE_ASPECT_COLOR_BIT;
3611 case OPERATION_NAME_READ_UBO_VERTEX:
3612 case OPERATION_NAME_READ_UBO_TESSELLATION_CONTROL:
3613 case OPERATION_NAME_READ_UBO_TESSELLATION_EVALUATION:
3614 case OPERATION_NAME_READ_UBO_GEOMETRY:
3615 case OPERATION_NAME_READ_UBO_FRAGMENT:
3616 case OPERATION_NAME_READ_UBO_COMPUTE:
3617 case OPERATION_NAME_READ_UBO_COMPUTE_INDIRECT:
3618 return resourceDesc.type == RESOURCE_TYPE_BUFFER && resourceDesc.size.x() <= MAX_UBO_RANGE;
3620 case OPERATION_NAME_WRITE_CLEAR_COLOR_IMAGE:
3621 return resourceDesc.type == RESOURCE_TYPE_IMAGE && resourceDesc.imageAspect == VK_IMAGE_ASPECT_COLOR_BIT;
3623 case OPERATION_NAME_WRITE_CLEAR_DEPTH_STENCIL_IMAGE:
3624 return resourceDesc.type == RESOURCE_TYPE_IMAGE && (resourceDesc.imageAspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT));
3626 case OPERATION_NAME_WRITE_DRAW:
3627 case OPERATION_NAME_WRITE_DRAW_INDEXED:
3628 case OPERATION_NAME_WRITE_DRAW_INDIRECT:
3629 case OPERATION_NAME_WRITE_DRAW_INDEXED_INDIRECT:
3630 return resourceDesc.type == RESOURCE_TYPE_IMAGE && resourceDesc.imageType == VK_IMAGE_TYPE_2D
3631 && (resourceDesc.imageAspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) == 0;
3639 std::string getOperationName (const OperationName opName)
3643 case OPERATION_NAME_WRITE_FILL_BUFFER: return "write_fill_buffer";
3644 case OPERATION_NAME_WRITE_UPDATE_BUFFER: return "write_update_buffer";
3645 case OPERATION_NAME_WRITE_COPY_BUFFER: return "write_copy_buffer";
3646 case OPERATION_NAME_WRITE_COPY_BUFFER_TO_IMAGE: return "write_copy_buffer_to_image";
3647 case OPERATION_NAME_WRITE_COPY_IMAGE_TO_BUFFER: return "write_copy_image_to_buffer";
3648 case OPERATION_NAME_WRITE_COPY_IMAGE: return "write_copy_image";
3649 case OPERATION_NAME_WRITE_BLIT_IMAGE: return "write_blit_image";
3650 case OPERATION_NAME_WRITE_SSBO_VERTEX: return "write_ssbo_vertex";
3651 case OPERATION_NAME_WRITE_SSBO_TESSELLATION_CONTROL: return "write_ssbo_tess_control";
3652 case OPERATION_NAME_WRITE_SSBO_TESSELLATION_EVALUATION: return "write_ssbo_tess_eval";
3653 case OPERATION_NAME_WRITE_SSBO_GEOMETRY: return "write_ssbo_geometry";
3654 case OPERATION_NAME_WRITE_SSBO_FRAGMENT: return "write_ssbo_fragment";
3655 case OPERATION_NAME_WRITE_SSBO_COMPUTE: return "write_ssbo_compute";
3656 case OPERATION_NAME_WRITE_SSBO_COMPUTE_INDIRECT: return "write_ssbo_compute_indirect";
3657 case OPERATION_NAME_WRITE_IMAGE_VERTEX: return "write_image_vertex";
3658 case OPERATION_NAME_WRITE_IMAGE_TESSELLATION_CONTROL: return "write_image_tess_control";
3659 case OPERATION_NAME_WRITE_IMAGE_TESSELLATION_EVALUATION: return "write_image_tess_eval";
3660 case OPERATION_NAME_WRITE_IMAGE_GEOMETRY: return "write_image_geometry";
3661 case OPERATION_NAME_WRITE_IMAGE_FRAGMENT: return "write_image_fragment";
3662 case OPERATION_NAME_WRITE_IMAGE_COMPUTE: return "write_image_compute";
3663 case OPERATION_NAME_WRITE_IMAGE_COMPUTE_INDIRECT: return "write_image_compute_indirect";
3664 case OPERATION_NAME_WRITE_CLEAR_COLOR_IMAGE: return "write_clear_color_image";
3665 case OPERATION_NAME_WRITE_CLEAR_DEPTH_STENCIL_IMAGE: return "write_clear_depth_stencil_image";
3666 case OPERATION_NAME_WRITE_DRAW: return "write_draw";
3667 case OPERATION_NAME_WRITE_DRAW_INDEXED: return "write_draw_indexed";
3668 case OPERATION_NAME_WRITE_DRAW_INDIRECT: return "write_draw_indirect";
3669 case OPERATION_NAME_WRITE_DRAW_INDEXED_INDIRECT: return "write_draw_indexed_indirect";
3670 case OPERATION_NAME_WRITE_CLEAR_ATTACHMENTS: return "write_clear_attachments";
3671 case OPERATION_NAME_WRITE_INDIRECT_BUFFER_DRAW: return "write_indirect_buffer_draw";
3672 case OPERATION_NAME_WRITE_INDIRECT_BUFFER_DRAW_INDEXED: return "write_indirect_buffer_draw_indexed";
3673 case OPERATION_NAME_WRITE_INDIRECT_BUFFER_DISPATCH: return "write_indirect_buffer_dispatch";
3675 case OPERATION_NAME_READ_COPY_BUFFER: return "read_copy_buffer";
3676 case OPERATION_NAME_READ_COPY_BUFFER_TO_IMAGE: return "read_copy_buffer_to_image";
3677 case OPERATION_NAME_READ_COPY_IMAGE_TO_BUFFER: return "read_copy_image_to_buffer";
3678 case OPERATION_NAME_READ_COPY_IMAGE: return "read_copy_image";
3679 case OPERATION_NAME_READ_BLIT_IMAGE: return "read_blit_image";
3680 case OPERATION_NAME_READ_UBO_VERTEX: return "read_ubo_vertex";
3681 case OPERATION_NAME_READ_UBO_TESSELLATION_CONTROL: return "read_ubo_tess_control";
3682 case OPERATION_NAME_READ_UBO_TESSELLATION_EVALUATION: return "read_ubo_tess_eval";
3683 case OPERATION_NAME_READ_UBO_GEOMETRY: return "read_ubo_geometry";
3684 case OPERATION_NAME_READ_UBO_FRAGMENT: return "read_ubo_fragment";
3685 case OPERATION_NAME_READ_UBO_COMPUTE: return "read_ubo_compute";
3686 case OPERATION_NAME_READ_UBO_COMPUTE_INDIRECT: return "read_ubo_compute_indirect";
3687 case OPERATION_NAME_READ_SSBO_VERTEX: return "read_ssbo_vertex";
3688 case OPERATION_NAME_READ_SSBO_TESSELLATION_CONTROL: return "read_ssbo_tess_control";
3689 case OPERATION_NAME_READ_SSBO_TESSELLATION_EVALUATION: return "read_ssbo_tess_eval";
3690 case OPERATION_NAME_READ_SSBO_GEOMETRY: return "read_ssbo_geometry";
3691 case OPERATION_NAME_READ_SSBO_FRAGMENT: return "read_ssbo_fragment";
3692 case OPERATION_NAME_READ_SSBO_COMPUTE: return "read_ssbo_compute";
3693 case OPERATION_NAME_READ_SSBO_COMPUTE_INDIRECT: return "read_ssbo_compute_indirect";
3694 case OPERATION_NAME_READ_IMAGE_VERTEX: return "read_image_vertex";
3695 case OPERATION_NAME_READ_IMAGE_TESSELLATION_CONTROL: return "read_image_tess_control";
3696 case OPERATION_NAME_READ_IMAGE_TESSELLATION_EVALUATION: return "read_image_tess_eval";
3697 case OPERATION_NAME_READ_IMAGE_GEOMETRY: return "read_image_geometry";
3698 case OPERATION_NAME_READ_IMAGE_FRAGMENT: return "read_image_fragment";
3699 case OPERATION_NAME_READ_IMAGE_COMPUTE: return "read_image_compute";
3700 case OPERATION_NAME_READ_IMAGE_COMPUTE_INDIRECT: return "read_image_compute_indirect";
3701 case OPERATION_NAME_READ_INDIRECT_BUFFER_DRAW: return "read_indirect_buffer_draw";
3702 case OPERATION_NAME_READ_INDIRECT_BUFFER_DRAW_INDEXED: return "read_indirect_buffer_draw_indexed";
3703 case OPERATION_NAME_READ_INDIRECT_BUFFER_DISPATCH: return "read_indirect_buffer_dispatch";
3704 case OPERATION_NAME_READ_VERTEX_INPUT: return "read_vertex_input";
3712 de::MovePtr<OperationSupport> makeOperationSupport (const OperationName opName, const ResourceDescription& resourceDesc)
3716 case OPERATION_NAME_WRITE_FILL_BUFFER: return de::MovePtr<OperationSupport>(new FillUpdateBuffer ::Support (resourceDesc, FillUpdateBuffer::BUFFER_OP_FILL));
3717 case OPERATION_NAME_WRITE_UPDATE_BUFFER: return de::MovePtr<OperationSupport>(new FillUpdateBuffer ::Support (resourceDesc, FillUpdateBuffer::BUFFER_OP_UPDATE));
3718 case OPERATION_NAME_WRITE_COPY_BUFFER: return de::MovePtr<OperationSupport>(new CopyBuffer ::Support (resourceDesc, ACCESS_MODE_WRITE));
3719 case OPERATION_NAME_WRITE_COPY_BUFFER_TO_IMAGE: return de::MovePtr<OperationSupport>(new CopyBufferToImage ::Support (resourceDesc, ACCESS_MODE_WRITE));
3720 case OPERATION_NAME_WRITE_COPY_IMAGE_TO_BUFFER: return de::MovePtr<OperationSupport>(new CopyImageToBuffer ::Support (resourceDesc, ACCESS_MODE_WRITE));
3721 case OPERATION_NAME_WRITE_COPY_IMAGE: return de::MovePtr<OperationSupport>(new CopyBlitImage ::Support (resourceDesc, CopyBlitImage::TYPE_COPY, ACCESS_MODE_WRITE));
3722 case OPERATION_NAME_WRITE_BLIT_IMAGE: return de::MovePtr<OperationSupport>(new CopyBlitImage ::Support (resourceDesc, CopyBlitImage::TYPE_BLIT, ACCESS_MODE_WRITE));
3723 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));
3724 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));
3725 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));
3726 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));
3727 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));
3728 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));
3729 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));
3730 case OPERATION_NAME_WRITE_IMAGE_VERTEX: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_WRITE, VK_SHADER_STAGE_VERTEX_BIT));
3731 case OPERATION_NAME_WRITE_IMAGE_TESSELLATION_CONTROL: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_WRITE, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT));
3732 case OPERATION_NAME_WRITE_IMAGE_TESSELLATION_EVALUATION: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_WRITE, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT));
3733 case OPERATION_NAME_WRITE_IMAGE_GEOMETRY: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_WRITE, VK_SHADER_STAGE_GEOMETRY_BIT));
3734 case OPERATION_NAME_WRITE_IMAGE_FRAGMENT: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_WRITE, VK_SHADER_STAGE_FRAGMENT_BIT));
3735 case OPERATION_NAME_WRITE_IMAGE_COMPUTE: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_WRITE, VK_SHADER_STAGE_COMPUTE_BIT));
3736 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));
3737 case OPERATION_NAME_WRITE_CLEAR_COLOR_IMAGE: return de::MovePtr<OperationSupport>(new ClearImage ::Support (resourceDesc, ClearImage::CLEAR_MODE_COLOR));
3738 case OPERATION_NAME_WRITE_CLEAR_DEPTH_STENCIL_IMAGE: return de::MovePtr<OperationSupport>(new ClearImage ::Support (resourceDesc, ClearImage::CLEAR_MODE_DEPTH_STENCIL));
3739 case OPERATION_NAME_WRITE_DRAW: return de::MovePtr<OperationSupport>(new Draw ::Support (resourceDesc, Draw::DRAW_CALL_DRAW));
3740 case OPERATION_NAME_WRITE_DRAW_INDEXED: return de::MovePtr<OperationSupport>(new Draw ::Support (resourceDesc, Draw::DRAW_CALL_DRAW_INDEXED));
3741 case OPERATION_NAME_WRITE_DRAW_INDIRECT: return de::MovePtr<OperationSupport>(new Draw ::Support (resourceDesc, Draw::DRAW_CALL_DRAW_INDIRECT));
3742 case OPERATION_NAME_WRITE_DRAW_INDEXED_INDIRECT: return de::MovePtr<OperationSupport>(new Draw ::Support (resourceDesc, Draw::DRAW_CALL_DRAW_INDEXED_INDIRECT));
3743 case OPERATION_NAME_WRITE_CLEAR_ATTACHMENTS: return de::MovePtr<OperationSupport>(new ClearAttachments ::Support (resourceDesc));
3744 case OPERATION_NAME_WRITE_INDIRECT_BUFFER_DRAW: return de::MovePtr<OperationSupport>(new IndirectBuffer ::WriteSupport (resourceDesc));
3745 case OPERATION_NAME_WRITE_INDIRECT_BUFFER_DRAW_INDEXED: return de::MovePtr<OperationSupport>(new IndirectBuffer ::WriteSupport (resourceDesc));
3746 case OPERATION_NAME_WRITE_INDIRECT_BUFFER_DISPATCH: return de::MovePtr<OperationSupport>(new IndirectBuffer ::WriteSupport (resourceDesc));
3748 case OPERATION_NAME_READ_COPY_BUFFER: return de::MovePtr<OperationSupport>(new CopyBuffer ::Support (resourceDesc, ACCESS_MODE_READ));
3749 case OPERATION_NAME_READ_COPY_BUFFER_TO_IMAGE: return de::MovePtr<OperationSupport>(new CopyBufferToImage ::Support (resourceDesc, ACCESS_MODE_READ));
3750 case OPERATION_NAME_READ_COPY_IMAGE_TO_BUFFER: return de::MovePtr<OperationSupport>(new CopyImageToBuffer ::Support (resourceDesc, ACCESS_MODE_READ));
3751 case OPERATION_NAME_READ_COPY_IMAGE: return de::MovePtr<OperationSupport>(new CopyBlitImage ::Support (resourceDesc, CopyBlitImage::TYPE_COPY, ACCESS_MODE_READ));
3752 case OPERATION_NAME_READ_BLIT_IMAGE: return de::MovePtr<OperationSupport>(new CopyBlitImage ::Support (resourceDesc, CopyBlitImage::TYPE_BLIT, ACCESS_MODE_READ));
3753 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));
3754 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));
3755 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));
3756 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));
3757 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));
3758 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));
3759 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));
3760 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));
3761 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));
3762 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));
3763 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));
3764 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));
3765 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));
3766 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));
3767 case OPERATION_NAME_READ_IMAGE_VERTEX: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_READ, VK_SHADER_STAGE_VERTEX_BIT));
3768 case OPERATION_NAME_READ_IMAGE_TESSELLATION_CONTROL: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_READ, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT));
3769 case OPERATION_NAME_READ_IMAGE_TESSELLATION_EVALUATION: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_READ, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT));
3770 case OPERATION_NAME_READ_IMAGE_GEOMETRY: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_READ, VK_SHADER_STAGE_GEOMETRY_BIT));
3771 case OPERATION_NAME_READ_IMAGE_FRAGMENT: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_READ, VK_SHADER_STAGE_FRAGMENT_BIT));
3772 case OPERATION_NAME_READ_IMAGE_COMPUTE: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_READ, VK_SHADER_STAGE_COMPUTE_BIT));
3773 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));
3774 case OPERATION_NAME_READ_INDIRECT_BUFFER_DRAW: return de::MovePtr<OperationSupport>(new IndirectBuffer ::ReadSupport (resourceDesc));
3775 case OPERATION_NAME_READ_INDIRECT_BUFFER_DRAW_INDEXED: return de::MovePtr<OperationSupport>(new IndirectBuffer ::ReadSupport (resourceDesc));
3776 case OPERATION_NAME_READ_INDIRECT_BUFFER_DISPATCH: return de::MovePtr<OperationSupport>(new IndirectBuffer ::ReadSupport (resourceDesc));
3777 case OPERATION_NAME_READ_VERTEX_INPUT: return de::MovePtr<OperationSupport>(new VertexInput ::Support (resourceDesc));
3781 return de::MovePtr<OperationSupport>();
3785 } // synchronization