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 "vkBarrierUtil.hpp"
32 #include "vkQueryUtil.hpp"
33 #include "vkTypeUtil.hpp"
34 #include "vkImageUtil.hpp"
35 #include "vkBuilderUtil.hpp"
36 #include "vkCmdUtil.hpp"
37 #include "vkObjUtil.hpp"
38 #include "deUniquePtr.hpp"
39 #include "tcuTestLog.hpp"
40 #include "tcuTextureUtil.hpp"
46 namespace synchronization
54 MAX_IMAGE_DIMENSION_2D = 0x1000u,
55 MAX_UBO_RANGE = 0x4000u,
56 MAX_UPDATE_BUFFER_SIZE = 0x10000u,
73 PIPELINE_TYPE_GRAPHICS,
74 PIPELINE_TYPE_COMPUTE,
77 static const char* const s_perVertexBlock = "gl_PerVertex {\n"
78 " vec4 gl_Position;\n"
81 static const SyncInfo emptySyncInfo =
83 0, // VkPipelineStageFlags stageMask;
84 0, // VkAccessFlags accessMask;
85 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
88 std::string getShaderStageName(VkShaderStageFlagBits stage)
93 DE_FATAL("Unhandled stage!");
95 case VK_SHADER_STAGE_COMPUTE_BIT:
97 case VK_SHADER_STAGE_FRAGMENT_BIT:
99 case VK_SHADER_STAGE_VERTEX_BIT:
101 case VK_SHADER_STAGE_GEOMETRY_BIT:
103 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
104 return "tess_control";
105 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
110 //! A pipeline that can be embedded inside an operation.
114 virtual ~Pipeline (void) {}
115 virtual void recordCommands (OperationContext& context, const VkCommandBuffer cmdBuffer, const VkDescriptorSet descriptorSet) = 0;
118 //! Vertex data that covers the whole viewport with two triangles.
122 VertexGrid (OperationContext& context)
123 : m_vertexFormat (VK_FORMAT_R32G32B32A32_SFLOAT)
124 , m_vertexStride (tcu::getPixelSize(mapVkFormat(m_vertexFormat)))
126 const DeviceInterface& vk = context.getDeviceInterface();
127 const VkDevice device = context.getDevice();
128 Allocator& allocator = context.getAllocator();
132 m_vertexData.push_back(tcu::Vec4( 1.0f, 1.0f, 0.0f, 1.0f));
133 m_vertexData.push_back(tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f));
134 m_vertexData.push_back(tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f));
136 m_vertexData.push_back(tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f));
137 m_vertexData.push_back(tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f));
138 m_vertexData.push_back(tcu::Vec4( 1.0f, 1.0f, 0.0f, 1.0f));
142 const VkDeviceSize vertexDataSizeBytes = m_vertexData.size() * sizeof(m_vertexData[0]);
144 m_vertexBuffer = de::MovePtr<Buffer>(new Buffer(vk, device, allocator, makeBufferCreateInfo(vertexDataSizeBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible));
145 DE_ASSERT(sizeof(m_vertexData[0]) == m_vertexStride);
148 const Allocation& alloc = m_vertexBuffer->getAllocation();
150 deMemcpy(alloc.getHostPtr(), &m_vertexData[0], static_cast<std::size_t>(vertexDataSizeBytes));
151 flushAlloc(vk, device, alloc);
157 const VkDeviceSize indexBufferSizeBytes = sizeof(deUint32) * m_vertexData.size();
158 const deUint32 numIndices = static_cast<deUint32>(m_vertexData.size());
160 m_indexBuffer = de::MovePtr<Buffer>(new Buffer(vk, device, allocator, makeBufferCreateInfo(indexBufferSizeBytes, VK_BUFFER_USAGE_INDEX_BUFFER_BIT), MemoryRequirement::HostVisible));
163 const Allocation& alloc = m_indexBuffer->getAllocation();
164 deUint32* const pData = static_cast<deUint32*>(alloc.getHostPtr());
166 for (deUint32 i = 0; i < numIndices; ++i)
169 flushAlloc(vk, device, alloc);
174 VkFormat getVertexFormat (void) const { return m_vertexFormat; }
175 deUint32 getVertexStride (void) const { return m_vertexStride; }
176 VkIndexType getIndexType (void) const { return VK_INDEX_TYPE_UINT32; }
177 deUint32 getNumVertices (void) const { return static_cast<deUint32>(m_vertexData.size()); }
178 deUint32 getNumIndices (void) const { return getNumVertices(); }
179 VkBuffer getVertexBuffer (void) const { return **m_vertexBuffer; }
180 VkBuffer getIndexBuffer (void) const { return **m_indexBuffer; }
183 const VkFormat m_vertexFormat;
184 const deUint32 m_vertexStride;
185 std::vector<tcu::Vec4> m_vertexData;
186 de::MovePtr<Buffer> m_vertexBuffer;
187 de::MovePtr<Buffer> m_indexBuffer;
190 //! Add flags for all shader stages required to support a particular stage (e.g. fragment requires vertex as well).
191 VkShaderStageFlags getRequiredStages (const VkShaderStageFlagBits stage)
193 VkShaderStageFlags flags = 0;
195 DE_ASSERT(stage == VK_SHADER_STAGE_COMPUTE_BIT || (stage & VK_SHADER_STAGE_COMPUTE_BIT) == 0);
197 if (stage & VK_SHADER_STAGE_ALL_GRAPHICS)
198 flags |= VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
200 if (stage & (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT))
201 flags |= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
203 if (stage & VK_SHADER_STAGE_GEOMETRY_BIT)
204 flags |= VK_SHADER_STAGE_GEOMETRY_BIT;
206 if (stage & VK_SHADER_STAGE_COMPUTE_BIT)
207 flags |= VK_SHADER_STAGE_COMPUTE_BIT;
212 //! Check that SSBO read/write is available and that all shader stages are supported.
213 void requireFeaturesForSSBOAccess (OperationContext& context, const VkShaderStageFlags usedStages)
215 const InstanceInterface& vki = context.getInstanceInterface();
216 const VkPhysicalDevice physDevice = context.getPhysicalDevice();
217 FeatureFlags flags = (FeatureFlags)0;
219 if (usedStages & VK_SHADER_STAGE_FRAGMENT_BIT)
220 flags |= FEATURE_FRAGMENT_STORES_AND_ATOMICS;
222 if (usedStages & (VK_SHADER_STAGE_ALL_GRAPHICS & (~VK_SHADER_STAGE_FRAGMENT_BIT)))
223 flags |= FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS;
225 if (usedStages & VK_SHADER_STAGE_GEOMETRY_BIT)
226 flags |= FEATURE_GEOMETRY_SHADER;
228 if (usedStages & (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT))
229 flags |= FEATURE_TESSELLATION_SHADER;
231 requireFeatures(vki, physDevice, flags);
234 Data getHostBufferData (const OperationContext& context, const Buffer& hostBuffer, const VkDeviceSize size)
236 const DeviceInterface& vk = context.getDeviceInterface();
237 const VkDevice device = context.getDevice();
238 const Allocation& alloc = hostBuffer.getAllocation();
241 static_cast<std::size_t>(size), // std::size_t size;
242 static_cast<deUint8*>(alloc.getHostPtr()), // const deUint8* data;
245 invalidateAlloc(vk, device, alloc);
250 void setHostBufferData (const OperationContext& context, const Buffer& hostBuffer, const Data& data)
252 const DeviceInterface& vk = context.getDeviceInterface();
253 const VkDevice device = context.getDevice();
254 const Allocation& alloc = hostBuffer.getAllocation();
256 deMemcpy(alloc.getHostPtr(), data.data, data.size);
257 flushAlloc(vk, device, alloc);
260 void assertValidShaderStage (const VkShaderStageFlagBits stage)
264 case VK_SHADER_STAGE_VERTEX_BIT:
265 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
266 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
267 case VK_SHADER_STAGE_GEOMETRY_BIT:
268 case VK_SHADER_STAGE_FRAGMENT_BIT:
269 case VK_SHADER_STAGE_COMPUTE_BIT:
274 DE_FATAL("Invalid shader stage");
279 VkPipelineStageFlags pipelineStageFlagsFromShaderStageFlagBits (const VkShaderStageFlagBits shaderStage)
283 case VK_SHADER_STAGE_VERTEX_BIT: return VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT_KHR;
284 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: return VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT_KHR;
285 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: return VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT_KHR;
286 case VK_SHADER_STAGE_GEOMETRY_BIT: return VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT_KHR;
287 case VK_SHADER_STAGE_FRAGMENT_BIT: return VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT_KHR;
288 case VK_SHADER_STAGE_COMPUTE_BIT: return VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT_KHR;
290 // Other usages are probably an error, so flag that.
292 DE_FATAL("Invalid shader stage");
293 return (VkPipelineStageFlags)0;
297 //! Fill destination buffer with a repeating pattern.
298 void fillPattern (void* const pData, const VkDeviceSize size, bool useIndexPattern = false)
300 // There are two pattern options - most operations use primePattern,
301 // indexPattern is only needed for testing vertex index bufffer.
302 static const deUint8 primePattern[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31 };
303 static const deUint32 indexPattern[] = { 0, 1, 2, 3, 4 };
305 const deUint8* pattern = (useIndexPattern ? reinterpret_cast<const deUint8*>(indexPattern)
307 const deUint32 patternSize = static_cast<deUint32>(useIndexPattern
308 ? DE_LENGTH_OF_ARRAY(indexPattern)*sizeof(deUint32)
309 : DE_LENGTH_OF_ARRAY(primePattern));
310 deUint8* const pBytes = static_cast<deUint8*>(pData);
312 for (deUint32 i = 0; i < size; ++i)
313 pBytes[i] = pattern[i % patternSize];
316 //! Get size in bytes of a pixel buffer with given extent.
317 VkDeviceSize getPixelBufferSize (const VkFormat format, const VkExtent3D& extent)
319 const int pixelSize = tcu::getPixelSize(mapVkFormat(format));
320 return (pixelSize * extent.width * extent.height * extent.depth);
323 //! Determine the size of a 2D image that can hold sizeBytes data.
324 VkExtent3D get2DImageExtentWithSize (const VkDeviceSize sizeBytes, const deUint32 pixelSize)
326 const deUint32 size = static_cast<deUint32>(sizeBytes / pixelSize);
328 DE_ASSERT(size <= MAX_IMAGE_DIMENSION_2D * MAX_IMAGE_DIMENSION_2D);
331 std::min(size, static_cast<deUint32>(MAX_IMAGE_DIMENSION_2D)),
332 (size / MAX_IMAGE_DIMENSION_2D) + (size % MAX_IMAGE_DIMENSION_2D != 0 ? 1u : 0u),
336 VkClearValue makeClearValue (const VkFormat format)
338 if (isDepthStencilFormat(format))
339 return makeClearValueDepthStencil(0.4f, 21u);
342 if (isIntFormat(format) || isUintFormat(format))
343 return makeClearValueColorU32(8u, 16u, 24u, 32u);
345 return makeClearValueColorF32(0.25f, 0.49f, 0.75f, 1.0f);
349 void clearPixelBuffer (tcu::PixelBufferAccess& pixels, const VkClearValue& clearValue)
351 const tcu::TextureFormat format = pixels.getFormat();
352 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
354 if (format.order == tcu::TextureFormat::D)
356 for (int z = 0; z < pixels.getDepth(); z++)
357 for (int y = 0; y < pixels.getHeight(); y++)
358 for (int x = 0; x < pixels.getWidth(); x++)
359 pixels.setPixDepth(clearValue.depthStencil.depth, x, y, z);
361 else if (format.order == tcu::TextureFormat::S)
363 for (int z = 0; z < pixels.getDepth(); z++)
364 for (int y = 0; y < pixels.getHeight(); y++)
365 for (int x = 0; x < pixels.getWidth(); x++)
366 pixels.setPixStencil(clearValue.depthStencil.stencil, x, y, z);
368 else if (format.order == tcu::TextureFormat::DS)
370 for (int z = 0; z < pixels.getDepth(); z++)
371 for (int y = 0; y < pixels.getHeight(); y++)
372 for (int x = 0; x < pixels.getWidth(); x++)
374 pixels.setPixDepth(clearValue.depthStencil.depth, x, y, z);
375 pixels.setPixStencil(clearValue.depthStencil.stencil, x, y, z);
378 else if (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
380 const tcu::UVec4 color (clearValue.color.uint32);
382 for (int z = 0; z < pixels.getDepth(); z++)
383 for (int y = 0; y < pixels.getHeight(); y++)
384 for (int x = 0; x < pixels.getWidth(); x++)
385 pixels.setPixel(color, x, y, z);
389 const tcu::Vec4 color (clearValue.color.float32);
391 for (int z = 0; z < pixels.getDepth(); z++)
392 for (int y = 0; y < pixels.getHeight(); y++)
393 for (int x = 0; x < pixels.getWidth(); x++)
394 pixels.setPixel(color, x, y, z);
398 VkImageViewType getImageViewType (const VkImageType imageType)
402 case VK_IMAGE_TYPE_1D: return VK_IMAGE_VIEW_TYPE_1D;
403 case VK_IMAGE_TYPE_2D: return VK_IMAGE_VIEW_TYPE_2D;
404 case VK_IMAGE_TYPE_3D: return VK_IMAGE_VIEW_TYPE_3D;
407 DE_FATAL("Unknown image type");
408 return VK_IMAGE_VIEW_TYPE_LAST;
412 std::string getShaderImageType (const VkFormat format, const VkImageType imageType)
414 const tcu::TextureFormat texFormat = mapVkFormat(format);
415 const std::string formatPart = tcu::getTextureChannelClass(texFormat.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ? "u" :
416 tcu::getTextureChannelClass(texFormat.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ? "i" : "";
419 case VK_IMAGE_TYPE_1D: return formatPart + "image1D";
420 case VK_IMAGE_TYPE_2D: return formatPart + "image2D";
421 case VK_IMAGE_TYPE_3D: return formatPart + "image3D";
424 DE_FATAL("Unknown image type");
429 std::string getShaderImageFormatQualifier (const VkFormat format)
431 const tcu::TextureFormat texFormat = mapVkFormat(format);
432 const char* orderPart = DE_NULL;
433 const char* typePart = DE_NULL;
435 switch (texFormat.order)
437 case tcu::TextureFormat::R: orderPart = "r"; break;
438 case tcu::TextureFormat::RG: orderPart = "rg"; break;
439 case tcu::TextureFormat::RGB: orderPart = "rgb"; break;
440 case tcu::TextureFormat::RGBA: orderPart = "rgba"; break;
443 DE_FATAL("Unksupported texture channel order");
447 switch (texFormat.type)
449 case tcu::TextureFormat::FLOAT: typePart = "32f"; break;
450 case tcu::TextureFormat::HALF_FLOAT: typePart = "16f"; break;
452 case tcu::TextureFormat::UNSIGNED_INT32: typePart = "32ui"; break;
453 case tcu::TextureFormat::UNSIGNED_INT16: typePart = "16ui"; break;
454 case tcu::TextureFormat::UNSIGNED_INT8: typePart = "8ui"; break;
456 case tcu::TextureFormat::SIGNED_INT32: typePart = "32i"; break;
457 case tcu::TextureFormat::SIGNED_INT16: typePart = "16i"; break;
458 case tcu::TextureFormat::SIGNED_INT8: typePart = "8i"; break;
460 case tcu::TextureFormat::UNORM_INT16: typePart = "16"; break;
461 case tcu::TextureFormat::UNORM_INT8: typePart = "8"; break;
463 case tcu::TextureFormat::SNORM_INT16: typePart = "16_snorm"; break;
464 case tcu::TextureFormat::SNORM_INT8: typePart = "8_snorm"; break;
467 DE_FATAL("Unksupported texture channel type");
471 return std::string(orderPart) + typePart;
474 namespace FillUpdateBuffer
481 BUFFER_OP_UPDATE_WITH_INDEX_PATTERN,
484 class Implementation : public Operation
487 Implementation (OperationContext& context, Resource& resource, const BufferOp bufferOp)
488 : m_context (context)
489 , m_resource (resource)
491 , m_bufferOp (bufferOp)
493 DE_ASSERT((m_resource.getBuffer().size % sizeof(deUint32)) == 0);
494 DE_ASSERT(m_bufferOp == BUFFER_OP_FILL || m_resource.getBuffer().size <= MAX_UPDATE_BUFFER_SIZE);
496 m_data.resize(static_cast<size_t>(m_resource.getBuffer().size));
498 if (m_bufferOp == BUFFER_OP_FILL)
500 const std::size_t size = m_data.size() / sizeof(m_fillValue);
501 deUint32* const pData = reinterpret_cast<deUint32*>(&m_data[0]);
503 for (deUint32 i = 0; i < size; ++i)
504 pData[i] = m_fillValue;
506 else if (m_bufferOp == BUFFER_OP_UPDATE)
508 fillPattern(&m_data[0], m_data.size());
510 else if(m_bufferOp == BUFFER_OP_UPDATE_WITH_INDEX_PATTERN)
512 fillPattern(&m_data[0], m_data.size(), true);
516 void recordCommands (const VkCommandBuffer cmdBuffer)
518 const DeviceInterface& vk = m_context.getDeviceInterface();
520 if (m_bufferOp == BUFFER_OP_FILL)
522 vk.cmdFillBuffer(cmdBuffer, m_resource.getBuffer().handle, m_resource.getBuffer().offset, m_resource.getBuffer().size, m_fillValue);
524 SynchronizationWrapperPtr synchronizationWrapper = getSynchronizationWrapper(m_context.getSynchronizationType(), vk, DE_FALSE);
525 const VkBufferMemoryBarrier2KHR bufferMemoryBarrier2 = makeBufferMemoryBarrier2(
526 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags2KHR srcStageMask
527 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR, // VkAccessFlags2KHR srcAccessMask
528 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags2KHR dstStageMask
529 VK_ACCESS_2_TRANSFER_READ_BIT_KHR, // VkAccessFlags2KHR dstAccessMask
530 m_resource.getBuffer().handle, // VkBuffer buffer
531 0u, // VkDeviceSize offset
532 m_resource.getBuffer().size // VkDeviceSize size
534 VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, &bufferMemoryBarrier2);
535 synchronizationWrapper->cmdPipelineBarrier(cmdBuffer, &dependencyInfo);
538 vk.cmdUpdateBuffer(cmdBuffer, m_resource.getBuffer().handle, m_resource.getBuffer().offset, m_resource.getBuffer().size, reinterpret_cast<deUint32*>(&m_data[0]));
541 SyncInfo getInSyncInfo (void) const
543 return emptySyncInfo;
546 SyncInfo getOutSyncInfo (void) const
548 const SyncInfo syncInfo =
550 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags stageMask;
551 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR, // VkAccessFlags accessMask;
552 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
558 Data getData (void) const
562 m_data.size(), // std::size_t size;
563 &m_data[0], // const deUint8* data;
568 void setData (const Data& data)
570 deMemcpy(&m_data[0], data.data, data.size);
574 OperationContext& m_context;
575 Resource& m_resource;
576 std::vector<deUint8> m_data;
577 const deUint32 m_fillValue;
578 const BufferOp m_bufferOp;
581 class Support : public OperationSupport
584 Support (const ResourceDescription& resourceDesc, const BufferOp bufferOp)
585 : m_resourceDesc (resourceDesc)
586 , m_bufferOp (bufferOp)
588 DE_ASSERT(m_bufferOp == BUFFER_OP_FILL || m_bufferOp == BUFFER_OP_UPDATE || m_bufferOp == BUFFER_OP_UPDATE_WITH_INDEX_PATTERN);
589 DE_ASSERT(m_resourceDesc.type == RESOURCE_TYPE_BUFFER || m_resourceDesc.type == RESOURCE_TYPE_INDEX_BUFFER);
592 deUint32 getInResourceUsageFlags (void) const
597 deUint32 getOutResourceUsageFlags (void) const
599 return VK_BUFFER_USAGE_TRANSFER_DST_BIT;
602 VkQueueFlags getQueueFlags (const OperationContext& context) const
604 if (m_bufferOp == BUFFER_OP_FILL && !context.isDeviceFunctionalitySupported("VK_KHR_maintenance1"))
606 return VK_QUEUE_COMPUTE_BIT | VK_QUEUE_GRAPHICS_BIT;
609 return VK_QUEUE_TRANSFER_BIT;
612 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
614 return de::MovePtr<Operation>(new Implementation(context, resource, m_bufferOp));
617 de::MovePtr<Operation> build (OperationContext&, Resource&, Resource&) const
620 return de::MovePtr<Operation>();
624 const ResourceDescription m_resourceDesc;
625 const BufferOp m_bufferOp;
628 } // FillUpdateBuffer ns
633 class Implementation : public Operation
636 Implementation (OperationContext& context, Resource& resource, const AccessMode mode)
637 : m_context (context)
638 , m_resource (resource)
641 const DeviceInterface& vk = m_context.getDeviceInterface();
642 const VkDevice device = m_context.getDevice();
643 Allocator& allocator = m_context.getAllocator();
644 const VkBufferUsageFlags hostBufferUsage = (m_mode == ACCESS_MODE_READ ? VK_BUFFER_USAGE_TRANSFER_DST_BIT : VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
646 m_hostBuffer = de::MovePtr<Buffer>(new Buffer(vk, device, allocator, makeBufferCreateInfo(m_resource.getBuffer().size, hostBufferUsage), MemoryRequirement::HostVisible));
648 const Allocation& alloc = m_hostBuffer->getAllocation();
650 if (m_mode == ACCESS_MODE_READ)
651 deMemset(alloc.getHostPtr(), 0, static_cast<size_t>(m_resource.getBuffer().size));
653 fillPattern(alloc.getHostPtr(), m_resource.getBuffer().size);
655 flushAlloc(vk, device, alloc);
658 void recordCommands (const VkCommandBuffer cmdBuffer)
660 const DeviceInterface& vk = m_context.getDeviceInterface();
661 const VkBufferCopy copyRegion = makeBufferCopy(0u, 0u, m_resource.getBuffer().size);
662 SynchronizationWrapperPtr synchronizationWrapper = getSynchronizationWrapper(m_context.getSynchronizationType(), vk, DE_FALSE);
664 if (m_mode == ACCESS_MODE_READ)
666 vk.cmdCopyBuffer(cmdBuffer, m_resource.getBuffer().handle, **m_hostBuffer, 1u, ©Region);
668 // Insert a barrier so copied data is available to the host
669 const VkBufferMemoryBarrier2KHR bufferMemoryBarrier2 = makeBufferMemoryBarrier2(
670 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags2KHR srcStageMask
671 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR, // VkAccessFlags2KHR srcAccessMask
672 VK_PIPELINE_STAGE_2_HOST_BIT_KHR, // VkPipelineStageFlags2KHR dstStageMask
673 VK_ACCESS_2_HOST_READ_BIT_KHR, // VkAccessFlags2KHR dstAccessMask
674 **m_hostBuffer, // VkBuffer buffer
675 0u, // VkDeviceSize offset
676 m_resource.getBuffer().size // VkDeviceSize size
678 VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, &bufferMemoryBarrier2);
679 synchronizationWrapper->cmdPipelineBarrier(cmdBuffer, &dependencyInfo);
683 // Insert a barrier so buffer data is available to the device
684 //const VkBufferMemoryBarrier2KHR bufferMemoryBarrier2 = makeBufferMemoryBarrier2(
685 // VK_PIPELINE_STAGE_2_HOST_BIT_KHR, // VkPipelineStageFlags2KHR srcStageMask
686 // VK_ACCESS_2_HOST_WRITE_BIT_KHR, // VkAccessFlags2KHR srcAccessMask
687 // VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags2KHR dstStageMask
688 // VK_ACCESS_2_TRANSFER_READ_BIT_KHR, // VkAccessFlags2KHR dstAccessMask
689 // **m_hostBuffer, // VkBuffer buffer
690 // 0u, // VkDeviceSize offset
691 // m_resource.getBuffer().size // VkDeviceSize size
693 //VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, &bufferMemoryBarrier2);
694 //synchronizationWrapper->cmdPipelineBarrier(cmdBuffer, &dependencyInfo);
696 vk.cmdCopyBuffer(cmdBuffer, **m_hostBuffer, m_resource.getBuffer().handle, 1u, ©Region);
700 SyncInfo getInSyncInfo (void) const
702 const VkAccessFlags access = (m_mode == ACCESS_MODE_READ ? VK_ACCESS_2_TRANSFER_READ_BIT_KHR : 0);
703 const SyncInfo syncInfo =
705 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags stageMask;
706 access, // VkAccessFlags accessMask;
707 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
712 SyncInfo getOutSyncInfo (void) const
714 const VkAccessFlags access = (m_mode == ACCESS_MODE_WRITE ? VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR : 0);
715 const SyncInfo syncInfo =
717 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags stageMask;
718 access, // VkAccessFlags accessMask;
719 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
724 Data getData (void) const
726 return getHostBufferData(m_context, *m_hostBuffer, m_resource.getBuffer().size);
729 void setData (const Data& data)
731 DE_ASSERT(m_mode == ACCESS_MODE_WRITE);
732 setHostBufferData(m_context, *m_hostBuffer, data);
736 OperationContext& m_context;
737 Resource& m_resource;
738 const AccessMode m_mode;
739 de::MovePtr<Buffer> m_hostBuffer;
742 class Support : public OperationSupport
745 Support (const ResourceDescription& resourceDesc, const AccessMode mode)
748 DE_ASSERT(resourceDesc.type == RESOURCE_TYPE_BUFFER);
749 DE_UNREF(resourceDesc);
752 deUint32 getInResourceUsageFlags (void) const
754 return m_mode == ACCESS_MODE_READ ? VK_BUFFER_USAGE_TRANSFER_SRC_BIT : 0;
757 deUint32 getOutResourceUsageFlags (void) const
759 return m_mode == ACCESS_MODE_WRITE ? VK_BUFFER_USAGE_TRANSFER_DST_BIT : 0;
762 VkQueueFlags getQueueFlags (const OperationContext& context) const
765 return VK_QUEUE_TRANSFER_BIT;
768 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
770 return de::MovePtr<Operation>(new Implementation(context, resource, m_mode));
773 de::MovePtr<Operation> build (OperationContext&, Resource&, Resource&) const
776 return de::MovePtr<Operation>();
780 const AccessMode m_mode;
783 class CopyImplementation : public Operation
786 CopyImplementation (OperationContext& context, Resource& inResource, Resource& outResource)
787 : m_context (context)
788 , m_inResource (inResource)
789 , m_outResource (outResource)
793 void recordCommands (const VkCommandBuffer cmdBuffer)
795 const DeviceInterface& vk = m_context.getDeviceInterface();
796 const VkBufferCopy copyRegion = makeBufferCopy(0u, 0u, m_inResource.getBuffer().size);
798 vk.cmdCopyBuffer(cmdBuffer, m_inResource.getBuffer().handle, m_outResource.getBuffer().handle, 1u, ©Region);
801 SyncInfo getInSyncInfo (void) const
803 const SyncInfo syncInfo =
805 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags stageMask;
806 VK_ACCESS_2_TRANSFER_READ_BIT_KHR, // VkAccessFlags accessMask;
807 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
812 SyncInfo getOutSyncInfo (void) const
814 const SyncInfo syncInfo =
816 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags stageMask;
817 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR, // VkAccessFlags accessMask;
818 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
823 Data getData (void) const
825 Data data = { 0, DE_NULL };
829 void setData (const Data&)
835 OperationContext& m_context;
836 Resource& m_inResource;
837 Resource& m_outResource;
838 de::MovePtr<Buffer> m_hostBuffer;
841 class CopySupport : public OperationSupport
844 CopySupport (const ResourceDescription& resourceDesc)
846 DE_ASSERT(resourceDesc.type == RESOURCE_TYPE_BUFFER);
847 DE_UNREF(resourceDesc);
850 deUint32 getInResourceUsageFlags (void) const
852 return VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
855 deUint32 getOutResourceUsageFlags (void) const
857 return VK_BUFFER_USAGE_TRANSFER_DST_BIT;
860 VkQueueFlags getQueueFlags (const OperationContext& context) const
863 return VK_QUEUE_TRANSFER_BIT;
866 de::MovePtr<Operation> build (OperationContext&, Resource&) const
869 return de::MovePtr<Operation>();
872 de::MovePtr<Operation> build (OperationContext& context, Resource& inResource, Resource& outResource) const
874 return de::MovePtr<Operation>(new CopyImplementation(context, inResource, outResource));
880 namespace CopyBlitResolveImage
883 class ImplementationBase : public Operation
886 //! Copy/Blit/Resolve etc. operation
887 virtual void recordCopyCommand (const VkCommandBuffer cmdBuffer) = 0;
889 //! Get source stage mask that is used during read - added to test synchronization2 new stage masks
890 virtual VkPipelineStageFlags2KHR getReadSrcStageMask() const = 0;
892 ImplementationBase (OperationContext& context, Resource& resource, const AccessMode mode)
893 : m_context (context)
894 , m_resource (resource)
896 , m_bufferSize (getPixelBufferSize(m_resource.getImage().format, m_resource.getImage().extent))
898 const DeviceInterface& vk = m_context.getDeviceInterface();
899 const VkDevice device = m_context.getDevice();
900 Allocator& allocator = m_context.getAllocator();
902 m_hostBuffer = de::MovePtr<Buffer>(new Buffer(
903 vk, device, allocator, makeBufferCreateInfo(m_bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT),
904 MemoryRequirement::HostVisible));
906 const Allocation& alloc = m_hostBuffer->getAllocation();
907 if (m_mode == ACCESS_MODE_READ)
908 deMemset(alloc.getHostPtr(), 0, static_cast<size_t>(m_bufferSize));
910 fillPattern(alloc.getHostPtr(), m_bufferSize);
911 flushAlloc(vk, device, alloc);
914 const auto& imgResource = m_resource.getImage();
915 m_image = de::MovePtr<Image>(new Image(
916 vk, device, allocator,
917 makeImageCreateInfo(imgResource.imageType, imgResource.extent, imgResource.format,
918 (VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT), VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL),
919 MemoryRequirement::Any));
922 void recordCommands (const VkCommandBuffer cmdBuffer)
924 const DeviceInterface& vk = m_context.getDeviceInterface();
925 const VkBufferImageCopy bufferCopyRegion = makeBufferImageCopy(m_resource.getImage().extent, m_resource.getImage().subresourceLayers);
926 SynchronizationWrapperPtr synchronizationWrapper = getSynchronizationWrapper(m_context.getSynchronizationType(), vk, DE_FALSE);
928 // Staging image layout
930 const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
931 VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR, // VkPipelineStageFlags2KHR srcStageMask
932 (VkAccessFlags)0, // VkAccessFlags2KHR srcAccessMask
933 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags2KHR dstStageMask
934 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR, // VkAccessFlags2KHR dstAccessMask
935 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
936 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout
937 **m_image, // VkImage image
938 m_resource.getImage().subresourceRange // VkImageSubresourceRange subresourceRange
940 VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
941 synchronizationWrapper->cmdPipelineBarrier(cmdBuffer, &dependencyInfo);
944 if (m_mode == ACCESS_MODE_READ)
946 // Resource Image -> Staging image
947 recordCopyCommand(cmdBuffer);
949 // Staging image layout
950 const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
951 getReadSrcStageMask(), // VkPipelineStageFlags2KHR srcStageMask
952 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR, // VkAccessFlags2KHR srcAccessMask
953 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags2KHR dstStageMask
954 VK_ACCESS_2_TRANSFER_READ_BIT_KHR, // VkAccessFlags2KHR dstAccessMask
955 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout
956 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout
957 **m_image, // VkImage image
958 m_resource.getImage().subresourceRange // VkImageSubresourceRange subresourceRange
960 VkDependencyInfoKHR imageDependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
961 synchronizationWrapper->cmdPipelineBarrier(cmdBuffer, &imageDependencyInfo);
963 // Image -> Host buffer
964 vk.cmdCopyImageToBuffer(cmdBuffer, **m_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_hostBuffer, 1u, &bufferCopyRegion);
966 // Insert a barrier so copied data is available to the host
967 const VkBufferMemoryBarrier2KHR bufferMemoryBarrier2 = makeBufferMemoryBarrier2(
968 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags2KHR srcStageMask
969 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR, // VkAccessFlags2KHR srcAccessMask
970 VK_PIPELINE_STAGE_2_HOST_BIT_KHR, // VkPipelineStageFlags2KHR dstStageMask
971 VK_ACCESS_2_HOST_READ_BIT_KHR, // VkAccessFlags2KHR dstAccessMask
972 **m_hostBuffer, // VkBuffer buffer
973 0u, // VkDeviceSize offset
974 m_bufferSize // VkDeviceSize size
976 VkDependencyInfoKHR bufferDependencyInfo = makeCommonDependencyInfo(DE_NULL, &bufferMemoryBarrier2);
977 synchronizationWrapper->cmdPipelineBarrier(cmdBuffer, &bufferDependencyInfo);
981 // Host buffer -> Staging image
982 vk.cmdCopyBufferToImage(cmdBuffer, **m_hostBuffer, **m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &bufferCopyRegion);
984 // Staging image layout
986 const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
987 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags2KHR srcStageMask
988 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR, // VkAccessFlags2KHR srcAccessMask
989 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags2KHR dstStageMask
990 VK_ACCESS_2_TRANSFER_READ_BIT_KHR, // VkAccessFlags2KHR dstAccessMask
991 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout
992 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout
993 **m_image, // VkImage image
994 m_resource.getImage().subresourceRange // VkImageSubresourceRange subresourceRange
996 VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
997 synchronizationWrapper->cmdPipelineBarrier(cmdBuffer, &dependencyInfo);
1000 // Resource image layout
1002 const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
1003 VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR, // VkPipelineStageFlags2KHR srcStageMask
1004 (VkAccessFlags2KHR)0, // VkAccessFlags2KHR srcAccessMask
1005 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags2KHR dstStageMask
1006 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR, // VkAccessFlags2KHR dstAccessMask
1007 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
1008 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout
1009 m_resource.getImage().handle, // VkImage image
1010 m_resource.getImage().subresourceRange // VkImageSubresourceRange subresourceRange
1012 VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
1013 synchronizationWrapper->cmdPipelineBarrier(cmdBuffer, &dependencyInfo);
1016 // Staging image -> Resource Image
1017 recordCopyCommand(cmdBuffer);
1021 SyncInfo getInSyncInfo (void) const
1023 const VkAccessFlags2KHR access = (m_mode == ACCESS_MODE_READ ? VK_ACCESS_2_TRANSFER_READ_BIT_KHR : VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR);
1024 const VkImageLayout layout = (m_mode == ACCESS_MODE_READ ? VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL : VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
1025 const SyncInfo syncInfo =
1027 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags stageMask;
1028 access, // VkAccessFlags accessMask;
1029 layout, // VkImageLayout imageLayout;
1034 SyncInfo getOutSyncInfo (void) const
1036 const VkAccessFlags2KHR access = (m_mode == ACCESS_MODE_READ ? VK_ACCESS_2_TRANSFER_READ_BIT_KHR : VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR);
1037 const VkImageLayout layout = (m_mode == ACCESS_MODE_READ ? VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL : VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
1038 const SyncInfo syncInfo =
1040 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags stageMask;
1041 access, // VkAccessFlags accessMask;
1042 layout, // VkImageLayout imageLayout;
1047 Data getData (void) const
1049 return getHostBufferData(m_context, *m_hostBuffer, m_bufferSize);
1052 void setData (const Data& data)
1054 DE_ASSERT(m_mode == ACCESS_MODE_WRITE);
1055 setHostBufferData(m_context, *m_hostBuffer, data);
1059 OperationContext& m_context;
1060 Resource& m_resource;
1061 const AccessMode m_mode;
1062 const VkDeviceSize m_bufferSize;
1063 de::MovePtr<Buffer> m_hostBuffer;
1064 de::MovePtr<Image> m_image;
1067 VkOffset3D makeExtentOffset (const Resource& resource)
1069 DE_ASSERT(resource.getType() == RESOURCE_TYPE_IMAGE);
1070 const VkExtent3D extent = resource.getImage().extent;
1072 switch (resource.getImage().imageType)
1074 case VK_IMAGE_TYPE_1D: return makeOffset3D(extent.width, 1, 1);
1075 case VK_IMAGE_TYPE_2D: return makeOffset3D(extent.width, extent.height, 1);
1076 case VK_IMAGE_TYPE_3D: return makeOffset3D(extent.width, extent.height, extent.depth);
1079 return VkOffset3D();
1083 VkImageBlit makeBlitRegion (const Resource& resource)
1085 const VkImageBlit blitRegion =
1087 resource.getImage().subresourceLayers, // VkImageSubresourceLayers srcSubresource;
1088 { makeOffset3D(0, 0, 0), makeExtentOffset(resource) }, // VkOffset3D srcOffsets[2];
1089 resource.getImage().subresourceLayers, // VkImageSubresourceLayers dstSubresource;
1090 { makeOffset3D(0, 0, 0), makeExtentOffset(resource) }, // VkOffset3D dstOffsets[2];
1095 class BlitImplementation : public ImplementationBase
1098 BlitImplementation (OperationContext& context, Resource& resource, const AccessMode mode)
1099 : ImplementationBase (context, resource, mode)
1100 , m_blitRegion (makeBlitRegion(m_resource))
1102 const InstanceInterface& vki = m_context.getInstanceInterface();
1103 const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
1104 const auto& imgResource = m_resource.getImage();
1105 const VkFormatProperties formatProps = getPhysicalDeviceFormatProperties(vki, physDevice, imgResource.format);
1106 const auto& features = ((imgResource.tiling == VK_IMAGE_TILING_LINEAR) ? formatProps.linearTilingFeatures : formatProps.optimalTilingFeatures);
1107 const VkFormatFeatureFlags requiredFlags = (VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT);
1109 // SRC and DST blit is required because both images are using the same format.
1110 if ((features & requiredFlags) != requiredFlags)
1111 TCU_THROW(NotSupportedError, "Format doesn't support blits");
1114 void recordCopyCommand (const VkCommandBuffer cmdBuffer)
1116 const DeviceInterface& vk = m_context.getDeviceInterface();
1118 if (m_mode == ACCESS_MODE_READ)
1120 // Resource Image -> Staging image
1121 vk.cmdBlitImage(cmdBuffer, m_resource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1122 1u, &m_blitRegion, VK_FILTER_NEAREST);
1126 // Staging image -> Resource Image
1127 vk.cmdBlitImage(cmdBuffer, **m_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_resource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1128 1u, &m_blitRegion, VK_FILTER_NEAREST);
1132 VkPipelineStageFlags2KHR getReadSrcStageMask() const
1134 return (m_context.getSynchronizationType() == SynchronizationType::LEGACY) ? VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR : VK_PIPELINE_STAGE_2_BLIT_BIT_KHR;
1139 const VkImageBlit m_blitRegion;
1142 template <typename ImageCopyOrResolve>
1143 ImageCopyOrResolve makeImageRegion (const Resource& resource)
1147 resource.getImage().subresourceLayers, // VkImageSubresourceLayers srcSubresource;
1148 makeOffset3D(0, 0, 0), // VkOffset3D srcOffset;
1149 resource.getImage().subresourceLayers, // VkImageSubresourceLayers dstSubresource;
1150 makeOffset3D(0, 0, 0), // VkOffset3D dstOffset;
1151 resource.getImage().extent, // VkExtent3D extent;
1155 class CopyImplementation : public ImplementationBase
1158 CopyImplementation (OperationContext& context, Resource& resource, const AccessMode mode)
1159 : ImplementationBase (context, resource, mode)
1160 , m_imageCopyRegion (makeImageRegion<VkImageCopy>(m_resource))
1164 void recordCopyCommand (const VkCommandBuffer cmdBuffer)
1166 const DeviceInterface& vk = m_context.getDeviceInterface();
1168 if (m_mode == ACCESS_MODE_READ)
1170 // Resource Image -> Staging image
1171 vk.cmdCopyImage(cmdBuffer, m_resource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &m_imageCopyRegion);
1175 // Staging image -> Resource Image
1176 vk.cmdCopyImage(cmdBuffer, **m_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_resource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &m_imageCopyRegion);
1180 VkPipelineStageFlags2KHR getReadSrcStageMask() const
1182 return (m_context.getSynchronizationType() == SynchronizationType::LEGACY) ? VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR : VK_PIPELINE_STAGE_2_COPY_BIT_KHR;
1186 const VkImageCopy m_imageCopyRegion;
1189 class ResolveImplementation : public ImplementationBase
1192 ResolveImplementation(OperationContext& context, Resource& resource, const AccessMode mode)
1193 : ImplementationBase (context, resource, mode)
1194 , m_imageResolveRegion (makeImageRegion<VkImageResolve>(resource))
1196 DE_ASSERT(m_mode == ACCESS_MODE_READ);
1199 void recordCopyCommand(const VkCommandBuffer cmdBuffer)
1201 const DeviceInterface& vk = m_context.getDeviceInterface();
1203 // Resource Image -> Staging image
1204 vk.cmdResolveImage(cmdBuffer, m_resource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &m_imageResolveRegion);
1207 VkPipelineStageFlags2KHR getReadSrcStageMask() const
1209 return (m_context.getSynchronizationType() == SynchronizationType::LEGACY) ? VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR : VK_PIPELINE_STAGE_2_RESOLVE_BIT_KHR;
1213 VkImageResolve m_imageResolveRegion;
1223 class Support : public OperationSupport
1226 Support (const ResourceDescription& resourceDesc, const Type type, const AccessMode mode)
1230 DE_ASSERT(resourceDesc.type == RESOURCE_TYPE_IMAGE);
1232 const bool isDepthStencil = isDepthStencilFormat(resourceDesc.imageFormat);
1233 m_requiredQueueFlags = (isDepthStencil || m_type != TYPE_COPY ? VK_QUEUE_GRAPHICS_BIT : VK_QUEUE_TRANSFER_BIT);
1235 // Don't blit depth/stencil images.
1236 DE_ASSERT(m_type != TYPE_BLIT || !isDepthStencil);
1239 deUint32 getInResourceUsageFlags (void) const
1241 return (m_mode == ACCESS_MODE_READ ? VK_IMAGE_USAGE_TRANSFER_SRC_BIT : 0);
1244 deUint32 getOutResourceUsageFlags (void) const
1246 return (m_mode == ACCESS_MODE_WRITE ? VK_IMAGE_USAGE_TRANSFER_DST_BIT : 0);
1249 VkQueueFlags getQueueFlags (const OperationContext& context) const
1252 return m_requiredQueueFlags;
1255 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
1257 if (m_type == TYPE_COPY)
1258 return de::MovePtr<Operation>(new CopyImplementation(context, resource, m_mode));
1259 else if (m_type == TYPE_BLIT)
1260 return de::MovePtr<Operation>(new BlitImplementation(context, resource, m_mode));
1262 return de::MovePtr<Operation>(new ResolveImplementation(context, resource, m_mode));
1265 de::MovePtr<Operation> build (OperationContext&, Resource&, Resource&) const
1268 return de::MovePtr<Operation>();
1273 const AccessMode m_mode;
1274 VkQueueFlags m_requiredQueueFlags;
1277 class BlitCopyImplementation : public Operation
1280 BlitCopyImplementation (OperationContext& context, Resource& inResource, Resource& outResource)
1281 : m_context (context)
1282 , m_inResource (inResource)
1283 , m_outResource (outResource)
1284 , m_blitRegion (makeBlitRegion(m_inResource))
1286 DE_ASSERT(m_inResource.getType() == RESOURCE_TYPE_IMAGE);
1287 DE_ASSERT(m_outResource.getType() == RESOURCE_TYPE_IMAGE);
1289 const InstanceInterface& vki = m_context.getInstanceInterface();
1290 const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
1291 const auto& imgResource = m_inResource.getImage();
1292 const VkFormatProperties formatProps = getPhysicalDeviceFormatProperties(vki, physDevice, imgResource.format);
1293 const auto& features = ((imgResource.tiling == VK_IMAGE_TILING_LINEAR) ? formatProps.linearTilingFeatures : formatProps.optimalTilingFeatures);
1294 const VkFormatFeatureFlags requiredFlags = (VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT);
1296 // SRC and DST blit is required because both images are using the same format.
1297 if ((features & requiredFlags) != requiredFlags)
1298 TCU_THROW(NotSupportedError, "Format doesn't support blits");
1301 void recordCommands (const VkCommandBuffer cmdBuffer)
1303 const DeviceInterface& vk = m_context.getDeviceInterface();
1304 SynchronizationWrapperPtr synchronizationWrapper = getSynchronizationWrapper(m_context.getSynchronizationType(), vk, DE_FALSE);
1307 const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
1308 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags2KHR srcStageMask
1309 (VkAccessFlags2KHR)0, // VkAccessFlags2KHR srcAccessMask
1310 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags2KHR dstStageMask
1311 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR, // VkAccessFlags2KHR dstAccessMask
1312 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
1313 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout
1314 m_outResource.getImage().handle, // VkImage image
1315 m_outResource.getImage().subresourceRange // VkImageSubresourceRange subresourceRange
1317 VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
1318 synchronizationWrapper->cmdPipelineBarrier(cmdBuffer, &dependencyInfo);
1321 vk.cmdBlitImage(cmdBuffer,
1322 m_inResource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1323 m_outResource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1324 1u, &m_blitRegion, VK_FILTER_NEAREST);
1327 SyncInfo getInSyncInfo (void) const
1329 const SyncInfo syncInfo =
1331 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
1332 VK_ACCESS_2_TRANSFER_READ_BIT_KHR, // VkAccessFlags accessMask;
1333 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout imageLayout;
1338 SyncInfo getOutSyncInfo (void) const
1340 const SyncInfo syncInfo =
1342 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
1343 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR, // VkAccessFlags accessMask;
1344 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout imageLayout;
1349 Data getData (void) const
1351 Data data = { 0, DE_NULL };
1355 void setData (const Data&)
1361 OperationContext& m_context;
1362 Resource& m_inResource;
1363 Resource& m_outResource;
1364 const VkImageBlit m_blitRegion;
1367 class CopyCopyImplementation : public Operation
1370 CopyCopyImplementation (OperationContext& context, Resource& inResource, Resource& outResource)
1371 : m_context (context)
1372 , m_inResource (inResource)
1373 , m_outResource (outResource)
1374 , m_imageCopyRegion (makeImageRegion<VkImageCopy>(m_inResource))
1376 DE_ASSERT(m_inResource.getType() == RESOURCE_TYPE_IMAGE);
1377 DE_ASSERT(m_outResource.getType() == RESOURCE_TYPE_IMAGE);
1380 void recordCommands (const VkCommandBuffer cmdBuffer)
1382 const DeviceInterface& vk = m_context.getDeviceInterface();
1383 SynchronizationWrapperPtr synchronizationWrapper = getSynchronizationWrapper(m_context.getSynchronizationType(), vk, DE_FALSE);
1386 const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
1387 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags2KHR srcStageMask
1388 (VkAccessFlags)0, // VkAccessFlags2KHR srcAccessMask
1389 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags2KHR dstStageMask
1390 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR, // VkAccessFlags2KHR dstAccessMask
1391 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
1392 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout
1393 m_outResource.getImage().handle, // VkImage image
1394 m_outResource.getImage().subresourceRange // VkImageSubresourceRange subresourceRange
1396 VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
1397 synchronizationWrapper->cmdPipelineBarrier(cmdBuffer, &dependencyInfo);
1400 vk.cmdCopyImage(cmdBuffer,
1401 m_inResource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1402 m_outResource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1403 1u, &m_imageCopyRegion);
1406 SyncInfo getInSyncInfo (void) const
1408 const SyncInfo syncInfo =
1410 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
1411 VK_ACCESS_2_TRANSFER_READ_BIT_KHR, // VkAccessFlags accessMask;
1412 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout imageLayout;
1417 SyncInfo getOutSyncInfo (void) const
1419 const SyncInfo syncInfo =
1421 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
1422 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR, // VkAccessFlags accessMask;
1423 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout imageLayout;
1428 Data getData (void) const
1430 Data data = { 0, DE_NULL };
1434 void setData (const Data&)
1440 OperationContext& m_context;
1441 Resource& m_inResource;
1442 Resource& m_outResource;
1443 const VkImageCopy m_imageCopyRegion;
1446 class CopySupport : public OperationSupport
1449 CopySupport (const ResourceDescription& resourceDesc, const Type type)
1452 DE_ASSERT(resourceDesc.type == RESOURCE_TYPE_IMAGE);
1454 const bool isDepthStencil = isDepthStencilFormat(resourceDesc.imageFormat);
1455 m_requiredQueueFlags = (isDepthStencil || m_type == TYPE_BLIT ? VK_QUEUE_GRAPHICS_BIT : VK_QUEUE_TRANSFER_BIT);
1457 // Don't blit depth/stencil images.
1458 DE_ASSERT(m_type != TYPE_BLIT || !isDepthStencil);
1461 deUint32 getInResourceUsageFlags (void) const
1463 return VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1466 deUint32 getOutResourceUsageFlags (void) const
1468 return VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1471 VkQueueFlags getQueueFlags (const OperationContext& context) const
1474 return m_requiredQueueFlags;
1477 de::MovePtr<Operation> build (OperationContext&, Resource&) const
1480 return de::MovePtr<Operation>();
1483 de::MovePtr<Operation> build (OperationContext& context, Resource& inResource, Resource& outResource) const
1485 if (m_type == TYPE_COPY)
1486 return de::MovePtr<Operation>(new CopyCopyImplementation(context, inResource, outResource));
1488 return de::MovePtr<Operation>(new BlitCopyImplementation(context, inResource, outResource));
1493 VkQueueFlags m_requiredQueueFlags;
1496 } // CopyBlitImage ns
1498 namespace ShaderAccess
1503 DISPATCH_CALL_DISPATCH,
1504 DISPATCH_CALL_DISPATCH_INDIRECT,
1507 class GraphicsPipeline : public Pipeline
1510 GraphicsPipeline (OperationContext& context, const VkShaderStageFlagBits stage, const std::string& shaderPrefix, const VkDescriptorSetLayout descriptorSetLayout)
1511 : m_vertices (context)
1513 const DeviceInterface& vk = context.getDeviceInterface();
1514 const VkDevice device = context.getDevice();
1515 Allocator& allocator = context.getAllocator();
1516 const VkShaderStageFlags requiredStages = getRequiredStages(stage);
1520 m_colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
1521 m_colorImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
1522 m_colorImageExtent = makeExtent3D(16u, 16u, 1u);
1523 m_colorAttachmentImage = de::MovePtr<Image>(new Image(vk, device, allocator,
1524 makeImageCreateInfo(VK_IMAGE_TYPE_2D, m_colorImageExtent, m_colorFormat, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
1525 VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL),
1526 MemoryRequirement::Any));
1530 m_colorAttachmentView = makeImageView (vk, device, **m_colorAttachmentImage, VK_IMAGE_VIEW_TYPE_2D, m_colorFormat, m_colorImageSubresourceRange);
1531 m_renderPass = makeRenderPass (vk, device, m_colorFormat);
1532 m_framebuffer = makeFramebuffer (vk, device, *m_renderPass, *m_colorAttachmentView, m_colorImageExtent.width, m_colorImageExtent.height);
1533 m_pipelineLayout = makePipelineLayout(vk, device, descriptorSetLayout);
1535 GraphicsPipelineBuilder pipelineBuilder;
1537 .setRenderSize (tcu::IVec2(m_colorImageExtent.width, m_colorImageExtent.height))
1538 .setVertexInputSingleAttribute (m_vertices.getVertexFormat(), m_vertices.getVertexStride())
1539 .setShader (vk, device, VK_SHADER_STAGE_VERTEX_BIT, context.getBinaryCollection().get(shaderPrefix + "vert"), DE_NULL)
1540 .setShader (vk, device, VK_SHADER_STAGE_FRAGMENT_BIT, context.getBinaryCollection().get(shaderPrefix + "frag"), DE_NULL);
1542 if (requiredStages & (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT))
1544 .setPatchControlPoints (m_vertices.getNumVertices())
1545 .setShader (vk, device, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, context.getBinaryCollection().get(shaderPrefix + "tesc"), DE_NULL)
1546 .setShader (vk, device, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, context.getBinaryCollection().get(shaderPrefix + "tese"), DE_NULL);
1548 if (requiredStages & VK_SHADER_STAGE_GEOMETRY_BIT)
1550 .setShader (vk, device, VK_SHADER_STAGE_GEOMETRY_BIT, context.getBinaryCollection().get(shaderPrefix + "geom"), DE_NULL);
1552 m_pipeline = pipelineBuilder.build(vk, device, *m_pipelineLayout, *m_renderPass, context.getPipelineCacheData());
1555 void recordCommands (OperationContext& context, const VkCommandBuffer cmdBuffer, const VkDescriptorSet descriptorSet)
1557 const DeviceInterface& vk = context.getDeviceInterface();
1558 SynchronizationWrapperPtr synchronizationWrapper = getSynchronizationWrapper(context.getSynchronizationType(), vk, DE_FALSE);
1560 // Change color attachment image layout
1562 const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
1563 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags2KHR srcStageMask
1564 (VkAccessFlags)0, // VkAccessFlags2KHR srcAccessMask
1565 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags2KHR dstStageMask
1566 VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR, // VkAccessFlags2KHR dstAccessMask
1567 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
1568 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout
1569 **m_colorAttachmentImage, // VkImage image
1570 m_colorImageSubresourceRange // VkImageSubresourceRange subresourceRange
1572 VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
1573 synchronizationWrapper->cmdPipelineBarrier(cmdBuffer, &dependencyInfo);
1577 const VkRect2D renderArea = makeRect2D(m_colorImageExtent);
1578 const tcu::Vec4 clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
1580 beginRenderPass(vk, cmdBuffer, *m_renderPass, *m_framebuffer, renderArea, clearColor);
1583 vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
1584 vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &descriptorSet, 0u, DE_NULL);
1586 const VkDeviceSize vertexBufferOffset = 0ull;
1587 const VkBuffer vertexBuffer = m_vertices.getVertexBuffer();
1588 vk.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer, &vertexBufferOffset);
1591 vk.cmdDraw(cmdBuffer, m_vertices.getNumVertices(), 1u, 0u, 0u);
1592 endRenderPass(vk, cmdBuffer);
1596 const VertexGrid m_vertices;
1597 VkFormat m_colorFormat;
1598 de::MovePtr<Image> m_colorAttachmentImage;
1599 Move<VkImageView> m_colorAttachmentView;
1600 VkExtent3D m_colorImageExtent;
1601 VkImageSubresourceRange m_colorImageSubresourceRange;
1602 Move<VkRenderPass> m_renderPass;
1603 Move<VkFramebuffer> m_framebuffer;
1604 Move<VkPipelineLayout> m_pipelineLayout;
1605 Move<VkPipeline> m_pipeline;
1608 class ComputePipeline : public Pipeline
1611 ComputePipeline (OperationContext& context, const DispatchCall dispatchCall, const std::string& shaderPrefix, const VkDescriptorSetLayout descriptorSetLayout)
1612 : m_dispatchCall (dispatchCall)
1614 const DeviceInterface& vk = context.getDeviceInterface();
1615 const VkDevice device = context.getDevice();
1616 Allocator& allocator = context.getAllocator();
1618 if (m_dispatchCall == DISPATCH_CALL_DISPATCH_INDIRECT)
1620 m_indirectBuffer = de::MovePtr<Buffer>(new Buffer(vk, device, allocator,
1621 makeBufferCreateInfo(sizeof(VkDispatchIndirectCommand), VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT), MemoryRequirement::HostVisible));
1623 const Allocation& alloc = m_indirectBuffer->getAllocation();
1624 VkDispatchIndirectCommand* const pIndirectCommand = static_cast<VkDispatchIndirectCommand*>(alloc.getHostPtr());
1626 pIndirectCommand->x = 1u;
1627 pIndirectCommand->y = 1u;
1628 pIndirectCommand->z = 1u;
1630 flushAlloc(vk, device, alloc);
1633 const Unique<VkShaderModule> shaderModule(createShaderModule(vk, device, context.getBinaryCollection().get(shaderPrefix + "comp"), (VkShaderModuleCreateFlags)0));
1635 m_pipelineLayout = makePipelineLayout(vk, device, descriptorSetLayout);
1636 m_pipeline = makeComputePipeline(vk, device, *m_pipelineLayout, *shaderModule, DE_NULL, context.getPipelineCacheData());
1639 void recordCommands (OperationContext& context, const VkCommandBuffer cmdBuffer, const VkDescriptorSet descriptorSet)
1641 const DeviceInterface& vk = context.getDeviceInterface();
1643 vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipeline);
1644 vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0u, 1u, &descriptorSet, 0u, DE_NULL);
1646 if (m_dispatchCall == DISPATCH_CALL_DISPATCH_INDIRECT)
1647 vk.cmdDispatchIndirect(cmdBuffer, **m_indirectBuffer, 0u);
1649 vk.cmdDispatch(cmdBuffer, 1u, 1u, 1u);
1653 const DispatchCall m_dispatchCall;
1654 de::MovePtr<Buffer> m_indirectBuffer;
1655 Move<VkPipelineLayout> m_pipelineLayout;
1656 Move<VkPipeline> m_pipeline;
1659 //! Read/write operation on a UBO/SSBO in graphics/compute pipeline.
1660 class BufferImplementation : public Operation
1663 BufferImplementation (OperationContext& context,
1665 const VkShaderStageFlagBits stage,
1666 const BufferType bufferType,
1667 const std::string& shaderPrefix,
1668 const AccessMode mode,
1669 const PipelineType pipelineType,
1670 const DispatchCall dispatchCall)
1671 : m_context (context)
1672 , m_resource (resource)
1674 , m_pipelineStage (pipelineStageFlagsFromShaderStageFlagBits(m_stage))
1675 , m_bufferType (bufferType)
1677 , m_dispatchCall (dispatchCall)
1679 requireFeaturesForSSBOAccess (m_context, m_stage);
1681 const DeviceInterface& vk = m_context.getDeviceInterface();
1682 const VkDevice device = m_context.getDevice();
1683 Allocator& allocator = m_context.getAllocator();
1685 m_hostBuffer = de::MovePtr<Buffer>(new Buffer(
1686 vk, device, allocator, makeBufferCreateInfo(m_resource.getBuffer().size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible));
1688 // Init host buffer data
1690 const Allocation& alloc = m_hostBuffer->getAllocation();
1691 if (m_mode == ACCESS_MODE_READ)
1692 deMemset(alloc.getHostPtr(), 0, static_cast<size_t>(m_resource.getBuffer().size));
1694 fillPattern(alloc.getHostPtr(), m_resource.getBuffer().size);
1695 flushAlloc(vk, device, alloc);
1698 // Prepare descriptors
1700 const VkDescriptorType bufferDescriptorType = (m_bufferType == BUFFER_TYPE_UNIFORM ? VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER : VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
1702 m_descriptorSetLayout = DescriptorSetLayoutBuilder()
1703 .addSingleBinding(bufferDescriptorType, m_stage)
1704 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, m_stage)
1707 m_descriptorPool = DescriptorPoolBuilder()
1708 .addType(bufferDescriptorType)
1709 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
1710 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1712 m_descriptorSet = makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout);
1714 const VkDescriptorBufferInfo bufferInfo = makeDescriptorBufferInfo(m_resource.getBuffer().handle, m_resource.getBuffer().offset, m_resource.getBuffer().size);
1715 const VkDescriptorBufferInfo hostBufferInfo = makeDescriptorBufferInfo(**m_hostBuffer, 0u, m_resource.getBuffer().size);
1717 if (m_mode == ACCESS_MODE_READ)
1719 DescriptorSetUpdateBuilder()
1720 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), bufferDescriptorType, &bufferInfo)
1721 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &hostBufferInfo)
1722 .update(vk, device);
1726 DescriptorSetUpdateBuilder()
1727 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &hostBufferInfo)
1728 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufferInfo)
1729 .update(vk, device);
1734 m_pipeline = (pipelineType == PIPELINE_TYPE_GRAPHICS ? de::MovePtr<Pipeline>(new GraphicsPipeline(context, stage, shaderPrefix, *m_descriptorSetLayout))
1735 : de::MovePtr<Pipeline>(new ComputePipeline(context, m_dispatchCall, shaderPrefix, *m_descriptorSetLayout)));
1738 void recordCommands (const VkCommandBuffer cmdBuffer)
1740 m_pipeline->recordCommands(m_context, cmdBuffer, *m_descriptorSet);
1742 // Post draw/dispatch commands
1744 if (m_mode == ACCESS_MODE_READ)
1746 const DeviceInterface& vk = m_context.getDeviceInterface();
1747 SynchronizationWrapperPtr synchronizationWrapper = getSynchronizationWrapper(m_context.getSynchronizationType(), vk, DE_FALSE);
1749 // Insert a barrier so data written by the shader is available to the host
1750 const VkBufferMemoryBarrier2KHR bufferMemoryBarrier2 = makeBufferMemoryBarrier2(
1751 m_pipelineStage, // VkPipelineStageFlags2KHR srcStageMask
1752 VK_ACCESS_2_SHADER_WRITE_BIT_KHR, // VkAccessFlags2KHR srcAccessMask
1753 VK_PIPELINE_STAGE_HOST_BIT, // VkPipelineStageFlags2KHR dstStageMask
1754 VK_ACCESS_2_HOST_READ_BIT_KHR, // VkAccessFlags2KHR dstAccessMask
1755 **m_hostBuffer, // VkBuffer buffer
1756 0u, // VkDeviceSize offset
1757 m_resource.getBuffer().size // VkDeviceSize size
1759 VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, &bufferMemoryBarrier2);
1760 synchronizationWrapper->cmdPipelineBarrier(cmdBuffer, &dependencyInfo);
1764 SyncInfo getInSyncInfo (void) const
1766 const VkAccessFlags2KHR accessFlags = (m_mode == ACCESS_MODE_READ ? (m_bufferType == BUFFER_TYPE_UNIFORM ? VK_ACCESS_2_UNIFORM_READ_BIT_KHR
1767 : VK_ACCESS_2_SHADER_READ_BIT_KHR)
1768 : VK_ACCESS_2_SHADER_WRITE_BIT_KHR);
1769 const SyncInfo syncInfo =
1771 m_pipelineStage, // VkPipelineStageFlags stageMask;
1772 accessFlags, // VkAccessFlags accessMask;
1773 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
1778 SyncInfo getOutSyncInfo (void) const
1780 const VkAccessFlags accessFlags = m_mode == ACCESS_MODE_WRITE ? VK_ACCESS_2_SHADER_WRITE_BIT_KHR : 0;
1781 const SyncInfo syncInfo =
1783 m_pipelineStage, // VkPipelineStageFlags stageMask;
1784 accessFlags, // VkAccessFlags accessMask;
1785 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
1790 Data getData (void) const
1792 return getHostBufferData(m_context, *m_hostBuffer, m_resource.getBuffer().size);
1795 void setData (const Data& data)
1797 DE_ASSERT(m_mode == ACCESS_MODE_WRITE);
1798 setHostBufferData(m_context, *m_hostBuffer, data);
1802 OperationContext& m_context;
1803 Resource& m_resource;
1804 const VkShaderStageFlagBits m_stage;
1805 const VkPipelineStageFlags m_pipelineStage;
1806 const BufferType m_bufferType;
1807 const AccessMode m_mode;
1808 const DispatchCall m_dispatchCall;
1809 de::MovePtr<Buffer> m_hostBuffer;
1810 Move<VkDescriptorPool> m_descriptorPool;
1811 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
1812 Move<VkDescriptorSet> m_descriptorSet;
1813 de::MovePtr<Pipeline> m_pipeline;
1816 class ImageImplementation : public Operation
1819 ImageImplementation (OperationContext& context,
1821 const VkShaderStageFlagBits stage,
1822 const std::string& shaderPrefix,
1823 const AccessMode mode,
1824 const PipelineType pipelineType,
1825 const DispatchCall dispatchCall)
1826 : m_context (context)
1827 , m_resource (resource)
1829 , m_pipelineStage (pipelineStageFlagsFromShaderStageFlagBits(m_stage))
1831 , m_dispatchCall (dispatchCall)
1832 , m_hostBufferSizeBytes (getPixelBufferSize(m_resource.getImage().format, m_resource.getImage().extent))
1834 const DeviceInterface& vk = m_context.getDeviceInterface();
1835 const InstanceInterface& vki = m_context.getInstanceInterface();
1836 const VkDevice device = m_context.getDevice();
1837 const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
1838 Allocator& allocator = m_context.getAllocator();
1840 // Image stores are always required, in either access mode.
1841 requireFeaturesForSSBOAccess(m_context, m_stage);
1843 // Some storage image formats may not be supported
1844 const auto& imgResource = m_resource.getImage();
1845 requireStorageImageSupport(vki, physDevice, imgResource.format, imgResource.tiling);
1847 m_hostBuffer = de::MovePtr<Buffer>(new Buffer(
1848 vk, device, allocator, makeBufferCreateInfo(m_hostBufferSizeBytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT),
1849 MemoryRequirement::HostVisible));
1851 // Init host buffer data
1853 const Allocation& alloc = m_hostBuffer->getAllocation();
1854 if (m_mode == ACCESS_MODE_READ)
1855 deMemset(alloc.getHostPtr(), 0, static_cast<size_t>(m_hostBufferSizeBytes));
1857 fillPattern(alloc.getHostPtr(), m_hostBufferSizeBytes);
1858 flushAlloc(vk, device, alloc);
1863 m_image = de::MovePtr<Image>(new Image(vk, device, allocator,
1864 makeImageCreateInfo(m_resource.getImage().imageType, m_resource.getImage().extent, m_resource.getImage().format,
1865 (VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_STORAGE_BIT),
1866 VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL),
1867 MemoryRequirement::Any));
1869 if (m_mode == ACCESS_MODE_READ)
1871 m_srcImage = &m_resource.getImage().handle;
1872 m_dstImage = &(**m_image);
1876 m_srcImage = &(**m_image);
1877 m_dstImage = &m_resource.getImage().handle;
1880 const VkImageViewType viewType = getImageViewType(m_resource.getImage().imageType);
1882 m_srcImageView = makeImageView(vk, device, *m_srcImage, viewType, m_resource.getImage().format, m_resource.getImage().subresourceRange);
1883 m_dstImageView = makeImageView(vk, device, *m_dstImage, viewType, m_resource.getImage().format, m_resource.getImage().subresourceRange);
1886 // Prepare descriptors
1888 m_descriptorSetLayout = DescriptorSetLayoutBuilder()
1889 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, m_stage)
1890 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, m_stage)
1893 m_descriptorPool = DescriptorPoolBuilder()
1894 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1895 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1896 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1898 m_descriptorSet = makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout);
1900 const VkDescriptorImageInfo srcImageInfo = makeDescriptorImageInfo(DE_NULL, *m_srcImageView, VK_IMAGE_LAYOUT_GENERAL);
1901 const VkDescriptorImageInfo dstImageInfo = makeDescriptorImageInfo(DE_NULL, *m_dstImageView, VK_IMAGE_LAYOUT_GENERAL);
1903 DescriptorSetUpdateBuilder()
1904 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &srcImageInfo)
1905 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &dstImageInfo)
1906 .update(vk, device);
1910 m_pipeline = (pipelineType == PIPELINE_TYPE_GRAPHICS ? de::MovePtr<Pipeline>(new GraphicsPipeline(context, stage, shaderPrefix, *m_descriptorSetLayout))
1911 : de::MovePtr<Pipeline>(new ComputePipeline(context, m_dispatchCall, shaderPrefix, *m_descriptorSetLayout)));
1914 void recordCommands (const VkCommandBuffer cmdBuffer)
1916 const DeviceInterface& vk = m_context.getDeviceInterface();
1917 const VkBufferImageCopy bufferCopyRegion = makeBufferImageCopy(m_resource.getImage().extent, m_resource.getImage().subresourceLayers);
1918 SynchronizationWrapperPtr synchronizationWrapper = getSynchronizationWrapper(m_context.getSynchronizationType(), vk, DE_FALSE);
1920 // Destination image layout
1922 const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
1923 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags2KHR srcStageMask
1924 (VkAccessFlags)0, // VkAccessFlags2KHR srcAccessMask
1925 m_pipelineStage, // VkPipelineStageFlags2KHR dstStageMask
1926 VK_ACCESS_2_SHADER_WRITE_BIT_KHR, // VkAccessFlags2KHR dstAccessMask
1927 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
1928 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout
1929 *m_dstImage, // VkImage image
1930 m_resource.getImage().subresourceRange // VkImageSubresourceRange subresourceRange
1932 VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
1933 synchronizationWrapper->cmdPipelineBarrier(cmdBuffer, &dependencyInfo);
1936 // In write mode, source image must be filled with data.
1937 if (m_mode == ACCESS_MODE_WRITE)
1939 // Layout for transfer
1941 const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
1942 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags2KHR srcStageMask
1943 (VkAccessFlags)0, // VkAccessFlags2KHR srcAccessMask
1944 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags2KHR dstStageMask
1945 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR, // VkAccessFlags2KHR dstAccessMask
1946 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
1947 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout
1948 *m_srcImage, // VkImage image
1949 m_resource.getImage().subresourceRange // VkImageSubresourceRange subresourceRange
1951 VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
1952 synchronizationWrapper->cmdPipelineBarrier(cmdBuffer, &dependencyInfo);
1955 // Host buffer -> Src image
1956 vk.cmdCopyBufferToImage(cmdBuffer, **m_hostBuffer, *m_srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &bufferCopyRegion);
1958 // Layout for shader reading
1960 const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
1961 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags2KHR srcStageMask
1962 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR, // VkAccessFlags2KHR srcAccessMask
1963 m_pipelineStage, // VkPipelineStageFlags2KHR dstStageMask
1964 VK_ACCESS_2_SHADER_READ_BIT_KHR, // VkAccessFlags2KHR dstAccessMask
1965 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout
1966 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout
1967 *m_srcImage, // VkImage image
1968 m_resource.getImage().subresourceRange // VkImageSubresourceRange subresourceRange
1970 VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
1971 synchronizationWrapper->cmdPipelineBarrier(cmdBuffer, &dependencyInfo);
1977 m_pipeline->recordCommands(m_context, cmdBuffer, *m_descriptorSet);
1979 // Post draw/dispatch commands
1981 if (m_mode == ACCESS_MODE_READ)
1983 // Layout for transfer
1985 const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
1986 m_pipelineStage, // VkPipelineStageFlags2KHR srcStageMask
1987 VK_ACCESS_2_SHADER_WRITE_BIT_KHR, // VkAccessFlags2KHR srcAccessMask
1988 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags2KHR dstStageMask
1989 VK_ACCESS_2_TRANSFER_READ_BIT_KHR, // VkAccessFlags2KHR dstAccessMask
1990 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout oldLayout
1991 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout
1992 *m_dstImage, // VkImage image
1993 m_resource.getImage().subresourceRange // VkImageSubresourceRange subresourceRange
1995 VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
1996 synchronizationWrapper->cmdPipelineBarrier(cmdBuffer, &dependencyInfo);
1999 // Dst image -> Host buffer
2000 vk.cmdCopyImageToBuffer(cmdBuffer, *m_dstImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_hostBuffer, 1u, &bufferCopyRegion);
2002 // Insert a barrier so data written by the shader is available to the host
2004 const VkBufferMemoryBarrier2KHR bufferMemoryBarrier2 = makeBufferMemoryBarrier2(
2005 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags2KHR srcStageMask
2006 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR, // VkAccessFlags2KHR srcAccessMask
2007 VK_PIPELINE_STAGE_HOST_BIT, // VkPipelineStageFlags2KHR dstStageMask
2008 VK_ACCESS_2_HOST_READ_BIT_KHR, // VkAccessFlags2KHR dstAccessMask
2009 **m_hostBuffer, // VkBuffer buffer
2010 0u, // VkDeviceSize offset
2011 m_hostBufferSizeBytes // VkDeviceSize size
2013 VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, &bufferMemoryBarrier2);
2014 synchronizationWrapper->cmdPipelineBarrier(cmdBuffer, &dependencyInfo);
2019 SyncInfo getInSyncInfo (void) const
2021 const VkAccessFlags accessFlags = (m_mode == ACCESS_MODE_READ ? VK_ACCESS_2_SHADER_READ_BIT_KHR : 0);
2022 const SyncInfo syncInfo =
2024 m_pipelineStage, // VkPipelineStageFlags stageMask;
2025 accessFlags, // VkAccessFlags accessMask;
2026 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout;
2031 SyncInfo getOutSyncInfo (void) const
2033 const VkAccessFlags accessFlags = (m_mode == ACCESS_MODE_WRITE ? VK_ACCESS_2_SHADER_WRITE_BIT_KHR : 0);
2034 const SyncInfo syncInfo =
2036 m_pipelineStage, // VkPipelineStageFlags stageMask;
2037 accessFlags, // VkAccessFlags accessMask;
2038 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout;
2043 Data getData (void) const
2045 return getHostBufferData(m_context, *m_hostBuffer, m_hostBufferSizeBytes);
2048 void setData (const Data& data)
2050 DE_ASSERT(m_mode == ACCESS_MODE_WRITE);
2051 setHostBufferData(m_context, *m_hostBuffer, data);
2055 OperationContext& m_context;
2056 Resource& m_resource;
2057 const VkShaderStageFlagBits m_stage;
2058 const VkPipelineStageFlags m_pipelineStage;
2059 const AccessMode m_mode;
2060 const DispatchCall m_dispatchCall;
2061 const VkDeviceSize m_hostBufferSizeBytes;
2062 de::MovePtr<Buffer> m_hostBuffer;
2063 de::MovePtr<Image> m_image; //! Additional image used as src or dst depending on operation mode.
2064 const VkImage* m_srcImage;
2065 const VkImage* m_dstImage;
2066 Move<VkImageView> m_srcImageView;
2067 Move<VkImageView> m_dstImageView;
2068 Move<VkDescriptorPool> m_descriptorPool;
2069 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
2070 Move<VkDescriptorSet> m_descriptorSet;
2071 de::MovePtr<Pipeline> m_pipeline;
2074 //! Create generic passthrough shaders with bits of custom code inserted in a specific shader stage.
2075 void initPassthroughPrograms (SourceCollections& programCollection,
2076 const std::string& shaderPrefix,
2077 const std::string& declCode,
2078 const std::string& mainCode,
2079 const VkShaderStageFlagBits stage)
2081 const VkShaderStageFlags requiredStages = getRequiredStages(stage);
2083 if (requiredStages & VK_SHADER_STAGE_VERTEX_BIT)
2085 std::ostringstream src;
2086 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
2088 << "layout(location = 0) in vec4 v_in_position;\n"
2090 << "out " << s_perVertexBlock << ";\n"
2092 << (stage & VK_SHADER_STAGE_VERTEX_BIT ? declCode + "\n" : "")
2093 << "void main (void)\n"
2095 << " gl_Position = v_in_position;\n"
2096 << (stage & VK_SHADER_STAGE_VERTEX_BIT ? mainCode : "")
2099 if (!programCollection.glslSources.contains(shaderPrefix + "vert"))
2100 programCollection.glslSources.add(shaderPrefix + "vert") << glu::VertexSource(src.str());
2103 if (requiredStages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
2105 std::ostringstream src;
2106 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
2108 << "layout(vertices = 3) out;\n"
2110 << "in " << s_perVertexBlock << " gl_in[gl_MaxPatchVertices];\n"
2112 << "out " << s_perVertexBlock << " gl_out[];\n"
2114 << (stage & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ? declCode + "\n" : "")
2115 << "void main (void)\n"
2117 << " gl_TessLevelInner[0] = 1.0;\n"
2118 << " gl_TessLevelInner[1] = 1.0;\n"
2120 << " gl_TessLevelOuter[0] = 1.0;\n"
2121 << " gl_TessLevelOuter[1] = 1.0;\n"
2122 << " gl_TessLevelOuter[2] = 1.0;\n"
2123 << " gl_TessLevelOuter[3] = 1.0;\n"
2125 << " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
2126 << (stage & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ? "\n" + mainCode : "")
2129 if (!programCollection.glslSources.contains(shaderPrefix + "tesc"))
2130 programCollection.glslSources.add(shaderPrefix + "tesc") << glu::TessellationControlSource(src.str());
2133 if (requiredStages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
2135 std::ostringstream src;
2136 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
2138 << "layout(triangles, equal_spacing, ccw) in;\n"
2140 << "in " << s_perVertexBlock << " gl_in[gl_MaxPatchVertices];\n"
2142 << "out " << s_perVertexBlock << ";\n"
2144 << (stage & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT ? declCode + "\n" : "")
2145 << "void main (void)\n"
2147 << " vec3 px = gl_TessCoord.x * gl_in[0].gl_Position.xyz;\n"
2148 << " vec3 py = gl_TessCoord.y * gl_in[1].gl_Position.xyz;\n"
2149 << " vec3 pz = gl_TessCoord.z * gl_in[2].gl_Position.xyz;\n"
2150 << " gl_Position = vec4(px + py + pz, 1.0);\n"
2151 << (stage & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT ? mainCode : "")
2154 if (!programCollection.glslSources.contains(shaderPrefix + "tese"))
2155 programCollection.glslSources.add(shaderPrefix + "tese") << glu::TessellationEvaluationSource(src.str());
2158 if (requiredStages & VK_SHADER_STAGE_GEOMETRY_BIT)
2160 std::ostringstream src;
2161 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
2163 << "layout(triangles) in;\n"
2164 << "layout(triangle_strip, max_vertices = 3) out;\n"
2166 << "in " << s_perVertexBlock << " gl_in[];\n"
2168 << "out " << s_perVertexBlock << ";\n"
2170 << (stage & VK_SHADER_STAGE_GEOMETRY_BIT ? declCode + "\n" : "")
2171 << "void main (void)\n"
2173 << " gl_Position = gl_in[0].gl_Position;\n"
2174 << " EmitVertex();\n"
2176 << " gl_Position = gl_in[1].gl_Position;\n"
2177 << " EmitVertex();\n"
2179 << " gl_Position = gl_in[2].gl_Position;\n"
2180 << " EmitVertex();\n"
2181 << (stage & VK_SHADER_STAGE_GEOMETRY_BIT ? "\n" + mainCode : "")
2184 if (!programCollection.glslSources.contains(shaderPrefix + "geom"))
2185 programCollection.glslSources.add(shaderPrefix + "geom") << glu::GeometrySource(src.str());
2188 if (requiredStages & VK_SHADER_STAGE_FRAGMENT_BIT)
2190 std::ostringstream src;
2191 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
2193 << "layout(location = 0) out vec4 o_color;\n"
2195 << (stage & VK_SHADER_STAGE_FRAGMENT_BIT ? declCode + "\n" : "")
2196 << "void main (void)\n"
2198 << " o_color = vec4(1.0);\n"
2199 << (stage & VK_SHADER_STAGE_FRAGMENT_BIT ? "\n" + mainCode : "")
2202 if (!programCollection.glslSources.contains(shaderPrefix + "frag"))
2203 programCollection.glslSources.add(shaderPrefix + "frag") << glu::FragmentSource(src.str());
2206 if (requiredStages & VK_SHADER_STAGE_COMPUTE_BIT)
2208 std::ostringstream src;
2209 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
2211 << "layout(local_size_x = 1) in;\n"
2213 << (stage & VK_SHADER_STAGE_COMPUTE_BIT ? declCode + "\n" : "")
2214 << "void main (void)\n"
2216 << (stage & VK_SHADER_STAGE_COMPUTE_BIT ? mainCode : "")
2219 if (!programCollection.glslSources.contains(shaderPrefix + "comp"))
2220 programCollection.glslSources.add(shaderPrefix + "comp") << glu::ComputeSource(src.str());
2224 class BufferSupport : public OperationSupport
2227 BufferSupport (const ResourceDescription& resourceDesc,
2228 const BufferType bufferType,
2229 const AccessMode mode,
2230 const VkShaderStageFlagBits stage,
2231 const DispatchCall dispatchCall = DISPATCH_CALL_DISPATCH)
2232 : m_resourceDesc (resourceDesc)
2233 , m_bufferType (bufferType)
2236 , m_shaderPrefix (std::string(m_mode == ACCESS_MODE_READ ? "read_" : "write_") + (m_bufferType == BUFFER_TYPE_UNIFORM ? "ubo_" : "ssbo_"))
2237 , m_dispatchCall (dispatchCall)
2239 DE_ASSERT(m_resourceDesc.type == RESOURCE_TYPE_BUFFER);
2240 DE_ASSERT(m_bufferType == BUFFER_TYPE_UNIFORM || m_bufferType == BUFFER_TYPE_STORAGE);
2241 DE_ASSERT(m_mode == ACCESS_MODE_READ || m_mode == ACCESS_MODE_WRITE);
2242 DE_ASSERT(m_mode == ACCESS_MODE_READ || m_bufferType == BUFFER_TYPE_STORAGE);
2243 DE_ASSERT(m_bufferType != BUFFER_TYPE_UNIFORM || m_resourceDesc.size.x() <= MAX_UBO_RANGE);
2244 DE_ASSERT(m_dispatchCall == DISPATCH_CALL_DISPATCH || m_dispatchCall == DISPATCH_CALL_DISPATCH_INDIRECT);
2246 assertValidShaderStage(m_stage);
2249 void initPrograms (SourceCollections& programCollection) const
2251 DE_ASSERT((m_resourceDesc.size.x() % sizeof(tcu::UVec4)) == 0);
2253 const std::string bufferTypeStr = (m_bufferType == BUFFER_TYPE_UNIFORM ? "uniform" : "buffer");
2254 const int numVecElements = static_cast<int>(m_resourceDesc.size.x() / sizeof(tcu::UVec4)); // std140 must be aligned to a multiple of 16
2256 std::ostringstream declSrc;
2257 declSrc << "layout(set = 0, binding = 0, std140) readonly " << bufferTypeStr << " Input {\n"
2258 << " uvec4 data[" << numVecElements << "];\n"
2261 << "layout(set = 0, binding = 1, std140) writeonly buffer Output {\n"
2262 << " uvec4 data[" << numVecElements << "];\n"
2265 std::ostringstream copySrc;
2266 copySrc << " for (int i = 0; i < " << numVecElements << "; ++i) {\n"
2267 << " b_out.data[i] = b_in.data[i];\n"
2270 initPassthroughPrograms(programCollection, m_shaderPrefix, declSrc.str(), copySrc.str(), m_stage);
2273 deUint32 getInResourceUsageFlags (void) const
2275 if (m_bufferType == BUFFER_TYPE_UNIFORM)
2276 return m_mode == ACCESS_MODE_READ ? VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT : 0;
2278 return m_mode == ACCESS_MODE_READ ? VK_BUFFER_USAGE_STORAGE_BUFFER_BIT : 0;
2281 deUint32 getOutResourceUsageFlags (void) const
2283 if (m_bufferType == BUFFER_TYPE_UNIFORM)
2284 return m_mode == ACCESS_MODE_WRITE ? VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT : 0;
2286 return m_mode == ACCESS_MODE_WRITE ? VK_BUFFER_USAGE_STORAGE_BUFFER_BIT : 0;
2289 VkQueueFlags getQueueFlags (const OperationContext& context) const
2292 return (m_stage == VK_SHADER_STAGE_COMPUTE_BIT ? VK_QUEUE_COMPUTE_BIT : VK_QUEUE_GRAPHICS_BIT);
2295 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
2297 if (m_stage & VK_SHADER_STAGE_COMPUTE_BIT)
2298 return de::MovePtr<Operation>(new BufferImplementation(context, resource, m_stage, m_bufferType, m_shaderPrefix, m_mode, PIPELINE_TYPE_COMPUTE, m_dispatchCall));
2300 return de::MovePtr<Operation>(new BufferImplementation(context, resource, m_stage, m_bufferType, m_shaderPrefix, m_mode, PIPELINE_TYPE_GRAPHICS, m_dispatchCall));
2303 de::MovePtr<Operation> build (OperationContext&, Resource&, Resource&) const
2306 return de::MovePtr<Operation>();
2310 const ResourceDescription m_resourceDesc;
2311 const BufferType m_bufferType;
2312 const AccessMode m_mode;
2313 const VkShaderStageFlagBits m_stage;
2314 const std::string m_shaderPrefix;
2315 const DispatchCall m_dispatchCall;
2318 class ImageSupport : public OperationSupport
2321 ImageSupport (const ResourceDescription& resourceDesc,
2322 const AccessMode mode,
2323 const VkShaderStageFlagBits stage,
2324 const DispatchCall dispatchCall = DISPATCH_CALL_DISPATCH)
2325 : m_resourceDesc (resourceDesc)
2328 , m_shaderPrefix (m_mode == ACCESS_MODE_READ ? "read_image_" : "write_image_")
2329 , m_dispatchCall (dispatchCall)
2331 DE_ASSERT(m_resourceDesc.type == RESOURCE_TYPE_IMAGE);
2332 DE_ASSERT(m_mode == ACCESS_MODE_READ || m_mode == ACCESS_MODE_WRITE);
2333 DE_ASSERT(m_dispatchCall == DISPATCH_CALL_DISPATCH || m_dispatchCall == DISPATCH_CALL_DISPATCH_INDIRECT);
2335 assertValidShaderStage(m_stage);
2338 void initPrograms (SourceCollections& programCollection) const
2340 const std::string imageFormat = getShaderImageFormatQualifier(m_resourceDesc.imageFormat);
2341 const std::string imageType = getShaderImageType(m_resourceDesc.imageFormat, m_resourceDesc.imageType);
2343 std::ostringstream declSrc;
2344 declSrc << "layout(set = 0, binding = 0, " << imageFormat << ") readonly uniform " << imageType << " srcImg;\n"
2345 << "layout(set = 0, binding = 1, " << imageFormat << ") writeonly uniform " << imageType << " dstImg;\n";
2347 std::ostringstream mainSrc;
2348 if (m_resourceDesc.imageType == VK_IMAGE_TYPE_1D)
2349 mainSrc << " for (int x = 0; x < " << m_resourceDesc.size.x() << "; ++x)\n"
2350 << " imageStore(dstImg, x, imageLoad(srcImg, x));\n";
2351 else if (m_resourceDesc.imageType == VK_IMAGE_TYPE_2D)
2352 mainSrc << " for (int y = 0; y < " << m_resourceDesc.size.y() << "; ++y)\n"
2353 << " for (int x = 0; x < " << m_resourceDesc.size.x() << "; ++x)\n"
2354 << " imageStore(dstImg, ivec2(x, y), imageLoad(srcImg, ivec2(x, y)));\n";
2355 else if (m_resourceDesc.imageType == VK_IMAGE_TYPE_3D)
2356 mainSrc << " for (int z = 0; z < " << m_resourceDesc.size.z() << "; ++z)\n"
2357 << " for (int y = 0; y < " << m_resourceDesc.size.y() << "; ++y)\n"
2358 << " for (int x = 0; x < " << m_resourceDesc.size.x() << "; ++x)\n"
2359 << " imageStore(dstImg, ivec3(x, y, z), imageLoad(srcImg, ivec3(x, y, z)));\n";
2363 initPassthroughPrograms(programCollection, m_shaderPrefix, declSrc.str(), mainSrc.str(), m_stage);
2366 deUint32 getInResourceUsageFlags (void) const
2368 return VK_IMAGE_USAGE_STORAGE_BIT;
2371 deUint32 getOutResourceUsageFlags (void) const
2373 return VK_IMAGE_USAGE_STORAGE_BIT;
2376 VkQueueFlags getQueueFlags (const OperationContext& context) const
2379 return (m_stage == VK_SHADER_STAGE_COMPUTE_BIT ? VK_QUEUE_COMPUTE_BIT : VK_QUEUE_GRAPHICS_BIT);
2382 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
2384 if (m_stage & VK_SHADER_STAGE_COMPUTE_BIT)
2385 return de::MovePtr<Operation>(new ImageImplementation(context, resource, m_stage, m_shaderPrefix, m_mode, PIPELINE_TYPE_COMPUTE, m_dispatchCall));
2387 return de::MovePtr<Operation>(new ImageImplementation(context, resource, m_stage, m_shaderPrefix, m_mode, PIPELINE_TYPE_GRAPHICS, m_dispatchCall));
2390 de::MovePtr<Operation> build (OperationContext&, Resource&, Resource&) const
2393 return de::MovePtr<Operation>();
2397 const ResourceDescription m_resourceDesc;
2398 const AccessMode m_mode;
2399 const VkShaderStageFlagBits m_stage;
2400 const std::string m_shaderPrefix;
2401 const DispatchCall m_dispatchCall;
2404 //! Copy operation on a UBO/SSBO in graphics/compute pipeline.
2405 class BufferCopyImplementation : public Operation
2408 BufferCopyImplementation (OperationContext& context,
2409 Resource& inResource,
2410 Resource& outResource,
2411 const VkShaderStageFlagBits stage,
2412 const BufferType bufferType,
2413 const std::string& shaderPrefix,
2414 const PipelineType pipelineType,
2415 const DispatchCall dispatchCall)
2416 : m_context (context)
2417 , m_inResource (inResource)
2418 , m_outResource (outResource)
2420 , m_pipelineStage (pipelineStageFlagsFromShaderStageFlagBits(m_stage))
2421 , m_bufferType (bufferType)
2422 , m_dispatchCall (dispatchCall)
2424 requireFeaturesForSSBOAccess (m_context, m_stage);
2426 const DeviceInterface& vk = m_context.getDeviceInterface();
2427 const VkDevice device = m_context.getDevice();
2429 // Prepare descriptors
2431 const VkDescriptorType bufferDescriptorType = (m_bufferType == BUFFER_TYPE_UNIFORM ? VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER : VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2433 m_descriptorSetLayout = DescriptorSetLayoutBuilder()
2434 .addSingleBinding(bufferDescriptorType, m_stage)
2435 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, m_stage)
2438 m_descriptorPool = DescriptorPoolBuilder()
2439 .addType(bufferDescriptorType)
2440 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
2441 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
2443 m_descriptorSet = makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout);
2445 const VkDescriptorBufferInfo inBufferInfo = makeDescriptorBufferInfo(m_inResource.getBuffer().handle, m_inResource.getBuffer().offset, m_inResource.getBuffer().size);
2446 const VkDescriptorBufferInfo outBufferInfo = makeDescriptorBufferInfo(m_outResource.getBuffer().handle, m_outResource.getBuffer().offset, m_outResource.getBuffer().size);
2448 DescriptorSetUpdateBuilder()
2449 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &inBufferInfo)
2450 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outBufferInfo)
2451 .update(vk, device);
2455 m_pipeline = (pipelineType == PIPELINE_TYPE_GRAPHICS ? de::MovePtr<Pipeline>(new GraphicsPipeline(context, stage, shaderPrefix, *m_descriptorSetLayout))
2456 : de::MovePtr<Pipeline>(new ComputePipeline(context, m_dispatchCall, shaderPrefix, *m_descriptorSetLayout)));
2459 void recordCommands (const VkCommandBuffer cmdBuffer)
2461 m_pipeline->recordCommands(m_context, cmdBuffer, *m_descriptorSet);
2464 SyncInfo getInSyncInfo (void) const
2466 const SyncInfo syncInfo =
2468 m_pipelineStage, // VkPipelineStageFlags stageMask;
2469 VK_ACCESS_2_SHADER_READ_BIT_KHR, // VkAccessFlags accessMask;
2470 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
2475 SyncInfo getOutSyncInfo (void) const
2477 const SyncInfo syncInfo =
2479 m_pipelineStage, // VkPipelineStageFlags stageMask;
2480 VK_ACCESS_2_SHADER_WRITE_BIT_KHR, // VkAccessFlags accessMask;
2481 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
2486 Data getData (void) const
2488 Data data = { 0, DE_NULL };
2492 void setData (const Data&)
2498 OperationContext& m_context;
2499 Resource& m_inResource;
2500 Resource& m_outResource;
2501 const VkShaderStageFlagBits m_stage;
2502 const VkPipelineStageFlags m_pipelineStage;
2503 const BufferType m_bufferType;
2504 const DispatchCall m_dispatchCall;
2505 Move<VkDescriptorPool> m_descriptorPool;
2506 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
2507 Move<VkDescriptorSet> m_descriptorSet;
2508 de::MovePtr<Pipeline> m_pipeline;
2511 class CopyBufferSupport : public OperationSupport
2514 CopyBufferSupport (const ResourceDescription& resourceDesc,
2515 const BufferType bufferType,
2516 const VkShaderStageFlagBits stage,
2517 const DispatchCall dispatchCall = DISPATCH_CALL_DISPATCH)
2518 : m_resourceDesc (resourceDesc)
2519 , m_bufferType (bufferType)
2521 , m_shaderPrefix (std::string("copy_") + getShaderStageName(stage) + (m_bufferType == BUFFER_TYPE_UNIFORM ? "_ubo_" : "_ssbo_"))
2522 , m_dispatchCall (dispatchCall)
2524 DE_ASSERT(m_resourceDesc.type == RESOURCE_TYPE_BUFFER);
2525 DE_ASSERT(m_bufferType == BUFFER_TYPE_UNIFORM || m_bufferType == BUFFER_TYPE_STORAGE);
2526 DE_ASSERT(m_bufferType != BUFFER_TYPE_UNIFORM || m_resourceDesc.size.x() <= MAX_UBO_RANGE);
2527 DE_ASSERT(m_dispatchCall == DISPATCH_CALL_DISPATCH || m_dispatchCall == DISPATCH_CALL_DISPATCH_INDIRECT);
2529 assertValidShaderStage(m_stage);
2532 void initPrograms (SourceCollections& programCollection) const
2534 DE_ASSERT((m_resourceDesc.size.x() % sizeof(tcu::UVec4)) == 0);
2536 const std::string bufferTypeStr = (m_bufferType == BUFFER_TYPE_UNIFORM ? "uniform" : "buffer");
2537 const int numVecElements = static_cast<int>(m_resourceDesc.size.x() / sizeof(tcu::UVec4)); // std140 must be aligned to a multiple of 16
2539 std::ostringstream declSrc;
2540 declSrc << "layout(set = 0, binding = 0, std140) readonly " << bufferTypeStr << " Input {\n"
2541 << " uvec4 data[" << numVecElements << "];\n"
2544 << "layout(set = 0, binding = 1, std140) writeonly buffer Output {\n"
2545 << " uvec4 data[" << numVecElements << "];\n"
2548 std::ostringstream copySrc;
2549 copySrc << " for (int i = 0; i < " << numVecElements << "; ++i) {\n"
2550 << " b_out.data[i] = b_in.data[i];\n"
2553 initPassthroughPrograms(programCollection, m_shaderPrefix, declSrc.str(), copySrc.str(), m_stage);
2556 deUint32 getInResourceUsageFlags (void) const
2558 return (m_bufferType == BUFFER_TYPE_UNIFORM ? VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT : VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
2561 deUint32 getOutResourceUsageFlags (void) const
2563 return VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
2566 VkQueueFlags getQueueFlags (const OperationContext& context) const
2569 return (m_stage == VK_SHADER_STAGE_COMPUTE_BIT ? VK_QUEUE_COMPUTE_BIT : VK_QUEUE_GRAPHICS_BIT);
2572 de::MovePtr<Operation> build (OperationContext&, Resource&) const
2575 return de::MovePtr<Operation>();
2578 de::MovePtr<Operation> build (OperationContext& context, Resource& inResource, Resource& outResource) const
2580 if (m_stage & VK_SHADER_STAGE_COMPUTE_BIT)
2581 return de::MovePtr<Operation>(new BufferCopyImplementation(context, inResource, outResource, m_stage, m_bufferType, m_shaderPrefix, PIPELINE_TYPE_COMPUTE, m_dispatchCall));
2583 return de::MovePtr<Operation>(new BufferCopyImplementation(context, inResource, outResource, m_stage, m_bufferType, m_shaderPrefix, PIPELINE_TYPE_GRAPHICS, m_dispatchCall));
2587 const ResourceDescription m_resourceDesc;
2588 const BufferType m_bufferType;
2589 const VkShaderStageFlagBits m_stage;
2590 const std::string m_shaderPrefix;
2591 const DispatchCall m_dispatchCall;
2594 class CopyImageImplementation : public Operation
2597 CopyImageImplementation (OperationContext& context,
2598 Resource& inResource,
2599 Resource& outResource,
2600 const VkShaderStageFlagBits stage,
2601 const std::string& shaderPrefix,
2602 const PipelineType pipelineType,
2603 const DispatchCall dispatchCall)
2604 : m_context (context)
2605 , m_inResource (inResource)
2606 , m_outResource (outResource)
2608 , m_pipelineStage (pipelineStageFlagsFromShaderStageFlagBits(m_stage))
2609 , m_dispatchCall (dispatchCall)
2611 const DeviceInterface& vk = m_context.getDeviceInterface();
2612 const InstanceInterface& vki = m_context.getInstanceInterface();
2613 const VkDevice device = m_context.getDevice();
2614 const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
2616 // Image stores are always required, in either access mode.
2617 requireFeaturesForSSBOAccess(m_context, m_stage);
2619 // Some storage image formats may not be supported
2620 const auto& imgResource = m_inResource.getImage();
2621 requireStorageImageSupport(vki, physDevice, imgResource.format, imgResource.tiling);
2625 const VkImageViewType viewType = getImageViewType(m_inResource.getImage().imageType);
2627 m_srcImageView = makeImageView(vk, device, m_inResource.getImage().handle, viewType, m_inResource.getImage().format, m_inResource.getImage().subresourceRange);
2628 m_dstImageView = makeImageView(vk, device, m_outResource.getImage().handle, viewType, m_outResource.getImage().format, m_outResource.getImage().subresourceRange);
2631 // Prepare descriptors
2633 m_descriptorSetLayout = DescriptorSetLayoutBuilder()
2634 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, m_stage)
2635 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, m_stage)
2638 m_descriptorPool = DescriptorPoolBuilder()
2639 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
2640 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
2641 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
2643 m_descriptorSet = makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout);
2645 const VkDescriptorImageInfo srcImageInfo = makeDescriptorImageInfo(DE_NULL, *m_srcImageView, VK_IMAGE_LAYOUT_GENERAL);
2646 const VkDescriptorImageInfo dstImageInfo = makeDescriptorImageInfo(DE_NULL, *m_dstImageView, VK_IMAGE_LAYOUT_GENERAL);
2648 DescriptorSetUpdateBuilder()
2649 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &srcImageInfo)
2650 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &dstImageInfo)
2651 .update(vk, device);
2655 m_pipeline = (pipelineType == PIPELINE_TYPE_GRAPHICS ? de::MovePtr<Pipeline>(new GraphicsPipeline(context, stage, shaderPrefix, *m_descriptorSetLayout))
2656 : de::MovePtr<Pipeline>(new ComputePipeline(context, m_dispatchCall, shaderPrefix, *m_descriptorSetLayout)));
2659 void recordCommands (const VkCommandBuffer cmdBuffer)
2662 const DeviceInterface& vk = m_context.getDeviceInterface();
2663 SynchronizationWrapperPtr synchronizationWrapper = getSynchronizationWrapper(m_context.getSynchronizationType(), vk, DE_FALSE);
2665 const VkImageMemoryBarrier2KHR imageMemoryBarriers2 = makeImageMemoryBarrier2(
2666 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags2KHR srcStageMask
2667 (VkAccessFlags)0, // VkAccessFlags2KHR srcAccessMask
2668 m_pipelineStage, // VkPipelineStageFlags2KHR dstStageMask
2669 VK_ACCESS_2_SHADER_WRITE_BIT_KHR, // VkAccessFlags2KHR dstAccessMask
2670 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
2671 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout
2672 m_outResource.getImage().handle, // VkImage image
2673 m_outResource.getImage().subresourceRange // VkImageSubresourceRange subresourceRange
2675 VkDependencyInfoKHR dependencyInfo
2677 VK_STRUCTURE_TYPE_DEPENDENCY_INFO_KHR, // VkStructureType sType
2678 DE_NULL, // const void* pNext
2679 VK_DEPENDENCY_BY_REGION_BIT, // VkDependencyFlags dependencyFlags
2680 0u, // deUint32 memoryBarrierCount
2681 DE_NULL, // const VkMemoryBarrier2KHR* pMemoryBarriers
2682 0u, // deUint32 bufferMemoryBarrierCount
2683 DE_NULL, // const VkBufferMemoryBarrier2KHR* pBufferMemoryBarriers
2684 1, // deUint32 imageMemoryBarrierCount
2685 &imageMemoryBarriers2 // const VkImageMemoryBarrier2KHR* pImageMemoryBarriers
2687 synchronizationWrapper->cmdPipelineBarrier(cmdBuffer, &dependencyInfo);
2691 m_pipeline->recordCommands(m_context, cmdBuffer, *m_descriptorSet);
2694 SyncInfo getInSyncInfo (void) const
2696 const SyncInfo syncInfo =
2698 m_pipelineStage, // VkPipelineStageFlags stageMask;
2699 VK_ACCESS_2_SHADER_READ_BIT_KHR, // VkAccessFlags accessMask;
2700 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout;
2705 SyncInfo getOutSyncInfo (void) const
2707 const SyncInfo syncInfo =
2709 m_pipelineStage, // VkPipelineStageFlags stageMask;
2710 VK_ACCESS_2_SHADER_WRITE_BIT_KHR, // VkAccessFlags accessMask;
2711 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout;
2716 Data getData (void) const
2718 Data data = { 0, DE_NULL };
2722 void setData (const Data&)
2728 OperationContext& m_context;
2729 Resource& m_inResource;
2730 Resource& m_outResource;
2731 const VkShaderStageFlagBits m_stage;
2732 const VkPipelineStageFlags m_pipelineStage;
2733 const DispatchCall m_dispatchCall;
2734 Move<VkImageView> m_srcImageView;
2735 Move<VkImageView> m_dstImageView;
2736 Move<VkDescriptorPool> m_descriptorPool;
2737 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
2738 Move<VkDescriptorSet> m_descriptorSet;
2739 de::MovePtr<Pipeline> m_pipeline;
2742 class CopyImageSupport : public OperationSupport
2745 CopyImageSupport (const ResourceDescription& resourceDesc,
2746 const VkShaderStageFlagBits stage,
2747 const DispatchCall dispatchCall = DISPATCH_CALL_DISPATCH)
2748 : m_resourceDesc (resourceDesc)
2750 , m_shaderPrefix (std::string("copy_image_") + getShaderStageName(stage) + "_")
2751 , m_dispatchCall (dispatchCall)
2753 DE_ASSERT(m_resourceDesc.type == RESOURCE_TYPE_IMAGE);
2754 DE_ASSERT(m_dispatchCall == DISPATCH_CALL_DISPATCH || m_dispatchCall == DISPATCH_CALL_DISPATCH_INDIRECT);
2756 assertValidShaderStage(m_stage);
2759 void initPrograms (SourceCollections& programCollection) const
2761 const std::string imageFormat = getShaderImageFormatQualifier(m_resourceDesc.imageFormat);
2762 const std::string imageType = getShaderImageType(m_resourceDesc.imageFormat, m_resourceDesc.imageType);
2764 std::ostringstream declSrc;
2765 declSrc << "layout(set = 0, binding = 0, " << imageFormat << ") readonly uniform " << imageType << " srcImg;\n"
2766 << "layout(set = 0, binding = 1, " << imageFormat << ") writeonly uniform " << imageType << " dstImg;\n";
2768 std::ostringstream mainSrc;
2769 if (m_resourceDesc.imageType == VK_IMAGE_TYPE_1D)
2770 mainSrc << " for (int x = 0; x < " << m_resourceDesc.size.x() << "; ++x)\n"
2771 << " imageStore(dstImg, x, imageLoad(srcImg, x));\n";
2772 else if (m_resourceDesc.imageType == VK_IMAGE_TYPE_2D)
2773 mainSrc << " for (int y = 0; y < " << m_resourceDesc.size.y() << "; ++y)\n"
2774 << " for (int x = 0; x < " << m_resourceDesc.size.x() << "; ++x)\n"
2775 << " imageStore(dstImg, ivec2(x, y), imageLoad(srcImg, ivec2(x, y)));\n";
2776 else if (m_resourceDesc.imageType == VK_IMAGE_TYPE_3D)
2777 mainSrc << " for (int z = 0; z < " << m_resourceDesc.size.z() << "; ++z)\n"
2778 << " for (int y = 0; y < " << m_resourceDesc.size.y() << "; ++y)\n"
2779 << " for (int x = 0; x < " << m_resourceDesc.size.x() << "; ++x)\n"
2780 << " imageStore(dstImg, ivec3(x, y, z), imageLoad(srcImg, ivec3(x, y, z)));\n";
2784 initPassthroughPrograms(programCollection, m_shaderPrefix, declSrc.str(), mainSrc.str(), m_stage);
2787 deUint32 getInResourceUsageFlags (void) const
2789 return VK_IMAGE_USAGE_STORAGE_BIT;
2792 deUint32 getOutResourceUsageFlags (void) const
2794 return VK_IMAGE_USAGE_STORAGE_BIT;
2797 VkQueueFlags getQueueFlags (const OperationContext& context) const
2800 return (m_stage == VK_SHADER_STAGE_COMPUTE_BIT ? VK_QUEUE_COMPUTE_BIT : VK_QUEUE_GRAPHICS_BIT);
2803 de::MovePtr<Operation> build (OperationContext&, Resource&) const
2806 return de::MovePtr<Operation>();
2809 de::MovePtr<Operation> build (OperationContext& context, Resource& inResource, Resource& outResource) const
2811 if (m_stage & VK_SHADER_STAGE_COMPUTE_BIT)
2812 return de::MovePtr<Operation>(new CopyImageImplementation(context, inResource, outResource, m_stage, m_shaderPrefix, PIPELINE_TYPE_COMPUTE, m_dispatchCall));
2814 return de::MovePtr<Operation>(new CopyImageImplementation(context, inResource, outResource, m_stage, m_shaderPrefix, PIPELINE_TYPE_GRAPHICS, m_dispatchCall));
2818 const ResourceDescription m_resourceDesc;
2819 const VkShaderStageFlagBits m_stage;
2820 const std::string m_shaderPrefix;
2821 const DispatchCall m_dispatchCall;
2824 class MSImageImplementation : public Operation
2827 MSImageImplementation(OperationContext& context,
2829 : m_context (context)
2830 , m_resource (resource)
2831 , m_hostBufferSizeBytes(getPixelBufferSize(m_resource.getImage().format, m_resource.getImage().extent))
2833 const DeviceInterface& vk = m_context.getDeviceInterface();
2834 const InstanceInterface& vki = m_context.getInstanceInterface();
2835 const VkDevice device = m_context.getDevice();
2836 const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
2837 const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
2838 Allocator& allocator = m_context.getAllocator();
2840 const auto& imgResource = m_resource.getImage();
2841 requireStorageImageSupport(vki, physDevice, imgResource.format, imgResource.tiling);
2842 if (!features.shaderStorageImageMultisample)
2843 TCU_THROW(NotSupportedError, "Using multisample images as storage is not supported");
2845 VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(m_hostBufferSizeBytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
2846 m_hostBuffer = de::MovePtr<Buffer>(new Buffer(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible));
2847 const Allocation& alloc = m_hostBuffer->getAllocation();
2848 fillPattern(alloc.getHostPtr(), m_hostBufferSizeBytes);
2849 flushAlloc(vk, device, alloc);
2851 const ImageResource& image = m_resource.getImage();
2852 const VkImageViewType viewType = getImageViewType(image.imageType);
2853 m_imageView = makeImageView(vk, device, image.handle, viewType, image.format, image.subresourceRange);
2855 // Prepare descriptors
2857 m_descriptorSetLayout = DescriptorSetLayoutBuilder()
2858 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
2859 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
2862 m_descriptorPool = DescriptorPoolBuilder()
2863 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
2864 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
2865 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
2867 m_descriptorSet = makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout);
2869 const VkDescriptorBufferInfo bufferInfo = makeDescriptorBufferInfo(**m_hostBuffer, 0u, m_hostBufferSizeBytes);
2870 const VkDescriptorImageInfo imageInfo = makeDescriptorImageInfo(DE_NULL, *m_imageView, VK_IMAGE_LAYOUT_GENERAL);
2872 DescriptorSetUpdateBuilder()
2873 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufferInfo)
2874 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &imageInfo)
2875 .update(vk, device);
2879 const Unique<VkShaderModule> shaderModule(createShaderModule(vk, device, context.getBinaryCollection().get("comp"), (VkShaderModuleCreateFlags)0));
2880 m_pipelineLayout = makePipelineLayout (vk, device, *m_descriptorSetLayout);
2881 m_pipeline = makeComputePipeline(vk, device, *m_pipelineLayout, *shaderModule, DE_NULL, context.getPipelineCacheData());
2884 void recordCommands(const VkCommandBuffer cmdBuffer)
2886 const DeviceInterface& vk = m_context.getDeviceInterface();
2887 SynchronizationWrapperPtr synchronizationWrapper = getSynchronizationWrapper(m_context.getSynchronizationType(), vk, DE_FALSE);
2889 // change image layout
2891 const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
2892 VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR, // VkPipelineStageFlags2KHR srcStageMask
2893 (VkAccessFlags)0, // VkAccessFlags2KHR srcAccessMask
2894 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT_KHR, // VkPipelineStageFlags2KHR dstStageMask
2895 VK_ACCESS_2_SHADER_WRITE_BIT_KHR, // VkAccessFlags2KHR dstAccessMask
2896 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
2897 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout
2898 m_resource.getImage().handle, // VkImage image
2899 m_resource.getImage().subresourceRange // VkImageSubresourceRange subresourceRange
2901 VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
2902 synchronizationWrapper->cmdPipelineBarrier(cmdBuffer, &dependencyInfo);
2906 vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipeline);
2907 vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0u, 1u, &*m_descriptorSet, 0u, DE_NULL);
2908 vk.cmdDispatch(cmdBuffer, m_resource.getImage().extent.width, m_resource.getImage().extent.height, 1u);
2911 SyncInfo getInSyncInfo(void) const
2914 return emptySyncInfo;
2917 SyncInfo getOutSyncInfo(void) const
2921 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT_KHR, // VkPipelineStageFlags stageMask;
2922 VK_ACCESS_2_SHADER_WRITE_BIT_KHR, // VkAccessFlags accessMask;
2923 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout;
2927 Data getData(void) const
2929 return getHostBufferData(m_context, *m_hostBuffer, m_hostBufferSizeBytes);
2932 void setData(const Data&)
2938 OperationContext& m_context;
2939 Resource& m_resource;
2940 Move<VkImageView> m_imageView;
2942 const VkDeviceSize m_hostBufferSizeBytes;
2943 de::MovePtr<Buffer> m_hostBuffer;
2945 Move<VkDescriptorPool> m_descriptorPool;
2946 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
2947 Move<VkDescriptorSet> m_descriptorSet;
2948 Move<VkPipelineLayout> m_pipelineLayout;
2949 Move<VkPipeline> m_pipeline;
2952 class MSImageSupport : public OperationSupport
2955 MSImageSupport(const ResourceDescription& resourceDesc)
2956 : m_resourceDesc (resourceDesc)
2958 DE_ASSERT(m_resourceDesc.type == RESOURCE_TYPE_IMAGE);
2961 void initPrograms (SourceCollections& programCollection) const
2963 std::stringstream source;
2967 "layout(local_size_x = 1) in;\n"
2968 "layout(set = 0, binding = 0, std430) readonly buffer Input {\n"
2971 "layout(set = 0, binding = 1, r32ui) writeonly uniform uimage2DMS msImage;\n"
2973 "void main (void)\n"
2975 " int gx = int(gl_GlobalInvocationID.x);\n"
2976 " int gy = int(gl_GlobalInvocationID.y);\n"
2977 " uint value = inData.data[gy * " << m_resourceDesc.size.x() << " + gx];\n"
2978 " for (int sampleNdx = 0; sampleNdx < " << m_resourceDesc.imageSamples << "; ++sampleNdx)\n"
2979 " imageStore(msImage, ivec2(gx, gy), sampleNdx, uvec4(value));\n"
2981 programCollection.glslSources.add("comp") << glu::ComputeSource(source.str().c_str());
2984 deUint32 getInResourceUsageFlags (void) const
2989 deUint32 getOutResourceUsageFlags (void) const
2991 return VK_IMAGE_USAGE_STORAGE_BIT;
2994 VkQueueFlags getQueueFlags (const OperationContext&) const
2996 return VK_QUEUE_COMPUTE_BIT;
2999 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
3001 return de::MovePtr<Operation>(new MSImageImplementation(context, resource));
3004 de::MovePtr<Operation> build (OperationContext&, Resource&, Resource&) const
3007 return de::MovePtr<Operation>();
3011 const ResourceDescription m_resourceDesc;
3014 } // ShaderAccess ns
3016 namespace CopyBufferToImage
3019 class WriteImplementation : public Operation
3022 WriteImplementation (OperationContext& context, Resource& resource)
3023 : m_context (context)
3024 , m_resource (resource)
3025 , m_bufferSize (getPixelBufferSize(m_resource.getImage().format, m_resource.getImage().extent))
3027 DE_ASSERT(m_resource.getType() == RESOURCE_TYPE_IMAGE);
3029 const DeviceInterface& vk = m_context.getDeviceInterface();
3030 const VkDevice device = m_context.getDevice();
3031 Allocator& allocator = m_context.getAllocator();
3033 m_hostBuffer = de::MovePtr<Buffer>(new Buffer(
3034 vk, device, allocator, makeBufferCreateInfo(m_bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT), MemoryRequirement::HostVisible));
3036 const Allocation& alloc = m_hostBuffer->getAllocation();
3037 fillPattern(alloc.getHostPtr(), m_bufferSize);
3038 flushAlloc(vk, device, alloc);
3041 void recordCommands (const VkCommandBuffer cmdBuffer)
3043 const DeviceInterface& vk = m_context.getDeviceInterface();
3044 const VkBufferImageCopy copyRegion = makeBufferImageCopy(m_resource.getImage().extent, m_resource.getImage().subresourceLayers);
3045 SynchronizationWrapperPtr synchronizationWrapper = getSynchronizationWrapper(m_context.getSynchronizationType(), vk, DE_FALSE);
3047 const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
3048 VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR, // VkPipelineStageFlags2KHR srcStageMask
3049 (VkAccessFlags)0, // VkAccessFlags2KHR srcAccessMask
3050 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags2KHR dstStageMask
3051 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR, // VkAccessFlags2KHR dstAccessMask
3052 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
3053 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout
3054 m_resource.getImage().handle, // VkImage image
3055 m_resource.getImage().subresourceRange // VkImageSubresourceRange subresourceRange
3057 VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
3058 synchronizationWrapper->cmdPipelineBarrier(cmdBuffer, &dependencyInfo);
3060 vk.cmdCopyBufferToImage(cmdBuffer, **m_hostBuffer, m_resource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ©Region);
3063 SyncInfo getInSyncInfo (void) const
3065 return emptySyncInfo;
3068 SyncInfo getOutSyncInfo (void) const
3070 const SyncInfo syncInfo =
3072 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags stageMask;
3073 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR, // VkAccessFlags accessMask;
3074 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout imageLayout;
3079 Data getData (void) const
3081 return getHostBufferData(m_context, *m_hostBuffer, m_bufferSize);
3084 void setData (const Data& data)
3086 setHostBufferData(m_context, *m_hostBuffer, data);
3090 OperationContext& m_context;
3091 Resource& m_resource;
3092 de::MovePtr<Buffer> m_hostBuffer;
3093 const VkDeviceSize m_bufferSize;
3096 class ReadImplementation : public Operation
3099 ReadImplementation (OperationContext& context, Resource& resource)
3100 : m_context (context)
3101 , m_resource (resource)
3102 , m_subresourceRange (makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u))
3103 , m_subresourceLayers (makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u))
3105 DE_ASSERT(m_resource.getType() == RESOURCE_TYPE_BUFFER);
3107 const DeviceInterface& vk = m_context.getDeviceInterface();
3108 const VkDevice device = m_context.getDevice();
3109 Allocator& allocator = m_context.getAllocator();
3110 const VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
3111 const deUint32 pixelSize = tcu::getPixelSize(mapVkFormat(format));
3113 DE_ASSERT((m_resource.getBuffer().size % pixelSize) == 0);
3114 m_imageExtent = get2DImageExtentWithSize(m_resource.getBuffer().size, pixelSize); // there may be some unused space at the end
3116 // Copy destination image.
3117 m_image = de::MovePtr<Image>(new Image(
3118 vk, device, allocator,
3119 makeImageCreateInfo(VK_IMAGE_TYPE_2D, m_imageExtent, format,
3120 (VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT),
3121 VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL),
3122 MemoryRequirement::Any));
3124 // Image data will be copied here, so it can be read on the host.
3125 m_hostBuffer = de::MovePtr<Buffer>(new Buffer(
3126 vk, device, allocator, makeBufferCreateInfo(m_resource.getBuffer().size, VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible));
3129 void recordCommands (const VkCommandBuffer cmdBuffer)
3131 const DeviceInterface& vk = m_context.getDeviceInterface();
3132 const VkBufferImageCopy copyRegion = makeBufferImageCopy(m_imageExtent, m_subresourceLayers);
3133 SynchronizationWrapperPtr synchronizationWrapper = getSynchronizationWrapper(m_context.getSynchronizationType(), vk, DE_FALSE);
3135 // Resource -> Image
3137 const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
3138 VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR, // VkPipelineStageFlags2KHR srcStageMask
3139 (VkAccessFlags)0, // VkAccessFlags2KHR srcAccessMask
3140 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags2KHR dstStageMask
3141 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR, // VkAccessFlags2KHR dstAccessMask
3142 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
3143 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout
3144 **m_image, // VkImage image
3145 m_subresourceRange // VkImageSubresourceRange subresourceRange
3147 VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
3148 synchronizationWrapper->cmdPipelineBarrier(cmdBuffer, &dependencyInfo);
3150 vk.cmdCopyBufferToImage(cmdBuffer, m_resource.getBuffer().handle, **m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ©Region);
3152 // Image -> Host buffer
3154 const VkImageMemoryBarrier2KHR imageLayoutBarrier2 = makeImageMemoryBarrier2(
3155 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags2KHR srcStageMask
3156 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR, // VkAccessFlags2KHR srcAccessMask
3157 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags2KHR dstStageMask
3158 VK_ACCESS_2_TRANSFER_READ_BIT_KHR, // VkAccessFlags2KHR dstAccessMask
3159 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout
3160 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout
3161 **m_image, // VkImage image
3162 m_subresourceRange // VkImageSubresourceRange subresourceRange
3164 VkDependencyInfoKHR layoutDependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageLayoutBarrier2);
3165 synchronizationWrapper->cmdPipelineBarrier(cmdBuffer, &layoutDependencyInfo);
3167 vk.cmdCopyImageToBuffer(cmdBuffer, **m_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_hostBuffer, 1u, ©Region);
3169 const VkBufferMemoryBarrier2KHR bufferMemoryBarrier2 = makeBufferMemoryBarrier2(
3170 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags2KHR srcStageMask
3171 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR, // VkAccessFlags2KHR srcAccessMask
3172 VK_PIPELINE_STAGE_2_HOST_BIT_KHR, // VkPipelineStageFlags2KHR dstStageMask
3173 VK_ACCESS_2_HOST_READ_BIT_KHR, // VkAccessFlags2KHR dstAccessMask
3174 **m_hostBuffer, // VkBuffer buffer
3175 0u, // VkDeviceSize offset
3176 m_resource.getBuffer().size // VkDeviceSize size
3178 VkDependencyInfoKHR bufferDependencyInfo = makeCommonDependencyInfo(DE_NULL, &bufferMemoryBarrier2);
3179 synchronizationWrapper->cmdPipelineBarrier(cmdBuffer, &bufferDependencyInfo);
3183 SyncInfo getInSyncInfo (void) const
3185 const SyncInfo syncInfo =
3187 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags stageMask;
3188 VK_ACCESS_2_TRANSFER_READ_BIT_KHR, // VkAccessFlags accessMask;
3189 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
3194 SyncInfo getOutSyncInfo (void) const
3196 return emptySyncInfo;
3199 Data getData (void) const
3201 return getHostBufferData(m_context, *m_hostBuffer, m_resource.getBuffer().size);
3204 void setData (const Data& data)
3206 setHostBufferData(m_context, *m_hostBuffer, data);
3210 OperationContext& m_context;
3211 Resource& m_resource;
3212 const VkImageSubresourceRange m_subresourceRange;
3213 const VkImageSubresourceLayers m_subresourceLayers;
3214 de::MovePtr<Buffer> m_hostBuffer;
3215 de::MovePtr<Image> m_image;
3216 VkExtent3D m_imageExtent;
3219 class Support : public OperationSupport
3222 Support (const ResourceDescription& resourceDesc, const AccessMode mode)
3224 , m_resourceType (resourceDesc.type)
3225 , m_requiredQueueFlags (resourceDesc.type == RESOURCE_TYPE_IMAGE && isDepthStencilFormat(resourceDesc.imageFormat) ? VK_QUEUE_GRAPHICS_BIT : VK_QUEUE_TRANSFER_BIT)
3228 // Because depth or stencil aspect buffer to image copies may require format conversions on some implementations,
3229 // they are not supported on queues that do not support graphics.
3231 DE_ASSERT(m_mode == ACCESS_MODE_READ || m_mode == ACCESS_MODE_WRITE);
3232 DE_ASSERT(m_mode == ACCESS_MODE_READ || resourceDesc.type != RESOURCE_TYPE_BUFFER);
3233 DE_ASSERT(m_mode == ACCESS_MODE_WRITE || resourceDesc.type != RESOURCE_TYPE_IMAGE);
3236 deUint32 getInResourceUsageFlags (void) const
3238 if (m_resourceType == RESOURCE_TYPE_IMAGE)
3239 return m_mode == ACCESS_MODE_READ ? VK_IMAGE_USAGE_TRANSFER_SRC_BIT : 0;
3241 return m_mode == ACCESS_MODE_READ ? VK_BUFFER_USAGE_TRANSFER_SRC_BIT : 0;
3244 deUint32 getOutResourceUsageFlags (void) const
3246 if (m_resourceType == RESOURCE_TYPE_IMAGE)
3247 return m_mode == ACCESS_MODE_WRITE ? VK_IMAGE_USAGE_TRANSFER_DST_BIT : 0;
3249 return m_mode == ACCESS_MODE_WRITE ? VK_BUFFER_USAGE_TRANSFER_DST_BIT : 0;
3252 VkQueueFlags getQueueFlags (const OperationContext& context) const
3255 return m_requiredQueueFlags;
3258 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
3260 if (m_mode == ACCESS_MODE_READ)
3261 return de::MovePtr<Operation>(new ReadImplementation(context, resource));
3263 return de::MovePtr<Operation>(new WriteImplementation(context, resource));
3266 de::MovePtr<Operation> build (OperationContext&, Resource&, Resource&) const
3269 return de::MovePtr<Operation>();
3273 const AccessMode m_mode;
3274 const enum ResourceType m_resourceType;
3275 const VkQueueFlags m_requiredQueueFlags;
3278 class CopyImplementation : public Operation
3281 CopyImplementation (OperationContext& context, Resource& inResource, Resource& outResource)
3282 : m_context (context)
3283 , m_inResource (inResource)
3284 , m_outResource (outResource)
3286 DE_ASSERT(m_inResource.getType() == RESOURCE_TYPE_BUFFER);
3287 DE_ASSERT(m_outResource.getType() == RESOURCE_TYPE_IMAGE);
3290 void recordCommands (const VkCommandBuffer cmdBuffer)
3292 const DeviceInterface& vk = m_context.getDeviceInterface();
3293 const VkBufferImageCopy copyRegion = makeBufferImageCopy(m_outResource.getImage().extent, m_outResource.getImage().subresourceLayers);
3294 SynchronizationWrapperPtr synchronizationWrapper = getSynchronizationWrapper(m_context.getSynchronizationType(), vk, DE_FALSE);
3296 const VkBufferMemoryBarrier2KHR bufferMemoryBarrier2 = makeBufferMemoryBarrier2(
3297 VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR, // VkPipelineStageFlags2KHR srcStageMask
3298 (VkAccessFlags)0, // VkAccessFlags2KHR srcAccessMask
3299 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags2KHR dstStageMask
3300 VK_ACCESS_2_TRANSFER_READ_BIT_KHR, // VkAccessFlags2KHR dstAccessMask
3301 m_inResource.getBuffer().handle, // VkBuffer buffer
3302 0u, // VkDeviceSize offset
3303 m_inResource.getBuffer().size // VkDeviceSize size
3305 const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
3306 VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR, // VkPipelineStageFlags2KHR srcStageMask
3307 (VkAccessFlags)0, // VkAccessFlags2KHR srcAccessMask
3308 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags2KHR dstStageMask
3309 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR, // VkAccessFlags2KHR dstAccessMask
3310 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
3311 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout
3312 m_outResource.getImage().handle, // VkImage image
3313 m_outResource.getImage().subresourceRange // VkImageSubresourceRange subresourceRange
3315 VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, &bufferMemoryBarrier2, &imageMemoryBarrier2);
3316 synchronizationWrapper->cmdPipelineBarrier(cmdBuffer, &dependencyInfo);
3318 vk.cmdCopyBufferToImage(cmdBuffer, m_inResource.getBuffer().handle, m_outResource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ©Region);
3321 SyncInfo getInSyncInfo (void) const
3323 const SyncInfo syncInfo =
3325 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags stageMask;
3326 VK_ACCESS_2_TRANSFER_READ_BIT_KHR, // VkAccessFlags accessMask;
3327 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout imageLayout;
3332 SyncInfo getOutSyncInfo (void) const
3334 const SyncInfo syncInfo =
3336 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags stageMask;
3337 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR, // VkAccessFlags accessMask;
3338 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout imageLayout;
3343 Data getData (void) const
3345 Data data = { 0, DE_NULL };
3349 void setData (const Data&)
3355 OperationContext& m_context;
3356 Resource& m_inResource;
3357 Resource& m_outResource;
3360 class CopySupport : public OperationSupport
3363 CopySupport (const ResourceDescription& resourceDesc)
3364 : m_resourceType (resourceDesc.type)
3365 , m_requiredQueueFlags (resourceDesc.type == RESOURCE_TYPE_IMAGE && isDepthStencilFormat(resourceDesc.imageFormat) ? VK_QUEUE_GRAPHICS_BIT : VK_QUEUE_TRANSFER_BIT)
3369 deUint32 getInResourceUsageFlags (void) const
3371 if (m_resourceType == RESOURCE_TYPE_IMAGE)
3372 return VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3374 return VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
3377 deUint32 getOutResourceUsageFlags (void) const
3379 if (m_resourceType == RESOURCE_TYPE_IMAGE)
3380 return VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3382 return VK_BUFFER_USAGE_TRANSFER_DST_BIT;
3385 VkQueueFlags getQueueFlags (const OperationContext& context) const
3388 return m_requiredQueueFlags;
3391 de::MovePtr<Operation> build (OperationContext&, Resource&) const
3394 return de::MovePtr<Operation>();
3397 de::MovePtr<Operation> build (OperationContext& context, Resource& inResource, Resource& outResource) const
3399 return de::MovePtr<Operation>(new CopyImplementation(context, inResource, outResource));
3403 const enum ResourceType m_resourceType;
3404 const VkQueueFlags m_requiredQueueFlags;
3407 } // CopyBufferToImage ns
3409 namespace CopyImageToBuffer
3412 class WriteImplementation : public Operation
3415 WriteImplementation (OperationContext& context, Resource& resource)
3416 : m_context (context)
3417 , m_resource (resource)
3418 , m_subresourceRange (makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u))
3419 , m_subresourceLayers (makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u))
3421 DE_ASSERT(m_resource.getType() == RESOURCE_TYPE_BUFFER);
3423 const DeviceInterface& vk = m_context.getDeviceInterface();
3424 const VkDevice device = m_context.getDevice();
3425 Allocator& allocator = m_context.getAllocator();
3426 const VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
3427 const deUint32 pixelSize = tcu::getPixelSize(mapVkFormat(format));
3429 DE_ASSERT((m_resource.getBuffer().size % pixelSize) == 0);
3430 m_imageExtent = get2DImageExtentWithSize(m_resource.getBuffer().size, pixelSize);
3432 // Source data staging buffer
3433 m_hostBuffer = de::MovePtr<Buffer>(new Buffer(
3434 vk, device, allocator, makeBufferCreateInfo(m_resource.getBuffer().size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT), MemoryRequirement::HostVisible));
3436 const Allocation& alloc = m_hostBuffer->getAllocation();
3437 fillPattern(alloc.getHostPtr(), m_resource.getBuffer().size);
3438 flushAlloc(vk, device, alloc);
3440 // Source data image
3441 m_image = de::MovePtr<Image>(new Image(
3442 vk, device, allocator,
3443 makeImageCreateInfo(VK_IMAGE_TYPE_2D, m_imageExtent, format, (VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT),
3444 VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL),
3445 MemoryRequirement::Any));
3448 void recordCommands (const VkCommandBuffer cmdBuffer)
3450 const DeviceInterface& vk = m_context.getDeviceInterface();
3451 const VkBufferImageCopy copyRegion = makeBufferImageCopy(m_imageExtent, m_subresourceLayers);
3452 SynchronizationWrapperPtr synchronizationWrapper = getSynchronizationWrapper(m_context.getSynchronizationType(), vk, DE_FALSE);
3454 // Host buffer -> Image
3456 const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
3457 VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR, // VkPipelineStageFlags2KHR srcStageMask
3458 (VkAccessFlags)0, // VkAccessFlags2KHR srcAccessMask
3459 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags2KHR dstStageMask
3460 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR, // VkAccessFlags2KHR dstAccessMask
3461 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
3462 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout
3463 **m_image, // VkImage image
3464 m_subresourceRange // VkImageSubresourceRange subresourceRange
3466 VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
3467 synchronizationWrapper->cmdPipelineBarrier(cmdBuffer, &dependencyInfo);
3469 vk.cmdCopyBufferToImage(cmdBuffer, **m_hostBuffer, **m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ©Region);
3471 // Image -> Resource
3473 const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
3474 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags2KHR srcStageMask
3475 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR, // VkAccessFlags2KHR srcAccessMask
3476 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags2KHR dstStageMask
3477 VK_ACCESS_2_TRANSFER_READ_BIT_KHR, // VkAccessFlags2KHR dstAccessMask
3478 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout
3479 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout
3480 **m_image, // VkImage image
3481 m_subresourceRange // VkImageSubresourceRange subresourceRange
3483 VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
3484 synchronizationWrapper->cmdPipelineBarrier(cmdBuffer, &dependencyInfo);
3486 vk.cmdCopyImageToBuffer(cmdBuffer, **m_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_resource.getBuffer().handle, 1u, ©Region);
3490 SyncInfo getInSyncInfo (void) const
3492 return emptySyncInfo;
3495 SyncInfo getOutSyncInfo (void) const
3497 const SyncInfo syncInfo =
3499 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags stageMask;
3500 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR, // VkAccessFlags accessMask;
3501 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
3506 Data getData (void) const
3508 return getHostBufferData(m_context, *m_hostBuffer, m_resource.getBuffer().size);
3511 void setData (const Data& data)
3513 setHostBufferData(m_context, *m_hostBuffer, data);
3517 OperationContext& m_context;
3518 Resource& m_resource;
3519 const VkImageSubresourceRange m_subresourceRange;
3520 const VkImageSubresourceLayers m_subresourceLayers;
3521 de::MovePtr<Buffer> m_hostBuffer;
3522 de::MovePtr<Image> m_image;
3523 VkExtent3D m_imageExtent;
3526 class ReadImplementation : public Operation
3529 ReadImplementation (OperationContext& context, Resource& resource)
3530 : m_context (context)
3531 , m_resource (resource)
3532 , m_bufferSize (getPixelBufferSize(m_resource.getImage().format, m_resource.getImage().extent))
3534 DE_ASSERT(m_resource.getType() == RESOURCE_TYPE_IMAGE);
3536 const DeviceInterface& vk = m_context.getDeviceInterface();
3537 const VkDevice device = m_context.getDevice();
3538 Allocator& allocator = m_context.getAllocator();
3540 m_hostBuffer = de::MovePtr<Buffer>(new Buffer(
3541 vk, device, allocator, makeBufferCreateInfo(m_bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible));
3543 const Allocation& alloc = m_hostBuffer->getAllocation();
3544 deMemset(alloc.getHostPtr(), 0, static_cast<size_t>(m_bufferSize));
3545 flushAlloc(vk, device, alloc);
3548 void recordCommands (const VkCommandBuffer cmdBuffer)
3550 const DeviceInterface& vk = m_context.getDeviceInterface();
3551 const VkBufferImageCopy copyRegion = makeBufferImageCopy(m_resource.getImage().extent, m_resource.getImage().subresourceLayers);
3552 SynchronizationWrapperPtr synchronizationWrapper = getSynchronizationWrapper(m_context.getSynchronizationType(), vk, DE_FALSE);
3554 vk.cmdCopyImageToBuffer(cmdBuffer, m_resource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_hostBuffer, 1u, ©Region);
3556 // Insert a barrier so data written by the transfer is available to the host
3558 const VkBufferMemoryBarrier2KHR bufferMemoryBarrier2 = makeBufferMemoryBarrier2(
3559 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags2KHR srcStageMask
3560 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR, // VkAccessFlags2KHR srcAccessMask
3561 VK_PIPELINE_STAGE_2_HOST_BIT_KHR, // VkPipelineStageFlags2KHR dstStageMask
3562 VK_ACCESS_2_HOST_READ_BIT_KHR, // VkAccessFlags2KHR dstAccessMask
3563 **m_hostBuffer, // VkBuffer buffer
3564 0u, // VkDeviceSize offset
3565 VK_WHOLE_SIZE // VkDeviceSize size
3567 VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, &bufferMemoryBarrier2);
3568 synchronizationWrapper->cmdPipelineBarrier(cmdBuffer, &dependencyInfo);
3572 SyncInfo getInSyncInfo (void) const
3574 const SyncInfo syncInfo =
3576 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags stageMask;
3577 VK_ACCESS_2_TRANSFER_READ_BIT_KHR, // VkAccessFlags accessMask;
3578 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout imageLayout;
3583 SyncInfo getOutSyncInfo (void) const
3585 return emptySyncInfo;
3588 Data getData (void) const
3590 return getHostBufferData(m_context, *m_hostBuffer, m_bufferSize);
3593 void setData (const Data&)
3599 OperationContext& m_context;
3600 Resource& m_resource;
3601 de::MovePtr<Buffer> m_hostBuffer;
3602 const VkDeviceSize m_bufferSize;
3605 class CopyImplementation : public Operation
3608 CopyImplementation (OperationContext& context, Resource& inResource, Resource& outResource)
3609 : m_context (context)
3610 , m_inResource (inResource)
3611 , m_outResource (outResource)
3612 , m_subresourceRange (makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u))
3613 , m_subresourceLayers (makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u))
3615 DE_ASSERT(m_inResource.getType() == RESOURCE_TYPE_IMAGE);
3616 DE_ASSERT(m_outResource.getType() == RESOURCE_TYPE_BUFFER);
3619 void recordCommands (const VkCommandBuffer cmdBuffer)
3621 const DeviceInterface& vk = m_context.getDeviceInterface();
3622 const VkBufferImageCopy copyRegion = makeBufferImageCopy(m_inResource.getImage().extent, m_subresourceLayers);
3623 SynchronizationWrapperPtr synchronizationWrapper = getSynchronizationWrapper(m_context.getSynchronizationType(), vk, DE_FALSE);
3626 const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
3627 VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR, // VkPipelineStageFlags2KHR srcStageMask
3628 (VkAccessFlags)0, // VkAccessFlags2KHR srcAccessMask
3629 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags2KHR dstStageMask
3630 VK_ACCESS_2_TRANSFER_READ_BIT_KHR, // VkAccessFlags2KHR dstAccessMask
3631 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
3632 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout
3633 m_inResource.getImage().handle, // VkImage image
3634 m_inResource.getImage().subresourceRange // VkImageSubresourceRange subresourceRange
3636 const VkBufferMemoryBarrier2KHR bufferMemoryBarrier2 = makeBufferMemoryBarrier2(
3637 VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR, // VkPipelineStageFlags2KHR srcStageMask
3638 (VkAccessFlags)0, // VkAccessFlags2KHR srcAccessMask
3639 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags2KHR dstStageMask
3640 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR, // VkAccessFlags2KHR dstAccessMask
3641 m_outResource.getBuffer().handle, // VkBuffer buffer
3642 0u, // VkDeviceSize offset
3643 m_outResource.getBuffer().size // VkDeviceSize size
3645 VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, &bufferMemoryBarrier2, &imageMemoryBarrier2);
3646 synchronizationWrapper->cmdPipelineBarrier(cmdBuffer, &dependencyInfo);
3649 vk.cmdCopyImageToBuffer(cmdBuffer, m_inResource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_outResource.getBuffer().handle, 1u, ©Region);
3652 SyncInfo getInSyncInfo (void) const
3654 const SyncInfo syncInfo =
3656 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags stageMask;
3657 VK_ACCESS_2_TRANSFER_READ_BIT_KHR, // VkAccessFlags accessMask;
3658 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
3663 SyncInfo getOutSyncInfo (void) const
3665 const SyncInfo syncInfo =
3667 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags stageMask;
3668 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR, // VkAccessFlags accessMask;
3669 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
3674 Data getData (void) const
3676 Data data = { 0, DE_NULL };
3680 void setData (const Data&)
3686 OperationContext& m_context;
3687 Resource& m_inResource;
3688 Resource& m_outResource;
3689 const VkImageSubresourceRange m_subresourceRange;
3690 const VkImageSubresourceLayers m_subresourceLayers;
3693 class Support : public OperationSupport
3696 Support (const ResourceDescription& resourceDesc, const AccessMode mode)
3698 , m_requiredQueueFlags (resourceDesc.type == RESOURCE_TYPE_IMAGE && isDepthStencilFormat(resourceDesc.imageFormat) ? VK_QUEUE_GRAPHICS_BIT : VK_QUEUE_TRANSFER_BIT)
3700 DE_ASSERT(m_mode == ACCESS_MODE_READ || m_mode == ACCESS_MODE_WRITE);
3701 DE_ASSERT(m_mode == ACCESS_MODE_READ || resourceDesc.type != RESOURCE_TYPE_IMAGE);
3702 DE_ASSERT(m_mode == ACCESS_MODE_WRITE || resourceDesc.type != RESOURCE_TYPE_BUFFER);
3705 deUint32 getInResourceUsageFlags (void) const
3707 return m_mode == ACCESS_MODE_READ ? VK_BUFFER_USAGE_TRANSFER_SRC_BIT : 0;
3710 deUint32 getOutResourceUsageFlags (void) const
3712 return m_mode == ACCESS_MODE_WRITE ? VK_BUFFER_USAGE_TRANSFER_DST_BIT : 0;
3715 VkQueueFlags getQueueFlags (const OperationContext& context) const
3718 return m_requiredQueueFlags;
3721 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
3723 if (m_mode == ACCESS_MODE_READ)
3724 return de::MovePtr<Operation>(new ReadImplementation(context, resource));
3726 return de::MovePtr<Operation>(new WriteImplementation(context, resource));
3729 de::MovePtr<Operation> build (OperationContext&, Resource&, Resource&) const
3732 return de::MovePtr<Operation>();
3736 const AccessMode m_mode;
3737 const VkQueueFlags m_requiredQueueFlags;
3740 } // CopyImageToBuffer ns
3742 namespace ClearImage
3748 CLEAR_MODE_DEPTH_STENCIL,
3751 class Implementation : public Operation
3754 Implementation (OperationContext& context, Resource& resource, const ClearMode mode)
3755 : m_context (context)
3756 , m_resource (resource)
3757 , m_clearValue (makeClearValue(m_resource.getImage().format))
3760 const VkDeviceSize size = getPixelBufferSize(m_resource.getImage().format, m_resource.getImage().extent);
3761 const VkExtent3D& extent = m_resource.getImage().extent;
3762 const VkFormat format = m_resource.getImage().format;
3763 const tcu::TextureFormat texFormat = mapVkFormat(format);
3765 m_data.resize(static_cast<std::size_t>(size));
3766 tcu::PixelBufferAccess imagePixels(texFormat, extent.width, extent.height, extent.depth, &m_data[0]);
3767 clearPixelBuffer(imagePixels, m_clearValue);
3770 void recordCommands (const VkCommandBuffer cmdBuffer)
3772 const DeviceInterface& vk = m_context.getDeviceInterface();
3773 SynchronizationWrapperPtr synchronizationWrapper = getSynchronizationWrapper(m_context.getSynchronizationType(), vk, DE_FALSE);
3775 VkPipelineStageFlags2KHR dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR;
3776 if (m_context.getSynchronizationType() == SynchronizationType::SYNCHRONIZATION2)
3777 dstStageMask = VK_PIPELINE_STAGE_2_CLEAR_BIT_KHR;
3779 const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
3780 VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR, // VkPipelineStageFlags2KHR srcStageMask
3781 (VkAccessFlags)0, // VkAccessFlags2KHR srcAccessMask
3782 dstStageMask, // VkPipelineStageFlags2KHR dstStageMask
3783 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR, // VkAccessFlags2KHR dstAccessMask
3784 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
3785 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout
3786 m_resource.getImage().handle, // VkImage image
3787 m_resource.getImage().subresourceRange // VkImageSubresourceRange subresourceRange
3789 VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
3790 synchronizationWrapper->cmdPipelineBarrier(cmdBuffer, &dependencyInfo);
3792 if (m_mode == CLEAR_MODE_COLOR)
3793 vk.cmdClearColorImage(cmdBuffer, m_resource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &m_clearValue.color, 1u, &m_resource.getImage().subresourceRange);
3795 vk.cmdClearDepthStencilImage(cmdBuffer, m_resource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &m_clearValue.depthStencil, 1u, &m_resource.getImage().subresourceRange);
3798 SyncInfo getInSyncInfo (void) const
3800 return emptySyncInfo;
3803 SyncInfo getOutSyncInfo (void) const
3805 VkPipelineStageFlags2KHR stageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR;
3806 if (m_context.getSynchronizationType() == SynchronizationType::SYNCHRONIZATION2)
3807 stageMask = VK_PIPELINE_STAGE_2_CLEAR_BIT_KHR;
3811 stageMask, // VkPipelineStageFlags stageMask;
3812 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR, // VkAccessFlags accessMask;
3813 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout imageLayout;
3817 Data getData (void) const
3821 m_data.size(), // std::size_t size;
3822 &m_data[0], // const deUint8* data;
3827 void setData (const Data&)
3833 OperationContext& m_context;
3834 Resource& m_resource;
3835 std::vector<deUint8> m_data;
3836 const VkClearValue m_clearValue;
3837 const ClearMode m_mode;
3840 class Support : public OperationSupport
3843 Support (const ResourceDescription& resourceDesc, const ClearMode mode)
3844 : m_resourceDesc (resourceDesc)
3847 DE_ASSERT(m_mode == CLEAR_MODE_COLOR || m_mode == CLEAR_MODE_DEPTH_STENCIL);
3848 DE_ASSERT(m_resourceDesc.type == RESOURCE_TYPE_IMAGE);
3849 DE_ASSERT(m_resourceDesc.imageAspect == VK_IMAGE_ASPECT_COLOR_BIT || (m_mode != CLEAR_MODE_COLOR));
3850 DE_ASSERT((m_resourceDesc.imageAspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) || (m_mode != CLEAR_MODE_DEPTH_STENCIL));
3853 deUint32 getInResourceUsageFlags (void) const
3858 deUint32 getOutResourceUsageFlags (void) const
3860 return VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3863 VkQueueFlags getQueueFlags (const OperationContext& context) const
3866 if (m_mode == CLEAR_MODE_COLOR)
3867 return VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT;
3869 return VK_QUEUE_GRAPHICS_BIT;
3872 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
3874 return de::MovePtr<Operation>(new Implementation(context, resource, m_mode));
3877 de::MovePtr<Operation> build (OperationContext&, Resource&, Resource&) const
3880 return de::MovePtr<Operation>();
3884 const ResourceDescription m_resourceDesc;
3885 const ClearMode m_mode;
3896 DRAW_CALL_DRAW_INDEXED,
3897 DRAW_CALL_DRAW_INDIRECT,
3898 DRAW_CALL_DRAW_INDEXED_INDIRECT,
3901 //! A write operation that is a result of drawing to an image.
3902 //! \todo Add support for depth/stencil too?
3903 class Implementation : public Operation
3906 Implementation (OperationContext& context, Resource& resource, const DrawCall drawCall)
3907 : m_context (context)
3908 , m_resource (resource)
3909 , m_drawCall (drawCall)
3910 , m_vertices (context)
3912 const DeviceInterface& vk = context.getDeviceInterface();
3913 const VkDevice device = context.getDevice();
3914 Allocator& allocator = context.getAllocator();
3918 if (m_drawCall == DRAW_CALL_DRAW_INDIRECT)
3920 m_indirectBuffer = de::MovePtr<Buffer>(new Buffer(vk, device, allocator,
3921 makeBufferCreateInfo(sizeof(VkDrawIndirectCommand), VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT), MemoryRequirement::HostVisible));
3923 const Allocation& alloc = m_indirectBuffer->getAllocation();
3924 VkDrawIndirectCommand* const pIndirectCommand = static_cast<VkDrawIndirectCommand*>(alloc.getHostPtr());
3926 pIndirectCommand->vertexCount = m_vertices.getNumVertices();
3927 pIndirectCommand->instanceCount = 1u;
3928 pIndirectCommand->firstVertex = 0u;
3929 pIndirectCommand->firstInstance = 0u;
3931 flushAlloc(vk, device, alloc);
3933 else if (m_drawCall == DRAW_CALL_DRAW_INDEXED_INDIRECT)
3935 m_indirectBuffer = de::MovePtr<Buffer>(new Buffer(vk, device, allocator,
3936 makeBufferCreateInfo(sizeof(VkDrawIndexedIndirectCommand), VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT), MemoryRequirement::HostVisible));
3938 const Allocation& alloc = m_indirectBuffer->getAllocation();
3939 VkDrawIndexedIndirectCommand* const pIndirectCommand = static_cast<VkDrawIndexedIndirectCommand*>(alloc.getHostPtr());
3941 pIndirectCommand->indexCount = m_vertices.getNumIndices();
3942 pIndirectCommand->instanceCount = 1u;
3943 pIndirectCommand->firstIndex = 0u;
3944 pIndirectCommand->vertexOffset = 0u;
3945 pIndirectCommand->firstInstance = 0u;
3947 flushAlloc(vk, device, alloc);
3950 // Resource image is the color attachment
3952 m_colorFormat = m_resource.getImage().format;
3953 m_colorSubresourceRange = m_resource.getImage().subresourceRange;
3954 m_colorImage = m_resource.getImage().handle;
3955 m_attachmentExtent = m_resource.getImage().extent;
3959 m_colorAttachmentView = makeImageView (vk, device, m_colorImage, VK_IMAGE_VIEW_TYPE_2D, m_colorFormat, m_colorSubresourceRange);
3960 m_renderPass = makeRenderPass (vk, device, m_colorFormat);
3961 m_framebuffer = makeFramebuffer (vk, device, *m_renderPass, *m_colorAttachmentView, m_attachmentExtent.width, m_attachmentExtent.height);
3962 m_pipelineLayout = makePipelineLayout(vk, device);
3964 GraphicsPipelineBuilder pipelineBuilder;
3966 .setRenderSize (tcu::IVec2(m_attachmentExtent.width, m_attachmentExtent.height))
3967 .setVertexInputSingleAttribute (m_vertices.getVertexFormat(), m_vertices.getVertexStride())
3968 .setShader (vk, device, VK_SHADER_STAGE_VERTEX_BIT, context.getBinaryCollection().get("draw_vert"), DE_NULL)
3969 .setShader (vk, device, VK_SHADER_STAGE_FRAGMENT_BIT, context.getBinaryCollection().get("draw_frag"), DE_NULL);
3971 m_pipeline = pipelineBuilder.build(vk, device, *m_pipelineLayout, *m_renderPass, context.getPipelineCacheData());
3973 // Set expected draw values
3975 m_expectedData.resize(static_cast<size_t>(getPixelBufferSize(m_resource.getImage().format, m_resource.getImage().extent)));
3976 tcu::PixelBufferAccess imagePixels(mapVkFormat(m_colorFormat), m_attachmentExtent.width, m_attachmentExtent.height, m_attachmentExtent.depth, &m_expectedData[0]);
3977 clearPixelBuffer(imagePixels, makeClearValue(m_colorFormat));
3980 void recordCommands (const VkCommandBuffer cmdBuffer)
3982 const DeviceInterface& vk = m_context.getDeviceInterface();
3983 SynchronizationWrapperPtr synchronizationWrapper = getSynchronizationWrapper(m_context.getSynchronizationType(), vk, DE_FALSE);
3985 // Change color attachment image layout
3987 const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
3988 VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR, // VkPipelineStageFlags2KHR srcStageMask
3989 (VkAccessFlags)0, // VkAccessFlags2KHR srcAccessMask
3990 VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR, // VkPipelineStageFlags2KHR dstStageMask
3991 VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR, // VkAccessFlags2KHR dstAccessMask
3992 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
3993 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout
3994 m_colorImage, // VkImage image
3995 m_colorSubresourceRange // VkImageSubresourceRange subresourceRange
3997 VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
3998 synchronizationWrapper->cmdPipelineBarrier(cmdBuffer, &dependencyInfo);
4002 const VkRect2D renderArea = makeRect2D(m_attachmentExtent);
4003 const tcu::Vec4 clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
4005 beginRenderPass(vk, cmdBuffer, *m_renderPass, *m_framebuffer, renderArea, clearColor);
4008 vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
4010 const VkDeviceSize vertexBufferOffset = 0ull;
4011 const VkBuffer vertexBuffer = m_vertices.getVertexBuffer();
4012 vk.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer, &vertexBufferOffset);
4015 if (m_drawCall == DRAW_CALL_DRAW_INDEXED || m_drawCall == DRAW_CALL_DRAW_INDEXED_INDIRECT)
4016 vk.cmdBindIndexBuffer(cmdBuffer, m_vertices.getIndexBuffer(), 0u, m_vertices.getIndexType());
4020 case DRAW_CALL_DRAW:
4021 vk.cmdDraw(cmdBuffer, m_vertices.getNumVertices(), 1u, 0u, 0u);
4024 case DRAW_CALL_DRAW_INDEXED:
4025 vk.cmdDrawIndexed(cmdBuffer, m_vertices.getNumIndices(), 1u, 0u, 0, 0u);
4028 case DRAW_CALL_DRAW_INDIRECT:
4029 vk.cmdDrawIndirect(cmdBuffer, **m_indirectBuffer, 0u, 1u, 0u);
4032 case DRAW_CALL_DRAW_INDEXED_INDIRECT:
4033 vk.cmdDrawIndexedIndirect(cmdBuffer, **m_indirectBuffer, 0u, 1u, 0u);
4037 endRenderPass(vk, cmdBuffer);
4040 SyncInfo getInSyncInfo (void) const
4042 return emptySyncInfo;
4045 SyncInfo getOutSyncInfo (void) const
4047 const SyncInfo syncInfo =
4049 VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR, // VkPipelineStageFlags stageMask;
4050 VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR, // VkAccessFlags accessMask;
4051 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout imageLayout;
4056 Data getData (void) const
4060 m_expectedData.size(), // std::size_t size;
4061 &m_expectedData[0], // const deUint8* data;
4066 void setData (const Data& data)
4068 DE_ASSERT(m_expectedData.size() == data.size);
4069 deMemcpy(&m_expectedData[0], data.data, data.size);
4073 OperationContext& m_context;
4074 Resource& m_resource;
4075 const DrawCall m_drawCall;
4076 const VertexGrid m_vertices;
4077 std::vector<deUint8> m_expectedData;
4078 de::MovePtr<Buffer> m_indirectBuffer;
4079 VkFormat m_colorFormat;
4080 VkImage m_colorImage;
4081 Move<VkImageView> m_colorAttachmentView;
4082 VkImageSubresourceRange m_colorSubresourceRange;
4083 VkExtent3D m_attachmentExtent;
4084 Move<VkRenderPass> m_renderPass;
4085 Move<VkFramebuffer> m_framebuffer;
4086 Move<VkPipelineLayout> m_pipelineLayout;
4087 Move<VkPipeline> m_pipeline;
4090 template<typename T, std::size_t N>
4091 std::string toString (const T (&values)[N])
4093 std::ostringstream str;
4094 for (std::size_t i = 0; i < N; ++i)
4095 str << (i != 0 ? ", " : "") << values[i];
4099 class Support : public OperationSupport
4102 Support (const ResourceDescription& resourceDesc, const DrawCall drawCall)
4103 : m_resourceDesc (resourceDesc)
4104 , m_drawCall (drawCall)
4106 DE_ASSERT(m_resourceDesc.type == RESOURCE_TYPE_IMAGE && m_resourceDesc.imageType == VK_IMAGE_TYPE_2D);
4107 DE_ASSERT(!isDepthStencilFormat(m_resourceDesc.imageFormat));
4110 void initPrograms (SourceCollections& programCollection) const
4114 std::ostringstream src;
4115 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
4117 << "layout(location = 0) in vec4 v_in_position;\n"
4119 << "out " << s_perVertexBlock << ";\n"
4121 << "void main (void)\n"
4123 << " gl_Position = v_in_position;\n"
4126 programCollection.glslSources.add("draw_vert") << glu::VertexSource(src.str());
4131 const VkClearValue clearValue = makeClearValue(m_resourceDesc.imageFormat);
4132 const bool isIntegerFormat = isIntFormat(m_resourceDesc.imageFormat) || isUintFormat(m_resourceDesc.imageFormat);
4133 const std::string colorType = (isIntegerFormat ? "uvec4" : "vec4");
4135 std::ostringstream src;
4136 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
4138 << "layout(location = 0) out " << colorType << " o_color;\n"
4140 << "void main (void)\n"
4142 << " o_color = " << colorType << "(" << (isIntegerFormat ? toString(clearValue.color.uint32) : toString(clearValue.color.float32)) << ");\n"
4145 programCollection.glslSources.add("draw_frag") << glu::FragmentSource(src.str());
4149 deUint32 getInResourceUsageFlags (void) const
4154 deUint32 getOutResourceUsageFlags (void) const
4156 return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
4159 VkQueueFlags getQueueFlags (const OperationContext& context) const
4162 return VK_QUEUE_GRAPHICS_BIT;
4165 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
4167 return de::MovePtr<Operation>(new Implementation(context, resource, m_drawCall));
4170 de::MovePtr<Operation> build (OperationContext&, Resource&, Resource&) const
4173 return de::MovePtr<Operation>();
4177 const ResourceDescription m_resourceDesc;
4178 const DrawCall m_drawCall;
4183 namespace ClearAttachments
4186 class Implementation : public Operation
4189 Implementation (OperationContext& context, Resource& resource)
4190 : m_context (context)
4191 , m_resource (resource)
4192 , m_clearValue (makeClearValue(m_resource.getImage().format))
4194 const DeviceInterface& vk = context.getDeviceInterface();
4195 const VkDevice device = context.getDevice();
4197 const VkDeviceSize size = getPixelBufferSize(m_resource.getImage().format, m_resource.getImage().extent);
4198 const VkExtent3D& extent = m_resource.getImage().extent;
4199 const VkFormat format = m_resource.getImage().format;
4200 const tcu::TextureFormat texFormat = mapVkFormat(format);
4201 const SyncInfo syncInfo = getOutSyncInfo();
4203 m_data.resize(static_cast<std::size_t>(size));
4204 tcu::PixelBufferAccess imagePixels(texFormat, extent.width, extent.height, extent.depth, &m_data[0]);
4205 clearPixelBuffer(imagePixels, m_clearValue);
4207 m_attachmentView = makeImageView(vk, device, m_resource.getImage().handle, getImageViewType(m_resource.getImage().imageType), m_resource.getImage().format, m_resource.getImage().subresourceRange);
4209 switch (m_resource.getImage().subresourceRange.aspectMask)
4211 case VK_IMAGE_ASPECT_COLOR_BIT:
4212 m_renderPass = makeRenderPass(vk, device, m_resource.getImage().format, VK_FORMAT_UNDEFINED, VK_ATTACHMENT_LOAD_OP_DONT_CARE, syncInfo.imageLayout);
4214 case VK_IMAGE_ASPECT_STENCIL_BIT:
4215 case VK_IMAGE_ASPECT_DEPTH_BIT:
4216 m_renderPass = makeRenderPass(vk, device, VK_FORMAT_UNDEFINED, m_resource.getImage().format, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, syncInfo.imageLayout);
4223 m_frameBuffer = makeFramebuffer(vk, device, *m_renderPass, *m_attachmentView, m_resource.getImage().extent.width, m_resource.getImage().extent.height);
4226 void recordCommands (const VkCommandBuffer cmdBuffer)
4228 const DeviceInterface& vk = m_context.getDeviceInterface();
4229 if ((m_resource.getImage().subresourceRange.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) != 0)
4231 const VkImageMemoryBarrier imageBarrier =
4233 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
4235 0u, // srcAccessMask
4236 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // dstAccessMask
4237 VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
4238 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // newLayout
4239 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
4240 VK_QUEUE_FAMILY_IGNORED, // dstQueueFamilyIndex
4241 m_resource.getImage().handle, // image
4242 m_resource.getImage().subresourceRange // subresourceRange
4244 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageBarrier);
4246 beginRenderPass(vk, cmdBuffer, *m_renderPass, *m_frameBuffer, makeRect2D(0 ,0, m_resource.getImage().extent.width, m_resource.getImage().extent.height), m_clearValue);
4248 const VkClearAttachment clearAttachment =
4250 m_resource.getImage().subresourceRange.aspectMask, // VkImageAspectFlags aspectMask;
4251 0, // deUint32 colorAttachment;
4252 m_clearValue // VkClearValue clearValue;
4255 const VkRect2D rect2D = makeRect2D(m_resource.getImage().extent);
4257 const VkClearRect clearRect =
4259 rect2D, // VkRect2D rect;
4260 0u, // deUint32 baseArrayLayer;
4261 m_resource.getImage().subresourceLayers.layerCount // deUint32 layerCount;
4264 vk.cmdClearAttachments(cmdBuffer, 1, &clearAttachment, 1, &clearRect);
4266 endRenderPass(vk, cmdBuffer);
4269 SyncInfo getInSyncInfo (void) const
4271 return emptySyncInfo;
4274 SyncInfo getOutSyncInfo (void) const
4277 syncInfo.stageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR;
4279 switch (m_resource.getImage().subresourceRange.aspectMask)
4281 case VK_IMAGE_ASPECT_COLOR_BIT:
4282 syncInfo.accessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR;
4283 syncInfo.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
4285 case VK_IMAGE_ASPECT_STENCIL_BIT:
4286 case VK_IMAGE_ASPECT_DEPTH_BIT:
4287 syncInfo.accessMask = VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT_KHR;
4288 syncInfo.imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
4298 Data getData (void) const
4302 m_data.size(), // std::size_t size;
4303 &m_data[0], // const deUint8* data;
4308 void setData (const Data&)
4314 OperationContext& m_context;
4315 Resource& m_resource;
4316 std::vector<deUint8> m_data;
4317 const VkClearValue m_clearValue;
4318 Move<VkImageView> m_attachmentView;
4319 Move<VkRenderPass> m_renderPass;
4320 Move<VkFramebuffer> m_frameBuffer;
4323 class Support : public OperationSupport
4326 Support (const ResourceDescription& resourceDesc)
4327 : m_resourceDesc (resourceDesc)
4329 DE_ASSERT(m_resourceDesc.type == RESOURCE_TYPE_IMAGE);
4332 deUint32 getInResourceUsageFlags (void) const
4337 deUint32 getOutResourceUsageFlags (void) const
4339 switch (m_resourceDesc.imageAspect)
4341 case VK_IMAGE_ASPECT_COLOR_BIT:
4342 return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
4343 case VK_IMAGE_ASPECT_STENCIL_BIT:
4344 case VK_IMAGE_ASPECT_DEPTH_BIT:
4345 return VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
4352 VkQueueFlags getQueueFlags (const OperationContext& context) const
4355 return VK_QUEUE_GRAPHICS_BIT;
4358 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
4360 return de::MovePtr<Operation>(new Implementation(context, resource));
4363 de::MovePtr<Operation> build (OperationContext&, Resource&, Resource&) const
4366 return de::MovePtr<Operation>();
4370 const ResourceDescription m_resourceDesc;
4373 } // ClearAttachments
4375 namespace IndirectBuffer
4378 class GraphicsPipeline : public Pipeline
4381 GraphicsPipeline (OperationContext& context,
4382 const ResourceType resourceType,
4383 const VkBuffer indirectBuffer,
4384 const std::string& shaderPrefix,
4385 const VkDescriptorSetLayout descriptorSetLayout)
4386 : m_resourceType (resourceType)
4387 , m_indirectBuffer (indirectBuffer)
4388 , m_vertices (context)
4390 const DeviceInterface& vk = context.getDeviceInterface();
4391 const VkDevice device = context.getDevice();
4392 Allocator& allocator = context.getAllocator();
4396 m_colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
4397 m_colorImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
4398 m_colorImageExtent = makeExtent3D(16u, 16u, 1u);
4399 m_colorAttachmentImage = de::MovePtr<Image>(new Image(vk, device, allocator,
4400 makeImageCreateInfo(VK_IMAGE_TYPE_2D, m_colorImageExtent, m_colorFormat, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
4401 VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL),
4402 MemoryRequirement::Any));
4406 m_colorAttachmentView = makeImageView (vk, device, **m_colorAttachmentImage, VK_IMAGE_VIEW_TYPE_2D, m_colorFormat, m_colorImageSubresourceRange);
4407 m_renderPass = makeRenderPass (vk, device, m_colorFormat);
4408 m_framebuffer = makeFramebuffer (vk, device, *m_renderPass, *m_colorAttachmentView, m_colorImageExtent.width, m_colorImageExtent.height);
4409 m_pipelineLayout = makePipelineLayout(vk, device, descriptorSetLayout);
4411 GraphicsPipelineBuilder pipelineBuilder;
4413 .setRenderSize (tcu::IVec2(m_colorImageExtent.width, m_colorImageExtent.height))
4414 .setVertexInputSingleAttribute (m_vertices.getVertexFormat(), m_vertices.getVertexStride())
4415 .setShader (vk, device, VK_SHADER_STAGE_VERTEX_BIT, context.getBinaryCollection().get(shaderPrefix + "vert"), DE_NULL)
4416 .setShader (vk, device, VK_SHADER_STAGE_FRAGMENT_BIT, context.getBinaryCollection().get(shaderPrefix + "frag"), DE_NULL);
4418 m_pipeline = pipelineBuilder.build(vk, device, *m_pipelineLayout, *m_renderPass, context.getPipelineCacheData());
4421 void recordCommands (OperationContext& context, const VkCommandBuffer cmdBuffer, const VkDescriptorSet descriptorSet)
4423 const DeviceInterface& vk = context.getDeviceInterface();
4424 SynchronizationWrapperPtr synchronizationWrapper = getSynchronizationWrapper(context.getSynchronizationType(), vk, DE_FALSE);
4426 // Change color attachment image layout
4428 const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
4429 VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR, // VkPipelineStageFlags2KHR srcStageMask
4430 (VkAccessFlags)0, // VkAccessFlags2KHR srcAccessMask
4431 VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR, // VkPipelineStageFlags2KHR dstStageMask
4432 VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR, // VkAccessFlags2KHR dstAccessMask
4433 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
4434 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout
4435 **m_colorAttachmentImage, // VkImage image
4436 m_colorImageSubresourceRange // VkImageSubresourceRange subresourceRange
4438 VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
4439 synchronizationWrapper->cmdPipelineBarrier(cmdBuffer, &dependencyInfo);
4443 const VkRect2D renderArea = makeRect2D(m_colorImageExtent);
4444 const tcu::Vec4 clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
4446 beginRenderPass(vk, cmdBuffer, *m_renderPass, *m_framebuffer, renderArea, clearColor);
4449 vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
4450 vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &descriptorSet, 0u, DE_NULL);
4452 const VkDeviceSize vertexBufferOffset = 0ull;
4453 const VkBuffer vertexBuffer = m_vertices.getVertexBuffer();
4454 vk.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer, &vertexBufferOffset);
4457 switch (m_resourceType)
4459 case RESOURCE_TYPE_INDIRECT_BUFFER_DRAW:
4460 vk.cmdDrawIndirect(cmdBuffer, m_indirectBuffer, 0u, 1u, 0u);
4463 case RESOURCE_TYPE_INDIRECT_BUFFER_DRAW_INDEXED:
4464 vk.cmdBindIndexBuffer(cmdBuffer, m_vertices.getIndexBuffer(), 0u, m_vertices.getIndexType());
4465 vk.cmdDrawIndexedIndirect(cmdBuffer, m_indirectBuffer, 0u, 1u, 0u);
4472 endRenderPass(vk, cmdBuffer);
4476 const ResourceType m_resourceType;
4477 const VkBuffer m_indirectBuffer;
4478 const VertexGrid m_vertices;
4479 VkFormat m_colorFormat;
4480 de::MovePtr<Image> m_colorAttachmentImage;
4481 Move<VkImageView> m_colorAttachmentView;
4482 VkExtent3D m_colorImageExtent;
4483 VkImageSubresourceRange m_colorImageSubresourceRange;
4484 Move<VkRenderPass> m_renderPass;
4485 Move<VkFramebuffer> m_framebuffer;
4486 Move<VkPipelineLayout> m_pipelineLayout;
4487 Move<VkPipeline> m_pipeline;
4490 class ComputePipeline : public Pipeline
4493 ComputePipeline (OperationContext& context,
4494 const VkBuffer indirectBuffer,
4495 const std::string& shaderPrefix,
4496 const VkDescriptorSetLayout descriptorSetLayout)
4497 : m_indirectBuffer (indirectBuffer)
4499 const DeviceInterface& vk = context.getDeviceInterface();
4500 const VkDevice device = context.getDevice();
4502 const Unique<VkShaderModule> shaderModule(createShaderModule(vk, device, context.getBinaryCollection().get(shaderPrefix + "comp"), (VkShaderModuleCreateFlags)0));
4504 m_pipelineLayout = makePipelineLayout(vk, device, descriptorSetLayout);
4505 m_pipeline = makeComputePipeline(vk, device, *m_pipelineLayout, *shaderModule, DE_NULL, context.getPipelineCacheData());
4508 void recordCommands (OperationContext& context, const VkCommandBuffer cmdBuffer, const VkDescriptorSet descriptorSet)
4510 const DeviceInterface& vk = context.getDeviceInterface();
4512 vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipeline);
4513 vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0u, 1u, &descriptorSet, 0u, DE_NULL);
4514 vk.cmdDispatchIndirect(cmdBuffer, m_indirectBuffer, 0u);
4518 const VkBuffer m_indirectBuffer;
4519 Move<VkPipelineLayout> m_pipelineLayout;
4520 Move<VkPipeline> m_pipeline;
4523 //! Read indirect buffer by executing an indirect draw or dispatch command.
4524 class ReadImplementation : public Operation
4527 ReadImplementation (OperationContext& context, Resource& resource)
4528 : m_context (context)
4529 , m_resource (resource)
4530 , m_stage (resource.getType() == RESOURCE_TYPE_INDIRECT_BUFFER_DISPATCH ? VK_SHADER_STAGE_COMPUTE_BIT : VK_SHADER_STAGE_VERTEX_BIT)
4531 , m_pipelineStage (pipelineStageFlagsFromShaderStageFlagBits(m_stage))
4532 , m_hostBufferSizeBytes (sizeof(deUint32))
4534 requireFeaturesForSSBOAccess (m_context, m_stage);
4536 const DeviceInterface& vk = m_context.getDeviceInterface();
4537 const VkDevice device = m_context.getDevice();
4538 Allocator& allocator = m_context.getAllocator();
4540 m_hostBuffer = de::MovePtr<Buffer>(new Buffer(
4541 vk, device, allocator, makeBufferCreateInfo(m_hostBufferSizeBytes, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible));
4543 // Init host buffer data
4545 const Allocation& alloc = m_hostBuffer->getAllocation();
4546 deMemset(alloc.getHostPtr(), 0, static_cast<size_t>(m_hostBufferSizeBytes));
4547 flushAlloc(vk, device, alloc);
4550 // Prepare descriptors
4552 m_descriptorSetLayout = DescriptorSetLayoutBuilder()
4553 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, m_stage)
4556 m_descriptorPool = DescriptorPoolBuilder()
4557 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
4558 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
4560 m_descriptorSet = makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout);
4562 const VkDescriptorBufferInfo hostBufferInfo = makeDescriptorBufferInfo(**m_hostBuffer, 0u, m_hostBufferSizeBytes);
4564 DescriptorSetUpdateBuilder()
4565 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &hostBufferInfo)
4566 .update(vk, device);
4570 m_pipeline = (m_resource.getType() == RESOURCE_TYPE_INDIRECT_BUFFER_DISPATCH
4571 ? de::MovePtr<Pipeline>(new ComputePipeline(context, m_resource.getBuffer().handle, "read_ib_", *m_descriptorSetLayout))
4572 : de::MovePtr<Pipeline>(new GraphicsPipeline(context, m_resource.getType(), m_resource.getBuffer().handle, "read_ib_", *m_descriptorSetLayout)));
4575 void recordCommands (const VkCommandBuffer cmdBuffer)
4577 const DeviceInterface& vk = m_context.getDeviceInterface();
4578 SynchronizationWrapperPtr synchronizationWrapper = getSynchronizationWrapper(m_context.getSynchronizationType(), vk, DE_FALSE);
4580 m_pipeline->recordCommands(m_context, cmdBuffer, *m_descriptorSet);
4582 // Insert a barrier so data written by the shader is available to the host
4583 const VkBufferMemoryBarrier2KHR bufferMemoryBarrier2 = makeBufferMemoryBarrier2(
4584 m_pipelineStage, // VkPipelineStageFlags2KHR srcStageMask
4585 VK_ACCESS_2_SHADER_WRITE_BIT_KHR, // VkAccessFlags2KHR srcAccessMask
4586 VK_PIPELINE_STAGE_2_HOST_BIT_KHR, // VkPipelineStageFlags2KHR dstStageMask
4587 VK_ACCESS_2_HOST_READ_BIT_KHR, // VkAccessFlags2KHR dstAccessMask
4588 **m_hostBuffer, // VkBuffer buffer
4589 0u, // VkDeviceSize offset
4590 m_hostBufferSizeBytes // VkDeviceSize size
4592 VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, &bufferMemoryBarrier2);
4593 synchronizationWrapper->cmdPipelineBarrier(cmdBuffer, &dependencyInfo);
4596 SyncInfo getInSyncInfo (void) const
4598 const SyncInfo syncInfo =
4600 VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT_KHR, // VkPipelineStageFlags stageMask;
4601 VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT_KHR, // VkAccessFlags accessMask;
4602 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
4607 SyncInfo getOutSyncInfo (void) const
4609 return emptySyncInfo;
4612 Data getData (void) const
4614 return getHostBufferData(m_context, *m_hostBuffer, m_hostBufferSizeBytes);
4617 void setData (const Data&)
4623 OperationContext& m_context;
4624 Resource& m_resource;
4625 const VkShaderStageFlagBits m_stage;
4626 const VkPipelineStageFlags m_pipelineStage;
4627 const VkDeviceSize m_hostBufferSizeBytes;
4628 de::MovePtr<Buffer> m_hostBuffer;
4629 Move<VkDescriptorPool> m_descriptorPool;
4630 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
4631 Move<VkDescriptorSet> m_descriptorSet;
4632 de::MovePtr<Pipeline> m_pipeline;
4635 //! Prepare indirect buffer for a draw/dispatch call.
4636 class WriteImplementation : public Operation
4639 WriteImplementation (OperationContext& context, Resource& resource)
4640 : m_context (context)
4641 , m_resource (resource)
4643 switch (m_resource.getType())
4645 case RESOURCE_TYPE_INDIRECT_BUFFER_DRAW:
4647 m_drawIndirect.vertexCount = 6u;
4648 m_drawIndirect.instanceCount = 1u;
4649 m_drawIndirect.firstVertex = 0u;
4650 m_drawIndirect.firstInstance = 0u;
4652 m_indirectData = reinterpret_cast<deUint32*>(&m_drawIndirect);
4653 m_expectedValue = 6u;
4657 case RESOURCE_TYPE_INDIRECT_BUFFER_DRAW_INDEXED:
4659 m_drawIndexedIndirect.indexCount = 6u;
4660 m_drawIndexedIndirect.instanceCount = 1u;
4661 m_drawIndexedIndirect.firstIndex = 0u;
4662 m_drawIndexedIndirect.vertexOffset = 0u;
4663 m_drawIndexedIndirect.firstInstance = 0u;
4665 m_indirectData = reinterpret_cast<deUint32*>(&m_drawIndexedIndirect);
4666 m_expectedValue = 6u;
4670 case RESOURCE_TYPE_INDIRECT_BUFFER_DISPATCH:
4672 m_dispatchIndirect.x = 7u;
4673 m_dispatchIndirect.y = 2u;
4674 m_dispatchIndirect.z = 1u;
4676 m_indirectData = reinterpret_cast<deUint32*>(&m_dispatchIndirect);
4677 m_expectedValue = 14u;
4687 void recordCommands (const VkCommandBuffer cmdBuffer)
4689 const DeviceInterface& vk = m_context.getDeviceInterface();
4691 vk.cmdUpdateBuffer(cmdBuffer, m_resource.getBuffer().handle, m_resource.getBuffer().offset, m_resource.getBuffer().size, m_indirectData);
4694 SyncInfo getInSyncInfo (void) const
4696 return emptySyncInfo;
4699 SyncInfo getOutSyncInfo (void) const
4701 const SyncInfo syncInfo =
4703 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags stageMask;
4704 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR, // VkAccessFlags accessMask;
4705 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
4710 Data getData (void) const
4714 sizeof(deUint32), // std::size_t size;
4715 reinterpret_cast<const deUint8*>(&m_expectedValue), // const deUint8* data;
4720 void setData (const Data&)
4726 OperationContext& m_context;
4727 Resource& m_resource;
4728 VkDrawIndirectCommand m_drawIndirect;
4729 VkDrawIndexedIndirectCommand m_drawIndexedIndirect;
4730 VkDispatchIndirectCommand m_dispatchIndirect;
4731 deUint32* m_indirectData;
4732 deUint32 m_expectedValue; //! Side-effect value expected to be computed by a read (draw/dispatch) command.
4735 class ReadSupport : public OperationSupport
4738 ReadSupport (const ResourceDescription& resourceDesc)
4739 : m_resourceDesc (resourceDesc)
4741 DE_ASSERT(isIndirectBuffer(m_resourceDesc.type));
4744 void initPrograms (SourceCollections& programCollection) const
4746 std::ostringstream decl;
4747 decl << "layout(set = 0, binding = 0, std140) coherent buffer Data {\n"
4751 std::ostringstream main;
4752 main << " atomicAdd(sb_out.value, 1u);\n";
4756 std::ostringstream src;
4757 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
4759 << "layout(location = 0) in vec4 v_in_position;\n"
4761 << "out " << s_perVertexBlock << ";\n"
4765 << "void main (void)\n"
4767 << " gl_Position = v_in_position;\n"
4771 programCollection.glslSources.add("read_ib_vert") << glu::VertexSource(src.str());
4776 std::ostringstream src;
4777 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
4779 << "layout(location = 0) out vec4 o_color;\n"
4781 << "void main (void)\n"
4783 << " o_color = vec4(1.0);\n"
4786 programCollection.glslSources.add("read_ib_frag") << glu::FragmentSource(src.str());
4791 std::ostringstream src;
4792 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
4794 << "layout(local_size_x = 1) in;\n"
4798 << "void main (void)\n"
4803 programCollection.glslSources.add("read_ib_comp") << glu::ComputeSource(src.str());
4807 deUint32 getInResourceUsageFlags (void) const
4809 return VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
4812 deUint32 getOutResourceUsageFlags (void) const
4817 VkQueueFlags getQueueFlags (const OperationContext& context) const
4820 return (m_resourceDesc.type == RESOURCE_TYPE_INDIRECT_BUFFER_DISPATCH ? VK_QUEUE_COMPUTE_BIT : VK_QUEUE_GRAPHICS_BIT);
4823 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
4825 return de::MovePtr<Operation>(new ReadImplementation(context, resource));
4828 de::MovePtr<Operation> build (OperationContext&, Resource&, Resource&) const
4831 return de::MovePtr<Operation>();
4835 const ResourceDescription m_resourceDesc;
4839 class WriteSupport : public OperationSupport
4842 WriteSupport (const ResourceDescription& resourceDesc)
4844 DE_ASSERT(isIndirectBuffer(resourceDesc.type));
4845 DE_UNREF(resourceDesc);
4848 deUint32 getInResourceUsageFlags (void) const
4853 deUint32 getOutResourceUsageFlags (void) const
4855 return VK_BUFFER_USAGE_TRANSFER_DST_BIT;
4858 VkQueueFlags getQueueFlags (const OperationContext& context) const
4861 return VK_QUEUE_TRANSFER_BIT;
4864 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
4866 return de::MovePtr<Operation>(new WriteImplementation(context, resource));
4869 de::MovePtr<Operation> build (OperationContext&, Resource&, Resource&) const
4872 return de::MovePtr<Operation>();
4876 } // IndirectBuffer ns
4878 namespace VertexInput
4883 DRAW_MODE_VERTEX = 0,
4887 class Implementation : public Operation
4890 Implementation (OperationContext& context, Resource& resource, DrawMode drawMode)
4891 : m_context (context)
4892 , m_resource (resource)
4893 , m_drawMode (drawMode)
4895 requireFeaturesForSSBOAccess (m_context, VK_SHADER_STAGE_VERTEX_BIT);
4897 const DeviceInterface& vk = context.getDeviceInterface();
4898 const VkDevice device = context.getDevice();
4899 Allocator& allocator = context.getAllocator();
4900 VkFormat attributeFormat = VK_FORMAT_R32G32B32A32_UINT;
4901 const VkDeviceSize dataSizeBytes = m_resource.getBuffer().size;
4903 // allocate ssbo that will store data used for verification
4905 m_outputBuffer = de::MovePtr<Buffer>(new Buffer(vk, device, allocator,
4906 makeBufferCreateInfo(dataSizeBytes, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible));
4908 const Allocation& alloc = m_outputBuffer->getAllocation();
4909 deMemset(alloc.getHostPtr(), 0, static_cast<size_t>(dataSizeBytes));
4910 flushAlloc(vk, device, alloc);
4913 // allocate buffer that will be used for vertex attributes when we use resource for indices
4914 if (m_drawMode == DRAW_MODE_INDEXED)
4916 attributeFormat = VK_FORMAT_R32_UINT;
4918 m_inputBuffer = de::MovePtr<Buffer>(new Buffer(vk, device, allocator,
4919 makeBufferCreateInfo(dataSizeBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible));
4921 const Allocation& alloc = m_inputBuffer->getAllocation();
4922 fillPattern(alloc.getHostPtr(), dataSizeBytes, true);
4923 flushAlloc(vk, device, alloc);
4926 m_descriptorSetLayout = DescriptorSetLayoutBuilder()
4927 .addSingleBinding (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_VERTEX_BIT)
4928 .build (vk, device);
4930 m_descriptorPool = DescriptorPoolBuilder()
4931 .addType (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
4932 .build (vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
4934 m_descriptorSet = makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout);
4936 const VkDescriptorBufferInfo outputBufferDescriptorInfo = makeDescriptorBufferInfo(m_outputBuffer->get(), 0ull, dataSizeBytes);
4937 DescriptorSetUpdateBuilder()
4938 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outputBufferDescriptorInfo)
4939 .update (vk, device);
4942 m_colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
4943 m_colorImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
4944 m_colorImageExtent = makeExtent3D(16u, 16u, 1u);
4945 m_colorAttachmentImage = de::MovePtr<Image>(new Image(vk, device, allocator,
4946 makeImageCreateInfo(VK_IMAGE_TYPE_2D, m_colorImageExtent, m_colorFormat, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
4947 VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL),
4948 MemoryRequirement::Any));
4951 m_colorAttachmentView = makeImageView (vk, device, **m_colorAttachmentImage, VK_IMAGE_VIEW_TYPE_2D, m_colorFormat, m_colorImageSubresourceRange);
4952 m_renderPass = makeRenderPass (vk, device, m_colorFormat);
4953 m_framebuffer = makeFramebuffer (vk, device, *m_renderPass, *m_colorAttachmentView, m_colorImageExtent.width, m_colorImageExtent.height);
4954 m_pipelineLayout = makePipelineLayout(vk, device, *m_descriptorSetLayout);
4956 m_pipeline = GraphicsPipelineBuilder()
4957 .setPrimitiveTopology (VK_PRIMITIVE_TOPOLOGY_POINT_LIST)
4958 .setRenderSize (tcu::IVec2(static_cast<int>(m_colorImageExtent.width), static_cast<int>(m_colorImageExtent.height)))
4959 .setVertexInputSingleAttribute (attributeFormat, tcu::getPixelSize(mapVkFormat(attributeFormat)))
4960 .setShader (vk, device, VK_SHADER_STAGE_VERTEX_BIT, context.getBinaryCollection().get("input_vert"), DE_NULL)
4961 .setShader (vk, device, VK_SHADER_STAGE_FRAGMENT_BIT, context.getBinaryCollection().get("input_frag"), DE_NULL)
4962 .build (vk, device, *m_pipelineLayout, *m_renderPass, context.getPipelineCacheData());
4965 void recordCommands (const VkCommandBuffer cmdBuffer)
4967 const DeviceInterface& vk = m_context.getDeviceInterface();
4968 const VkDeviceSize dataSizeBytes = m_resource.getBuffer().size;
4969 SynchronizationWrapperPtr synchronizationWrapper = getSynchronizationWrapper(m_context.getSynchronizationType(), vk, DE_FALSE);
4971 // Change color attachment image layout
4973 const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
4974 VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR, // VkPipelineStageFlags2KHR srcStageMask
4975 (VkAccessFlags)0, // VkAccessFlags2KHR srcAccessMask
4976 VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR, // VkPipelineStageFlags2KHR dstStageMask
4977 VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR, // VkAccessFlags2KHR dstAccessMask
4978 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
4979 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout
4980 **m_colorAttachmentImage, // VkImage image
4981 m_colorImageSubresourceRange // VkImageSubresourceRange subresourceRange
4983 VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
4984 synchronizationWrapper->cmdPipelineBarrier(cmdBuffer, &dependencyInfo);
4988 const VkRect2D renderArea = makeRect2D(m_colorImageExtent);
4989 const tcu::Vec4 clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
4991 beginRenderPass(vk, cmdBuffer, *m_renderPass, *m_framebuffer, renderArea, clearColor);
4994 vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
4995 vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &m_descriptorSet.get(), 0u, DE_NULL);
4997 const VkDeviceSize vertexBufferOffset = 0ull;
4998 if (m_drawMode == DRAW_MODE_VERTEX)
5000 const deUint32 count = static_cast<deUint32>(dataSizeBytes / sizeof(tcu::UVec4));
5001 vk.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &m_resource.getBuffer().handle, &vertexBufferOffset);
5002 vk.cmdDraw(cmdBuffer, count, 1u, 0u, 0u);
5004 else // (m_drawMode == DRAW_MODE_INDEXED)
5006 const deUint32 count = static_cast<deUint32>(dataSizeBytes / sizeof(deUint32));
5007 vk.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &**m_inputBuffer, &vertexBufferOffset);
5008 vk.cmdBindIndexBuffer(cmdBuffer, m_resource.getBuffer().handle, 0u, VK_INDEX_TYPE_UINT32);
5009 vk.cmdDrawIndexed(cmdBuffer, count, 1, 0, 0, 0);
5012 endRenderPass(vk, cmdBuffer);
5014 // Insert a barrier so data written by the shader is available to the host
5016 const VkBufferMemoryBarrier2KHR bufferMemoryBarrier2 = makeBufferMemoryBarrier2(
5017 VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT_KHR, // VkPipelineStageFlags2KHR srcStageMask
5018 VK_ACCESS_2_SHADER_WRITE_BIT_KHR, // VkAccessFlags2KHR srcAccessMask
5019 VK_PIPELINE_STAGE_2_HOST_BIT_KHR, // VkPipelineStageFlags2KHR dstStageMask
5020 VK_ACCESS_2_HOST_READ_BIT_KHR, // VkAccessFlags2KHR dstAccessMask
5021 **m_outputBuffer, // VkBuffer buffer
5022 0u, // VkDeviceSize offset
5023 m_resource.getBuffer().size // VkDeviceSize size
5025 VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, &bufferMemoryBarrier2);
5026 synchronizationWrapper->cmdPipelineBarrier(cmdBuffer, &dependencyInfo);
5030 SyncInfo getInSyncInfo (void) const
5032 const bool usingIndexedDraw = (m_drawMode == DRAW_MODE_INDEXED);
5033 VkPipelineStageFlags2KHR stageMask = VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT_KHR;
5034 VkAccessFlags2KHR accessMask = usingIndexedDraw ? VK_ACCESS_2_INDEX_READ_BIT_KHR
5035 : VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT_KHR;
5037 if (m_context.getSynchronizationType() == SynchronizationType::SYNCHRONIZATION2)
5039 // test new stages added with VK_KHR_synchronization2 (no need to further duplicate those tests);
5040 // with this operation we can test pre_rasterization, index_input and attribute_input flags;
5041 // since this operation is executed for three buffers of different size we use diferent flags depending on the size
5042 if (m_resource.getBuffer().size > MAX_UPDATE_BUFFER_SIZE)
5043 stageMask = VK_PIPELINE_STAGE_2_PRE_RASTERIZATION_SHADERS_BIT_KHR;
5045 stageMask = usingIndexedDraw ? VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT_KHR
5046 : VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT_KHR;
5049 const SyncInfo syncInfo =
5051 stageMask, // VkPipelineStageFlags stageMask;
5052 accessMask, // VkAccessFlags accessMask;
5053 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
5058 SyncInfo getOutSyncInfo (void) const
5060 return emptySyncInfo;
5063 Data getData (void) const
5065 return getHostBufferData(m_context, *m_outputBuffer, m_resource.getBuffer().size);
5068 void setData (const Data& data)
5070 setHostBufferData(m_context, *m_outputBuffer, data);
5074 OperationContext& m_context;
5075 Resource& m_resource;
5076 DrawMode m_drawMode;
5077 de::MovePtr<Buffer> m_inputBuffer;
5078 de::MovePtr<Buffer> m_outputBuffer;
5079 Move<VkRenderPass> m_renderPass;
5080 Move<VkFramebuffer> m_framebuffer;
5081 Move<VkPipelineLayout> m_pipelineLayout;
5082 Move<VkPipeline> m_pipeline;
5083 VkFormat m_colorFormat;
5084 de::MovePtr<Image> m_colorAttachmentImage;
5085 Move<VkImageView> m_colorAttachmentView;
5086 VkExtent3D m_colorImageExtent;
5087 VkImageSubresourceRange m_colorImageSubresourceRange;
5088 Move<VkDescriptorPool> m_descriptorPool;
5089 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
5090 Move<VkDescriptorSet> m_descriptorSet;
5093 class Support : public OperationSupport
5096 Support(const ResourceDescription& resourceDesc, DrawMode drawMode)
5097 : m_resourceDesc (resourceDesc)
5098 , m_drawMode (drawMode)
5100 DE_ASSERT(m_resourceDesc.type == RESOURCE_TYPE_BUFFER || m_resourceDesc.type == RESOURCE_TYPE_INDEX_BUFFER);
5103 void initPrograms (SourceCollections& programCollection) const
5107 std::ostringstream src;
5108 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n";
5109 if (m_drawMode == DRAW_MODE_VERTEX)
5111 src << "layout(location = 0) in uvec4 v_in_data;\n"
5112 << "layout(set = 0, binding = 0, std140) writeonly buffer Output {\n"
5113 << " uvec4 data[" << m_resourceDesc.size.x() / sizeof(tcu::UVec4) << "];\n"
5116 << "void main (void)\n"
5118 << " b_out.data[gl_VertexIndex] = v_in_data;\n"
5119 << " gl_PointSize = 1.0f;\n"
5122 else // DRAW_MODE_INDEXED
5124 src << "layout(location = 0) in uint v_in_data;\n"
5125 << "layout(set = 0, binding = 0, std430) writeonly buffer Output {\n"
5126 << " uint data[" << m_resourceDesc.size.x() / sizeof(deUint32) << "];\n"
5129 << "void main (void)\n"
5131 << " b_out.data[gl_VertexIndex] = v_in_data;\n"
5132 << " gl_PointSize = 1.0f;\n"
5135 programCollection.glslSources.add("input_vert") << glu::VertexSource(src.str());
5140 std::ostringstream src;
5141 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
5143 << "layout(location = 0) out vec4 o_color;\n"
5145 << "void main (void)\n"
5147 << " o_color = vec4(1.0);\n"
5149 programCollection.glslSources.add("input_frag") << glu::FragmentSource(src.str());
5153 deUint32 getInResourceUsageFlags (void) const
5155 return (m_drawMode == DRAW_MODE_VERTEX) ? VK_BUFFER_USAGE_VERTEX_BUFFER_BIT : VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
5158 deUint32 getOutResourceUsageFlags (void) const
5160 return VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
5163 VkQueueFlags getQueueFlags (const OperationContext&) const
5165 return VK_QUEUE_GRAPHICS_BIT;
5168 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
5170 return de::MovePtr<Operation>(new Implementation(context, resource, m_drawMode));
5173 de::MovePtr<Operation> build (OperationContext&, Resource&, Resource&) const
5176 return de::MovePtr<Operation>();
5180 const ResourceDescription m_resourceDesc;
5181 const DrawMode m_drawMode;
5188 OperationContext::OperationContext (Context& context, SynchronizationType syncType, PipelineCacheData& pipelineCacheData)
5189 : m_context (context)
5190 , m_syncType (syncType)
5191 , m_vki (context.getInstanceInterface())
5192 , m_vk (context.getDeviceInterface())
5193 , m_physicalDevice (context.getPhysicalDevice())
5194 , m_device (context.getDevice())
5195 , m_allocator (context.getDefaultAllocator())
5196 , m_progCollection (context.getBinaryCollection())
5197 , m_pipelineCacheData (pipelineCacheData)
5201 OperationContext::OperationContext (Context& context,
5202 SynchronizationType syncType,
5203 const DeviceInterface& vk,
5204 const VkDevice device,
5205 vk::Allocator& allocator,
5206 PipelineCacheData& pipelineCacheData)
5207 : m_context (context)
5208 , m_syncType (syncType)
5209 , m_vki (context.getInstanceInterface())
5211 , m_physicalDevice (context.getPhysicalDevice())
5213 , m_allocator (allocator)
5214 , m_progCollection (context.getBinaryCollection())
5215 , m_pipelineCacheData (pipelineCacheData)
5219 OperationContext::OperationContext (Context& context,
5220 SynchronizationType syncType,
5221 const vk::InstanceInterface& vki,
5222 const vk::DeviceInterface& vkd,
5223 vk::VkPhysicalDevice physicalDevice,
5224 vk::VkDevice device,
5225 vk::Allocator& allocator,
5226 vk::BinaryCollection& programCollection,
5227 PipelineCacheData& pipelineCacheData)
5228 : m_context (context)
5229 , m_syncType (syncType)
5232 , m_physicalDevice (physicalDevice)
5234 , m_allocator (allocator)
5235 , m_progCollection (programCollection)
5236 , m_pipelineCacheData (pipelineCacheData)
5240 Resource::Resource (OperationContext& context, const ResourceDescription& desc, const deUint32 usage, const vk::VkSharingMode sharingMode, const std::vector<deUint32>& queueFamilyIndex)
5241 : m_type (desc.type)
5243 const DeviceInterface& vk = context.getDeviceInterface();
5244 const InstanceInterface& vki = context.getInstanceInterface();
5245 const VkDevice device = context.getDevice();
5246 const VkPhysicalDevice physDevice = context.getPhysicalDevice();
5247 Allocator& allocator = context.getAllocator();
5249 if (m_type == RESOURCE_TYPE_BUFFER || m_type == RESOURCE_TYPE_INDEX_BUFFER || isIndirectBuffer(m_type))
5251 m_bufferData = de::MovePtr<BufferResource>(new BufferResource(DE_NULL, 0u, static_cast<VkDeviceSize>(desc.size.x())));
5252 VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(m_bufferData->size, usage);
5253 bufferCreateInfo.sharingMode = sharingMode;
5254 if (queueFamilyIndex.size() > 0)
5256 bufferCreateInfo.queueFamilyIndexCount = static_cast<deUint32>(queueFamilyIndex.size());
5257 bufferCreateInfo.pQueueFamilyIndices = &queueFamilyIndex[0];
5259 m_buffer = de::MovePtr<Buffer>(new Buffer(vk, device, allocator, bufferCreateInfo, MemoryRequirement::Any));
5260 m_bufferData->handle = **m_buffer;
5262 else if (m_type == RESOURCE_TYPE_IMAGE)
5264 m_imageData = de::MovePtr<ImageResource>(new ImageResource(
5266 makeExtent3D(desc.size.x(), std::max(1, desc.size.y()), std::max(1, desc.size.z())),
5269 makeImageSubresourceRange(desc.imageAspect, 0u, 1u, 0u, 1u),
5270 makeImageSubresourceLayers(desc.imageAspect, 0u, 0u, 1u),
5271 vk::VK_IMAGE_TILING_OPTIMAL
5273 VkImageCreateInfo imageInfo = makeImageCreateInfo(m_imageData->imageType, m_imageData->extent, m_imageData->format, usage, desc.imageSamples, m_imageData->tiling);
5274 imageInfo.sharingMode = sharingMode;
5275 if (queueFamilyIndex.size() > 0)
5277 imageInfo.queueFamilyIndexCount = static_cast<deUint32>(queueFamilyIndex.size());
5278 imageInfo.pQueueFamilyIndices = &queueFamilyIndex[0];
5281 VkImageFormatProperties imageFormatProperties;
5282 const VkResult formatResult = vki.getPhysicalDeviceImageFormatProperties(physDevice, imageInfo.format, imageInfo.imageType, imageInfo.tiling, imageInfo.usage, imageInfo.flags, &imageFormatProperties);
5284 if (formatResult != VK_SUCCESS)
5285 TCU_THROW(NotSupportedError, "Image format is not supported");
5287 if ((imageFormatProperties.sampleCounts & desc.imageSamples) != desc.imageSamples)
5288 TCU_THROW(NotSupportedError, "Requested sample count is not supported");
5290 m_image = de::MovePtr<Image>(new Image(vk, device, allocator, imageInfo, MemoryRequirement::Any));
5291 m_imageData->handle = **m_image;
5297 Resource::Resource (ResourceType type,
5298 vk::Move<vk::VkBuffer> buffer,
5299 de::MovePtr<vk::Allocation> allocation,
5300 vk::VkDeviceSize offset,
5301 vk::VkDeviceSize size)
5303 , m_buffer (new Buffer(buffer, allocation))
5304 , m_bufferData (de::MovePtr<BufferResource>(new BufferResource(m_buffer->get(), offset, size)))
5306 DE_ASSERT(type != RESOURCE_TYPE_IMAGE);
5309 Resource::Resource (vk::Move<vk::VkImage> image,
5310 de::MovePtr<vk::Allocation> allocation,
5311 const vk::VkExtent3D& extent,
5312 vk::VkImageType imageType,
5313 vk::VkFormat format,
5314 vk::VkImageSubresourceRange subresourceRange,
5315 vk::VkImageSubresourceLayers subresourceLayers,
5316 vk::VkImageTiling tiling)
5317 : m_type (RESOURCE_TYPE_IMAGE)
5318 , m_image (new Image(image, allocation))
5319 , m_imageData (de::MovePtr<ImageResource>(new ImageResource(m_image->get(), extent, imageType, format, subresourceRange, subresourceLayers, tiling)))
5323 vk::VkDeviceMemory Resource::getMemory (void) const
5325 if (m_type == RESOURCE_TYPE_IMAGE)
5326 return m_image->getAllocation().getMemory();
5328 return m_buffer->getAllocation().getMemory();
5331 //! \note This function exists for performance reasons. We're creating a lot of tests and checking requirements here
5332 //! before creating an OperationSupport object is faster.
5333 bool isResourceSupported (const OperationName opName, const ResourceDescription& resourceDesc)
5337 case OPERATION_NAME_WRITE_FILL_BUFFER:
5338 case OPERATION_NAME_WRITE_COPY_BUFFER:
5339 case OPERATION_NAME_WRITE_COPY_IMAGE_TO_BUFFER:
5340 case OPERATION_NAME_WRITE_SSBO_VERTEX:
5341 case OPERATION_NAME_WRITE_SSBO_TESSELLATION_CONTROL:
5342 case OPERATION_NAME_WRITE_SSBO_TESSELLATION_EVALUATION:
5343 case OPERATION_NAME_WRITE_SSBO_GEOMETRY:
5344 case OPERATION_NAME_WRITE_SSBO_FRAGMENT:
5345 case OPERATION_NAME_WRITE_SSBO_COMPUTE:
5346 case OPERATION_NAME_WRITE_SSBO_COMPUTE_INDIRECT:
5347 case OPERATION_NAME_READ_COPY_BUFFER:
5348 case OPERATION_NAME_READ_COPY_BUFFER_TO_IMAGE:
5349 case OPERATION_NAME_READ_SSBO_VERTEX:
5350 case OPERATION_NAME_READ_SSBO_TESSELLATION_CONTROL:
5351 case OPERATION_NAME_READ_SSBO_TESSELLATION_EVALUATION:
5352 case OPERATION_NAME_READ_SSBO_GEOMETRY:
5353 case OPERATION_NAME_READ_SSBO_FRAGMENT:
5354 case OPERATION_NAME_READ_SSBO_COMPUTE:
5355 case OPERATION_NAME_READ_SSBO_COMPUTE_INDIRECT:
5356 case OPERATION_NAME_READ_VERTEX_INPUT:
5357 return resourceDesc.type == RESOURCE_TYPE_BUFFER;
5359 case OPERATION_NAME_WRITE_INDIRECT_BUFFER_DRAW:
5360 case OPERATION_NAME_READ_INDIRECT_BUFFER_DRAW:
5361 return resourceDesc.type == RESOURCE_TYPE_INDIRECT_BUFFER_DRAW;
5363 case OPERATION_NAME_WRITE_INDIRECT_BUFFER_DRAW_INDEXED:
5364 case OPERATION_NAME_READ_INDIRECT_BUFFER_DRAW_INDEXED:
5365 return resourceDesc.type == RESOURCE_TYPE_INDIRECT_BUFFER_DRAW_INDEXED;
5367 case OPERATION_NAME_WRITE_INDIRECT_BUFFER_DISPATCH:
5368 case OPERATION_NAME_READ_INDIRECT_BUFFER_DISPATCH:
5369 return resourceDesc.type == RESOURCE_TYPE_INDIRECT_BUFFER_DISPATCH;
5371 case OPERATION_NAME_WRITE_UPDATE_INDEX_BUFFER:
5372 case OPERATION_NAME_READ_INDEX_INPUT:
5373 return resourceDesc.type == RESOURCE_TYPE_INDEX_BUFFER;
5375 case OPERATION_NAME_WRITE_UPDATE_BUFFER:
5376 return resourceDesc.type == RESOURCE_TYPE_BUFFER && resourceDesc.size.x() <= MAX_UPDATE_BUFFER_SIZE;
5378 case OPERATION_NAME_WRITE_COPY_IMAGE:
5379 case OPERATION_NAME_WRITE_COPY_BUFFER_TO_IMAGE:
5380 case OPERATION_NAME_READ_COPY_IMAGE:
5381 case OPERATION_NAME_READ_COPY_IMAGE_TO_BUFFER:
5382 return resourceDesc.type == RESOURCE_TYPE_IMAGE && resourceDesc.imageSamples == VK_SAMPLE_COUNT_1_BIT;
5384 case OPERATION_NAME_WRITE_CLEAR_ATTACHMENTS:
5385 return resourceDesc.type == RESOURCE_TYPE_IMAGE && resourceDesc.imageType != VK_IMAGE_TYPE_3D
5386 && resourceDesc.imageSamples == VK_SAMPLE_COUNT_1_BIT;
5388 case OPERATION_NAME_WRITE_IMAGE_COMPUTE_MULTISAMPLE:
5389 case OPERATION_NAME_READ_RESOLVE_IMAGE:
5390 return resourceDesc.type == RESOURCE_TYPE_IMAGE && resourceDesc.imageAspect == VK_IMAGE_ASPECT_COLOR_BIT
5391 && resourceDesc.imageSamples != VK_SAMPLE_COUNT_1_BIT;
5393 case OPERATION_NAME_WRITE_BLIT_IMAGE:
5394 case OPERATION_NAME_READ_BLIT_IMAGE:
5395 case OPERATION_NAME_WRITE_IMAGE_VERTEX:
5396 case OPERATION_NAME_WRITE_IMAGE_TESSELLATION_CONTROL:
5397 case OPERATION_NAME_WRITE_IMAGE_TESSELLATION_EVALUATION:
5398 case OPERATION_NAME_WRITE_IMAGE_GEOMETRY:
5399 case OPERATION_NAME_WRITE_IMAGE_FRAGMENT:
5400 case OPERATION_NAME_WRITE_IMAGE_COMPUTE:
5401 case OPERATION_NAME_WRITE_IMAGE_COMPUTE_INDIRECT:
5402 case OPERATION_NAME_READ_IMAGE_VERTEX:
5403 case OPERATION_NAME_READ_IMAGE_TESSELLATION_CONTROL:
5404 case OPERATION_NAME_READ_IMAGE_TESSELLATION_EVALUATION:
5405 case OPERATION_NAME_READ_IMAGE_GEOMETRY:
5406 case OPERATION_NAME_READ_IMAGE_FRAGMENT:
5407 case OPERATION_NAME_READ_IMAGE_COMPUTE:
5408 case OPERATION_NAME_READ_IMAGE_COMPUTE_INDIRECT:
5409 return resourceDesc.type == RESOURCE_TYPE_IMAGE && resourceDesc.imageAspect == VK_IMAGE_ASPECT_COLOR_BIT
5410 && resourceDesc.imageSamples == VK_SAMPLE_COUNT_1_BIT;
5412 case OPERATION_NAME_READ_UBO_VERTEX:
5413 case OPERATION_NAME_READ_UBO_TESSELLATION_CONTROL:
5414 case OPERATION_NAME_READ_UBO_TESSELLATION_EVALUATION:
5415 case OPERATION_NAME_READ_UBO_GEOMETRY:
5416 case OPERATION_NAME_READ_UBO_FRAGMENT:
5417 case OPERATION_NAME_READ_UBO_COMPUTE:
5418 case OPERATION_NAME_READ_UBO_COMPUTE_INDIRECT:
5419 return resourceDesc.type == RESOURCE_TYPE_BUFFER && resourceDesc.size.x() <= MAX_UBO_RANGE;
5421 case OPERATION_NAME_WRITE_CLEAR_COLOR_IMAGE:
5422 return resourceDesc.type == RESOURCE_TYPE_IMAGE && resourceDesc.imageAspect == VK_IMAGE_ASPECT_COLOR_BIT
5423 && resourceDesc.imageSamples == VK_SAMPLE_COUNT_1_BIT;
5425 case OPERATION_NAME_WRITE_CLEAR_DEPTH_STENCIL_IMAGE:
5426 return resourceDesc.type == RESOURCE_TYPE_IMAGE && (resourceDesc.imageAspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))
5427 && resourceDesc.imageSamples == VK_SAMPLE_COUNT_1_BIT;
5429 case OPERATION_NAME_WRITE_DRAW:
5430 case OPERATION_NAME_WRITE_DRAW_INDEXED:
5431 case OPERATION_NAME_WRITE_DRAW_INDIRECT:
5432 case OPERATION_NAME_WRITE_DRAW_INDEXED_INDIRECT:
5433 return resourceDesc.type == RESOURCE_TYPE_IMAGE && resourceDesc.imageType == VK_IMAGE_TYPE_2D
5434 && (resourceDesc.imageAspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) == 0
5435 && resourceDesc.imageSamples == VK_SAMPLE_COUNT_1_BIT;
5437 case OPERATION_NAME_COPY_BUFFER:
5438 case OPERATION_NAME_COPY_SSBO_VERTEX:
5439 case OPERATION_NAME_COPY_SSBO_TESSELLATION_CONTROL:
5440 case OPERATION_NAME_COPY_SSBO_TESSELLATION_EVALUATION:
5441 case OPERATION_NAME_COPY_SSBO_GEOMETRY:
5442 case OPERATION_NAME_COPY_SSBO_FRAGMENT:
5443 case OPERATION_NAME_COPY_SSBO_COMPUTE:
5444 case OPERATION_NAME_COPY_SSBO_COMPUTE_INDIRECT:
5445 return resourceDesc.type == RESOURCE_TYPE_BUFFER;
5447 case OPERATION_NAME_COPY_IMAGE:
5448 case OPERATION_NAME_BLIT_IMAGE:
5449 case OPERATION_NAME_COPY_IMAGE_VERTEX:
5450 case OPERATION_NAME_COPY_IMAGE_TESSELLATION_CONTROL:
5451 case OPERATION_NAME_COPY_IMAGE_TESSELLATION_EVALUATION:
5452 case OPERATION_NAME_COPY_IMAGE_GEOMETRY:
5453 case OPERATION_NAME_COPY_IMAGE_FRAGMENT:
5454 case OPERATION_NAME_COPY_IMAGE_COMPUTE:
5455 case OPERATION_NAME_COPY_IMAGE_COMPUTE_INDIRECT:
5456 return resourceDesc.type == RESOURCE_TYPE_IMAGE && resourceDesc.imageAspect == VK_IMAGE_ASPECT_COLOR_BIT
5457 && resourceDesc.imageSamples == VK_SAMPLE_COUNT_1_BIT;
5465 std::string getOperationName (const OperationName opName)
5469 case OPERATION_NAME_WRITE_FILL_BUFFER: return "write_fill_buffer";
5470 case OPERATION_NAME_WRITE_UPDATE_BUFFER: return "write_update_buffer";
5471 case OPERATION_NAME_WRITE_COPY_BUFFER: return "write_copy_buffer";
5472 case OPERATION_NAME_WRITE_COPY_BUFFER_TO_IMAGE: return "write_copy_buffer_to_image";
5473 case OPERATION_NAME_WRITE_COPY_IMAGE_TO_BUFFER: return "write_copy_image_to_buffer";
5474 case OPERATION_NAME_WRITE_COPY_IMAGE: return "write_copy_image";
5475 case OPERATION_NAME_WRITE_BLIT_IMAGE: return "write_blit_image";
5476 case OPERATION_NAME_WRITE_SSBO_VERTEX: return "write_ssbo_vertex";
5477 case OPERATION_NAME_WRITE_SSBO_TESSELLATION_CONTROL: return "write_ssbo_tess_control";
5478 case OPERATION_NAME_WRITE_SSBO_TESSELLATION_EVALUATION: return "write_ssbo_tess_eval";
5479 case OPERATION_NAME_WRITE_SSBO_GEOMETRY: return "write_ssbo_geometry";
5480 case OPERATION_NAME_WRITE_SSBO_FRAGMENT: return "write_ssbo_fragment";
5481 case OPERATION_NAME_WRITE_SSBO_COMPUTE: return "write_ssbo_compute";
5482 case OPERATION_NAME_WRITE_SSBO_COMPUTE_INDIRECT: return "write_ssbo_compute_indirect";
5483 case OPERATION_NAME_WRITE_IMAGE_VERTEX: return "write_image_vertex";
5484 case OPERATION_NAME_WRITE_IMAGE_TESSELLATION_CONTROL: return "write_image_tess_control";
5485 case OPERATION_NAME_WRITE_IMAGE_TESSELLATION_EVALUATION: return "write_image_tess_eval";
5486 case OPERATION_NAME_WRITE_IMAGE_GEOMETRY: return "write_image_geometry";
5487 case OPERATION_NAME_WRITE_IMAGE_FRAGMENT: return "write_image_fragment";
5488 case OPERATION_NAME_WRITE_IMAGE_COMPUTE: return "write_image_compute";
5489 case OPERATION_NAME_WRITE_IMAGE_COMPUTE_MULTISAMPLE: return "write_image_compute_multisample";
5490 case OPERATION_NAME_WRITE_IMAGE_COMPUTE_INDIRECT: return "write_image_compute_indirect";
5491 case OPERATION_NAME_WRITE_CLEAR_COLOR_IMAGE: return "write_clear_color_image";
5492 case OPERATION_NAME_WRITE_CLEAR_DEPTH_STENCIL_IMAGE: return "write_clear_depth_stencil_image";
5493 case OPERATION_NAME_WRITE_DRAW: return "write_draw";
5494 case OPERATION_NAME_WRITE_DRAW_INDEXED: return "write_draw_indexed";
5495 case OPERATION_NAME_WRITE_DRAW_INDIRECT: return "write_draw_indirect";
5496 case OPERATION_NAME_WRITE_DRAW_INDEXED_INDIRECT: return "write_draw_indexed_indirect";
5497 case OPERATION_NAME_WRITE_CLEAR_ATTACHMENTS: return "write_clear_attachments";
5498 case OPERATION_NAME_WRITE_INDIRECT_BUFFER_DRAW: return "write_indirect_buffer_draw";
5499 case OPERATION_NAME_WRITE_INDIRECT_BUFFER_DRAW_INDEXED: return "write_indirect_buffer_draw_indexed";
5500 case OPERATION_NAME_WRITE_INDIRECT_BUFFER_DISPATCH: return "write_indirect_buffer_dispatch";
5501 case OPERATION_NAME_WRITE_UPDATE_INDEX_BUFFER: return "write_update_index_buffer";
5503 case OPERATION_NAME_READ_COPY_BUFFER: return "read_copy_buffer";
5504 case OPERATION_NAME_READ_COPY_BUFFER_TO_IMAGE: return "read_copy_buffer_to_image";
5505 case OPERATION_NAME_READ_COPY_IMAGE_TO_BUFFER: return "read_copy_image_to_buffer";
5506 case OPERATION_NAME_READ_COPY_IMAGE: return "read_copy_image";
5507 case OPERATION_NAME_READ_BLIT_IMAGE: return "read_blit_image";
5508 case OPERATION_NAME_READ_RESOLVE_IMAGE: return "read_resolve_image";
5509 case OPERATION_NAME_READ_UBO_VERTEX: return "read_ubo_vertex";
5510 case OPERATION_NAME_READ_UBO_TESSELLATION_CONTROL: return "read_ubo_tess_control";
5511 case OPERATION_NAME_READ_UBO_TESSELLATION_EVALUATION: return "read_ubo_tess_eval";
5512 case OPERATION_NAME_READ_UBO_GEOMETRY: return "read_ubo_geometry";
5513 case OPERATION_NAME_READ_UBO_FRAGMENT: return "read_ubo_fragment";
5514 case OPERATION_NAME_READ_UBO_COMPUTE: return "read_ubo_compute";
5515 case OPERATION_NAME_READ_UBO_COMPUTE_INDIRECT: return "read_ubo_compute_indirect";
5516 case OPERATION_NAME_READ_SSBO_VERTEX: return "read_ssbo_vertex";
5517 case OPERATION_NAME_READ_SSBO_TESSELLATION_CONTROL: return "read_ssbo_tess_control";
5518 case OPERATION_NAME_READ_SSBO_TESSELLATION_EVALUATION: return "read_ssbo_tess_eval";
5519 case OPERATION_NAME_READ_SSBO_GEOMETRY: return "read_ssbo_geometry";
5520 case OPERATION_NAME_READ_SSBO_FRAGMENT: return "read_ssbo_fragment";
5521 case OPERATION_NAME_READ_SSBO_COMPUTE: return "read_ssbo_compute";
5522 case OPERATION_NAME_READ_SSBO_COMPUTE_INDIRECT: return "read_ssbo_compute_indirect";
5523 case OPERATION_NAME_READ_IMAGE_VERTEX: return "read_image_vertex";
5524 case OPERATION_NAME_READ_IMAGE_TESSELLATION_CONTROL: return "read_image_tess_control";
5525 case OPERATION_NAME_READ_IMAGE_TESSELLATION_EVALUATION: return "read_image_tess_eval";
5526 case OPERATION_NAME_READ_IMAGE_GEOMETRY: return "read_image_geometry";
5527 case OPERATION_NAME_READ_IMAGE_FRAGMENT: return "read_image_fragment";
5528 case OPERATION_NAME_READ_IMAGE_COMPUTE: return "read_image_compute";
5529 case OPERATION_NAME_READ_IMAGE_COMPUTE_INDIRECT: return "read_image_compute_indirect";
5530 case OPERATION_NAME_READ_INDIRECT_BUFFER_DRAW: return "read_indirect_buffer_draw";
5531 case OPERATION_NAME_READ_INDIRECT_BUFFER_DRAW_INDEXED: return "read_indirect_buffer_draw_indexed";
5532 case OPERATION_NAME_READ_INDIRECT_BUFFER_DISPATCH: return "read_indirect_buffer_dispatch";
5533 case OPERATION_NAME_READ_VERTEX_INPUT: return "read_vertex_input";
5534 case OPERATION_NAME_READ_INDEX_INPUT: return "read_index_input";
5536 case OPERATION_NAME_COPY_BUFFER: return "copy_buffer";
5537 case OPERATION_NAME_COPY_IMAGE: return "copy_image";
5538 case OPERATION_NAME_BLIT_IMAGE: return "blit_image";
5539 case OPERATION_NAME_COPY_SSBO_VERTEX: return "copy_buffer_vertex";
5540 case OPERATION_NAME_COPY_SSBO_TESSELLATION_CONTROL: return "copy_ssbo_tess_control";
5541 case OPERATION_NAME_COPY_SSBO_TESSELLATION_EVALUATION: return "copy_ssbo_tess_eval";
5542 case OPERATION_NAME_COPY_SSBO_GEOMETRY: return "copy_ssbo_geometry";
5543 case OPERATION_NAME_COPY_SSBO_FRAGMENT: return "copy_ssbo_fragment";
5544 case OPERATION_NAME_COPY_SSBO_COMPUTE: return "copy_ssbo_compute";
5545 case OPERATION_NAME_COPY_SSBO_COMPUTE_INDIRECT: return "copy_ssbo_compute_indirect";
5546 case OPERATION_NAME_COPY_IMAGE_VERTEX: return "copy_image_vertex";
5547 case OPERATION_NAME_COPY_IMAGE_TESSELLATION_CONTROL: return "copy_image_tess_control";
5548 case OPERATION_NAME_COPY_IMAGE_TESSELLATION_EVALUATION: return "copy_image_tess_eval";
5549 case OPERATION_NAME_COPY_IMAGE_GEOMETRY: return "copy_image_geometry";
5550 case OPERATION_NAME_COPY_IMAGE_FRAGMENT: return "copy_image_fragment";
5551 case OPERATION_NAME_COPY_IMAGE_COMPUTE: return "copy_image_compute";
5552 case OPERATION_NAME_COPY_IMAGE_COMPUTE_INDIRECT: return "copy_image_compute_indirect";
5559 de::MovePtr<OperationSupport> makeOperationSupport (const OperationName opName, const ResourceDescription& resourceDesc)
5563 case OPERATION_NAME_WRITE_FILL_BUFFER: return de::MovePtr<OperationSupport>(new FillUpdateBuffer ::Support (resourceDesc, FillUpdateBuffer::BUFFER_OP_FILL));
5564 case OPERATION_NAME_WRITE_UPDATE_BUFFER: return de::MovePtr<OperationSupport>(new FillUpdateBuffer ::Support (resourceDesc, FillUpdateBuffer::BUFFER_OP_UPDATE));
5565 case OPERATION_NAME_WRITE_COPY_BUFFER: return de::MovePtr<OperationSupport>(new CopyBuffer ::Support (resourceDesc, ACCESS_MODE_WRITE));
5566 case OPERATION_NAME_WRITE_COPY_BUFFER_TO_IMAGE: return de::MovePtr<OperationSupport>(new CopyBufferToImage ::Support (resourceDesc, ACCESS_MODE_WRITE));
5567 case OPERATION_NAME_WRITE_COPY_IMAGE_TO_BUFFER: return de::MovePtr<OperationSupport>(new CopyImageToBuffer ::Support (resourceDesc, ACCESS_MODE_WRITE));
5568 case OPERATION_NAME_WRITE_COPY_IMAGE: return de::MovePtr<OperationSupport>(new CopyBlitResolveImage ::Support (resourceDesc, CopyBlitResolveImage::TYPE_COPY, ACCESS_MODE_WRITE));
5569 case OPERATION_NAME_WRITE_BLIT_IMAGE: return de::MovePtr<OperationSupport>(new CopyBlitResolveImage ::Support (resourceDesc, CopyBlitResolveImage::TYPE_BLIT, ACCESS_MODE_WRITE));
5570 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));
5571 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));
5572 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));
5573 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));
5574 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));
5575 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));
5576 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));
5577 case OPERATION_NAME_WRITE_IMAGE_VERTEX: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_WRITE, VK_SHADER_STAGE_VERTEX_BIT));
5578 case OPERATION_NAME_WRITE_IMAGE_TESSELLATION_CONTROL: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_WRITE, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT));
5579 case OPERATION_NAME_WRITE_IMAGE_TESSELLATION_EVALUATION: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_WRITE, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT));
5580 case OPERATION_NAME_WRITE_IMAGE_GEOMETRY: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_WRITE, VK_SHADER_STAGE_GEOMETRY_BIT));
5581 case OPERATION_NAME_WRITE_IMAGE_FRAGMENT: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_WRITE, VK_SHADER_STAGE_FRAGMENT_BIT));
5582 case OPERATION_NAME_WRITE_IMAGE_COMPUTE: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_WRITE, VK_SHADER_STAGE_COMPUTE_BIT));
5583 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));
5584 case OPERATION_NAME_WRITE_IMAGE_COMPUTE_MULTISAMPLE: return de::MovePtr<OperationSupport>(new ShaderAccess ::MSImageSupport(resourceDesc));
5585 case OPERATION_NAME_WRITE_CLEAR_COLOR_IMAGE: return de::MovePtr<OperationSupport>(new ClearImage ::Support (resourceDesc, ClearImage::CLEAR_MODE_COLOR));
5586 case OPERATION_NAME_WRITE_CLEAR_DEPTH_STENCIL_IMAGE: return de::MovePtr<OperationSupport>(new ClearImage ::Support (resourceDesc, ClearImage::CLEAR_MODE_DEPTH_STENCIL));
5587 case OPERATION_NAME_WRITE_DRAW: return de::MovePtr<OperationSupport>(new Draw ::Support (resourceDesc, Draw::DRAW_CALL_DRAW));
5588 case OPERATION_NAME_WRITE_DRAW_INDEXED: return de::MovePtr<OperationSupport>(new Draw ::Support (resourceDesc, Draw::DRAW_CALL_DRAW_INDEXED));
5589 case OPERATION_NAME_WRITE_DRAW_INDIRECT: return de::MovePtr<OperationSupport>(new Draw ::Support (resourceDesc, Draw::DRAW_CALL_DRAW_INDIRECT));
5590 case OPERATION_NAME_WRITE_DRAW_INDEXED_INDIRECT: return de::MovePtr<OperationSupport>(new Draw ::Support (resourceDesc, Draw::DRAW_CALL_DRAW_INDEXED_INDIRECT));
5591 case OPERATION_NAME_WRITE_CLEAR_ATTACHMENTS: return de::MovePtr<OperationSupport>(new ClearAttachments ::Support (resourceDesc));
5592 case OPERATION_NAME_WRITE_INDIRECT_BUFFER_DRAW: return de::MovePtr<OperationSupport>(new IndirectBuffer ::WriteSupport (resourceDesc));
5593 case OPERATION_NAME_WRITE_INDIRECT_BUFFER_DRAW_INDEXED: return de::MovePtr<OperationSupport>(new IndirectBuffer ::WriteSupport (resourceDesc));
5594 case OPERATION_NAME_WRITE_INDIRECT_BUFFER_DISPATCH: return de::MovePtr<OperationSupport>(new IndirectBuffer ::WriteSupport (resourceDesc));
5595 case OPERATION_NAME_WRITE_UPDATE_INDEX_BUFFER: return de::MovePtr<OperationSupport>(new FillUpdateBuffer ::Support (resourceDesc, FillUpdateBuffer::BUFFER_OP_UPDATE_WITH_INDEX_PATTERN));
5597 case OPERATION_NAME_READ_COPY_BUFFER: return de::MovePtr<OperationSupport>(new CopyBuffer ::Support (resourceDesc, ACCESS_MODE_READ));
5598 case OPERATION_NAME_READ_COPY_BUFFER_TO_IMAGE: return de::MovePtr<OperationSupport>(new CopyBufferToImage ::Support (resourceDesc, ACCESS_MODE_READ));
5599 case OPERATION_NAME_READ_COPY_IMAGE_TO_BUFFER: return de::MovePtr<OperationSupport>(new CopyImageToBuffer ::Support (resourceDesc, ACCESS_MODE_READ));
5600 case OPERATION_NAME_READ_COPY_IMAGE: return de::MovePtr<OperationSupport>(new CopyBlitResolveImage::Support (resourceDesc, CopyBlitResolveImage::TYPE_COPY, ACCESS_MODE_READ));
5601 case OPERATION_NAME_READ_BLIT_IMAGE: return de::MovePtr<OperationSupport>(new CopyBlitResolveImage::Support (resourceDesc, CopyBlitResolveImage::TYPE_BLIT, ACCESS_MODE_READ));
5602 case OPERATION_NAME_READ_RESOLVE_IMAGE: return de::MovePtr<OperationSupport>(new CopyBlitResolveImage::Support (resourceDesc, CopyBlitResolveImage::TYPE_RESOLVE, ACCESS_MODE_READ));
5603 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));
5604 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));
5605 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));
5606 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));
5607 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));
5608 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));
5609 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));
5610 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));
5611 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));
5612 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));
5613 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));
5614 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));
5615 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));
5616 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));
5617 case OPERATION_NAME_READ_IMAGE_VERTEX: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_READ, VK_SHADER_STAGE_VERTEX_BIT));
5618 case OPERATION_NAME_READ_IMAGE_TESSELLATION_CONTROL: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_READ, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT));
5619 case OPERATION_NAME_READ_IMAGE_TESSELLATION_EVALUATION: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_READ, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT));
5620 case OPERATION_NAME_READ_IMAGE_GEOMETRY: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_READ, VK_SHADER_STAGE_GEOMETRY_BIT));
5621 case OPERATION_NAME_READ_IMAGE_FRAGMENT: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_READ, VK_SHADER_STAGE_FRAGMENT_BIT));
5622 case OPERATION_NAME_READ_IMAGE_COMPUTE: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_READ, VK_SHADER_STAGE_COMPUTE_BIT));
5623 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));
5624 case OPERATION_NAME_READ_INDIRECT_BUFFER_DRAW: return de::MovePtr<OperationSupport>(new IndirectBuffer ::ReadSupport (resourceDesc));
5625 case OPERATION_NAME_READ_INDIRECT_BUFFER_DRAW_INDEXED: return de::MovePtr<OperationSupport>(new IndirectBuffer ::ReadSupport (resourceDesc));
5626 case OPERATION_NAME_READ_INDIRECT_BUFFER_DISPATCH: return de::MovePtr<OperationSupport>(new IndirectBuffer ::ReadSupport (resourceDesc));
5627 case OPERATION_NAME_READ_VERTEX_INPUT: return de::MovePtr<OperationSupport>(new VertexInput ::Support (resourceDesc, VertexInput::DRAW_MODE_VERTEX));
5628 case OPERATION_NAME_READ_INDEX_INPUT: return de::MovePtr<OperationSupport>(new VertexInput ::Support (resourceDesc, VertexInput::DRAW_MODE_INDEXED));
5630 case OPERATION_NAME_COPY_BUFFER: return de::MovePtr<OperationSupport>(new CopyBuffer ::CopySupport (resourceDesc));
5631 case OPERATION_NAME_COPY_IMAGE: return de::MovePtr<OperationSupport>(new CopyBlitResolveImage::CopySupport (resourceDesc, CopyBlitResolveImage::TYPE_COPY));
5632 case OPERATION_NAME_BLIT_IMAGE: return de::MovePtr<OperationSupport>(new CopyBlitResolveImage::CopySupport (resourceDesc, CopyBlitResolveImage::TYPE_BLIT));
5633 case OPERATION_NAME_COPY_SSBO_VERTEX: return de::MovePtr<OperationSupport>(new ShaderAccess ::CopyBufferSupport (resourceDesc, BUFFER_TYPE_STORAGE, VK_SHADER_STAGE_VERTEX_BIT));
5634 case OPERATION_NAME_COPY_SSBO_TESSELLATION_CONTROL: return de::MovePtr<OperationSupport>(new ShaderAccess ::CopyBufferSupport (resourceDesc, BUFFER_TYPE_STORAGE, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT));
5635 case OPERATION_NAME_COPY_SSBO_TESSELLATION_EVALUATION: return de::MovePtr<OperationSupport>(new ShaderAccess ::CopyBufferSupport (resourceDesc, BUFFER_TYPE_STORAGE, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT));
5636 case OPERATION_NAME_COPY_SSBO_GEOMETRY: return de::MovePtr<OperationSupport>(new ShaderAccess ::CopyBufferSupport (resourceDesc, BUFFER_TYPE_STORAGE, VK_SHADER_STAGE_GEOMETRY_BIT));
5637 case OPERATION_NAME_COPY_SSBO_FRAGMENT: return de::MovePtr<OperationSupport>(new ShaderAccess ::CopyBufferSupport (resourceDesc, BUFFER_TYPE_STORAGE, VK_SHADER_STAGE_FRAGMENT_BIT));
5638 case OPERATION_NAME_COPY_SSBO_COMPUTE: return de::MovePtr<OperationSupport>(new ShaderAccess ::CopyBufferSupport (resourceDesc, BUFFER_TYPE_STORAGE, VK_SHADER_STAGE_COMPUTE_BIT));
5639 case OPERATION_NAME_COPY_SSBO_COMPUTE_INDIRECT: return de::MovePtr<OperationSupport>(new ShaderAccess ::CopyBufferSupport (resourceDesc, BUFFER_TYPE_STORAGE, VK_SHADER_STAGE_COMPUTE_BIT, ShaderAccess::DISPATCH_CALL_DISPATCH_INDIRECT));
5640 case OPERATION_NAME_COPY_IMAGE_VERTEX: return de::MovePtr<OperationSupport>(new ShaderAccess ::CopyImageSupport (resourceDesc, VK_SHADER_STAGE_VERTEX_BIT));
5641 case OPERATION_NAME_COPY_IMAGE_TESSELLATION_CONTROL: return de::MovePtr<OperationSupport>(new ShaderAccess ::CopyImageSupport (resourceDesc, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT));
5642 case OPERATION_NAME_COPY_IMAGE_TESSELLATION_EVALUATION: return de::MovePtr<OperationSupport>(new ShaderAccess ::CopyImageSupport (resourceDesc, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT));
5643 case OPERATION_NAME_COPY_IMAGE_GEOMETRY: return de::MovePtr<OperationSupport>(new ShaderAccess ::CopyImageSupport (resourceDesc, VK_SHADER_STAGE_GEOMETRY_BIT));
5644 case OPERATION_NAME_COPY_IMAGE_FRAGMENT: return de::MovePtr<OperationSupport>(new ShaderAccess ::CopyImageSupport (resourceDesc, VK_SHADER_STAGE_FRAGMENT_BIT));
5645 case OPERATION_NAME_COPY_IMAGE_COMPUTE: return de::MovePtr<OperationSupport>(new ShaderAccess ::CopyImageSupport (resourceDesc, VK_SHADER_STAGE_COMPUTE_BIT));
5646 case OPERATION_NAME_COPY_IMAGE_COMPUTE_INDIRECT: return de::MovePtr<OperationSupport>(new ShaderAccess ::CopyImageSupport (resourceDesc, VK_SHADER_STAGE_COMPUTE_BIT, ShaderAccess::DISPATCH_CALL_DISPATCH_INDIRECT));
5650 return de::MovePtr<OperationSupport>();
5654 } // synchronization