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_VERTEX_SHADER_BIT;
284 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: return VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT;
285 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: return VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT;
286 case VK_SHADER_STAGE_GEOMETRY_BIT: return VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT;
287 case VK_SHADER_STAGE_FRAGMENT_BIT: return VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
288 case VK_SHADER_STAGE_COMPUTE_BIT: return VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
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)
300 static const deUint8 pattern[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31 };
301 deUint8* const pBytes = static_cast<deUint8*>(pData);
303 for (deUint32 i = 0; i < size; ++i)
304 pBytes[i] = pattern[i % DE_LENGTH_OF_ARRAY(pattern)];
307 //! Get size in bytes of a pixel buffer with given extent.
308 VkDeviceSize getPixelBufferSize (const VkFormat format, const VkExtent3D& extent)
310 const int pixelSize = tcu::getPixelSize(mapVkFormat(format));
311 return (pixelSize * extent.width * extent.height * extent.depth);
314 //! Determine the size of a 2D image that can hold sizeBytes data.
315 VkExtent3D get2DImageExtentWithSize (const VkDeviceSize sizeBytes, const deUint32 pixelSize)
317 const deUint32 size = static_cast<deUint32>(sizeBytes / pixelSize);
319 DE_ASSERT(size <= MAX_IMAGE_DIMENSION_2D * MAX_IMAGE_DIMENSION_2D);
322 std::min(size, static_cast<deUint32>(MAX_IMAGE_DIMENSION_2D)),
323 (size / MAX_IMAGE_DIMENSION_2D) + (size % MAX_IMAGE_DIMENSION_2D != 0 ? 1u : 0u),
327 VkClearValue makeClearValue (const VkFormat format)
329 if (isDepthStencilFormat(format))
330 return makeClearValueDepthStencil(0.4f, 21u);
333 if (isIntFormat(format) || isUintFormat(format))
334 return makeClearValueColorU32(8u, 16u, 24u, 32u);
336 return makeClearValueColorF32(0.25f, 0.49f, 0.75f, 1.0f);
340 void clearPixelBuffer (tcu::PixelBufferAccess& pixels, const VkClearValue& clearValue)
342 const tcu::TextureFormat format = pixels.getFormat();
343 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
345 if (format.order == tcu::TextureFormat::D)
347 for (int z = 0; z < pixels.getDepth(); z++)
348 for (int y = 0; y < pixels.getHeight(); y++)
349 for (int x = 0; x < pixels.getWidth(); x++)
350 pixels.setPixDepth(clearValue.depthStencil.depth, x, y, z);
352 else if (format.order == tcu::TextureFormat::S)
354 for (int z = 0; z < pixels.getDepth(); z++)
355 for (int y = 0; y < pixels.getHeight(); y++)
356 for (int x = 0; x < pixels.getWidth(); x++)
357 pixels.setPixStencil(clearValue.depthStencil.stencil, x, y, z);
359 else if (format.order == tcu::TextureFormat::DS)
361 for (int z = 0; z < pixels.getDepth(); z++)
362 for (int y = 0; y < pixels.getHeight(); y++)
363 for (int x = 0; x < pixels.getWidth(); x++)
365 pixels.setPixDepth(clearValue.depthStencil.depth, x, y, z);
366 pixels.setPixStencil(clearValue.depthStencil.stencil, x, y, z);
369 else if (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
371 const tcu::UVec4 color (clearValue.color.uint32);
373 for (int z = 0; z < pixels.getDepth(); z++)
374 for (int y = 0; y < pixels.getHeight(); y++)
375 for (int x = 0; x < pixels.getWidth(); x++)
376 pixels.setPixel(color, x, y, z);
380 const tcu::Vec4 color (clearValue.color.float32);
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 //! Storage image format that requires StorageImageExtendedFormats SPIR-V capability (listed only Vulkan-defined formats).
390 bool isStorageImageExtendedFormat (const VkFormat format)
394 case VK_FORMAT_R32G32_SFLOAT:
395 case VK_FORMAT_R32G32_SINT:
396 case VK_FORMAT_R32G32_UINT:
397 case VK_FORMAT_R16G16B16A16_UNORM:
398 case VK_FORMAT_R16G16B16A16_SNORM:
399 case VK_FORMAT_R16G16_SFLOAT:
400 case VK_FORMAT_R16G16_UNORM:
401 case VK_FORMAT_R16G16_SNORM:
402 case VK_FORMAT_R16G16_SINT:
403 case VK_FORMAT_R16G16_UINT:
404 case VK_FORMAT_R16_SFLOAT:
405 case VK_FORMAT_R16_UNORM:
406 case VK_FORMAT_R16_SNORM:
407 case VK_FORMAT_R16_SINT:
408 case VK_FORMAT_R16_UINT:
409 case VK_FORMAT_R8G8_UNORM:
410 case VK_FORMAT_R8G8_SNORM:
411 case VK_FORMAT_R8G8_SINT:
412 case VK_FORMAT_R8G8_UINT:
413 case VK_FORMAT_R8_UNORM:
414 case VK_FORMAT_R8_SNORM:
415 case VK_FORMAT_R8_SINT:
416 case VK_FORMAT_R8_UINT:
424 VkImageViewType getImageViewType (const VkImageType imageType)
428 case VK_IMAGE_TYPE_1D: return VK_IMAGE_VIEW_TYPE_1D;
429 case VK_IMAGE_TYPE_2D: return VK_IMAGE_VIEW_TYPE_2D;
430 case VK_IMAGE_TYPE_3D: return VK_IMAGE_VIEW_TYPE_3D;
433 DE_FATAL("Unknown image type");
434 return VK_IMAGE_VIEW_TYPE_LAST;
438 std::string getShaderImageType (const VkFormat format, const VkImageType imageType)
440 const tcu::TextureFormat texFormat = mapVkFormat(format);
441 const std::string formatPart = tcu::getTextureChannelClass(texFormat.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ? "u" :
442 tcu::getTextureChannelClass(texFormat.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ? "i" : "";
445 case VK_IMAGE_TYPE_1D: return formatPart + "image1D";
446 case VK_IMAGE_TYPE_2D: return formatPart + "image2D";
447 case VK_IMAGE_TYPE_3D: return formatPart + "image3D";
450 DE_FATAL("Unknown image type");
455 std::string getShaderImageFormatQualifier (const VkFormat format)
457 const tcu::TextureFormat texFormat = mapVkFormat(format);
458 const char* orderPart = DE_NULL;
459 const char* typePart = DE_NULL;
461 switch (texFormat.order)
463 case tcu::TextureFormat::R: orderPart = "r"; break;
464 case tcu::TextureFormat::RG: orderPart = "rg"; break;
465 case tcu::TextureFormat::RGB: orderPart = "rgb"; break;
466 case tcu::TextureFormat::RGBA: orderPart = "rgba"; break;
469 DE_FATAL("Unksupported texture channel order");
473 switch (texFormat.type)
475 case tcu::TextureFormat::FLOAT: typePart = "32f"; break;
476 case tcu::TextureFormat::HALF_FLOAT: typePart = "16f"; break;
478 case tcu::TextureFormat::UNSIGNED_INT32: typePart = "32ui"; break;
479 case tcu::TextureFormat::UNSIGNED_INT16: typePart = "16ui"; break;
480 case tcu::TextureFormat::UNSIGNED_INT8: typePart = "8ui"; break;
482 case tcu::TextureFormat::SIGNED_INT32: typePart = "32i"; break;
483 case tcu::TextureFormat::SIGNED_INT16: typePart = "16i"; break;
484 case tcu::TextureFormat::SIGNED_INT8: typePart = "8i"; break;
486 case tcu::TextureFormat::UNORM_INT16: typePart = "16"; break;
487 case tcu::TextureFormat::UNORM_INT8: typePart = "8"; break;
489 case tcu::TextureFormat::SNORM_INT16: typePart = "16_snorm"; break;
490 case tcu::TextureFormat::SNORM_INT8: typePart = "8_snorm"; break;
493 DE_FATAL("Unksupported texture channel type");
497 return std::string(orderPart) + typePart;
500 namespace FillUpdateBuffer
509 class Implementation : public Operation
512 Implementation (OperationContext& context, Resource& resource, const BufferOp bufferOp)
513 : m_context (context)
514 , m_resource (resource)
516 , m_bufferOp (bufferOp)
518 DE_ASSERT((m_resource.getBuffer().size % sizeof(deUint32)) == 0);
519 DE_ASSERT(m_bufferOp == BUFFER_OP_FILL || m_resource.getBuffer().size <= MAX_UPDATE_BUFFER_SIZE);
521 m_data.resize(static_cast<size_t>(m_resource.getBuffer().size));
523 if (m_bufferOp == BUFFER_OP_FILL)
525 const std::size_t size = m_data.size() / sizeof(m_fillValue);
526 deUint32* const pData = reinterpret_cast<deUint32*>(&m_data[0]);
528 for (deUint32 i = 0; i < size; ++i)
529 pData[i] = m_fillValue;
531 else if (m_bufferOp == BUFFER_OP_UPDATE)
533 fillPattern(&m_data[0], m_data.size());
542 void recordCommands (const VkCommandBuffer cmdBuffer)
544 const DeviceInterface& vk = m_context.getDeviceInterface();
546 if (m_bufferOp == BUFFER_OP_FILL)
547 vk.cmdFillBuffer(cmdBuffer, m_resource.getBuffer().handle, m_resource.getBuffer().offset, m_resource.getBuffer().size, m_fillValue);
548 else if (m_bufferOp == BUFFER_OP_UPDATE)
549 vk.cmdUpdateBuffer(cmdBuffer, m_resource.getBuffer().handle, m_resource.getBuffer().offset, m_resource.getBuffer().size, reinterpret_cast<deUint32*>(&m_data[0]));
557 SyncInfo getInSyncInfo (void) const
559 return emptySyncInfo;
562 SyncInfo getOutSyncInfo (void) const
564 const SyncInfo syncInfo =
566 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
567 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags accessMask;
568 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
574 Data getData (void) const
578 m_data.size(), // std::size_t size;
579 &m_data[0], // const deUint8* data;
584 void setData (const Data& data)
586 deMemcpy(&m_data[0], data.data, data.size);
590 OperationContext& m_context;
591 Resource& m_resource;
592 std::vector<deUint8> m_data;
593 const deUint32 m_fillValue;
594 const BufferOp m_bufferOp;
597 class Support : public OperationSupport
600 Support (const ResourceDescription& resourceDesc, const BufferOp bufferOp)
601 : m_resourceDesc (resourceDesc)
602 , m_bufferOp (bufferOp)
604 DE_ASSERT(m_bufferOp == BUFFER_OP_FILL || m_bufferOp == BUFFER_OP_UPDATE);
605 DE_ASSERT(m_resourceDesc.type == RESOURCE_TYPE_BUFFER);
608 deUint32 getInResourceUsageFlags (void) const
613 deUint32 getOutResourceUsageFlags (void) const
615 return VK_BUFFER_USAGE_TRANSFER_DST_BIT;
618 VkQueueFlags getQueueFlags (const OperationContext& context) const
620 if (m_bufferOp == BUFFER_OP_FILL && !context.isDeviceFunctionalitySupported("VK_KHR_maintenance1"))
622 return VK_QUEUE_COMPUTE_BIT | VK_QUEUE_GRAPHICS_BIT;
625 return VK_QUEUE_TRANSFER_BIT;
628 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
630 return de::MovePtr<Operation>(new Implementation(context, resource, m_bufferOp));
633 de::MovePtr<Operation> build (OperationContext&, Resource&, Resource&) const
636 return de::MovePtr<Operation>();
640 const ResourceDescription m_resourceDesc;
641 const BufferOp m_bufferOp;
644 } // FillUpdateBuffer ns
649 class Implementation : public Operation
652 Implementation (OperationContext& context, Resource& resource, const AccessMode mode)
653 : m_context (context)
654 , m_resource (resource)
657 const DeviceInterface& vk = m_context.getDeviceInterface();
658 const VkDevice device = m_context.getDevice();
659 Allocator& allocator = m_context.getAllocator();
660 const VkBufferUsageFlags hostBufferUsage = (m_mode == ACCESS_MODE_READ ? VK_BUFFER_USAGE_TRANSFER_DST_BIT : VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
662 m_hostBuffer = de::MovePtr<Buffer>(new Buffer(vk, device, allocator, makeBufferCreateInfo(m_resource.getBuffer().size, hostBufferUsage), MemoryRequirement::HostVisible));
664 const Allocation& alloc = m_hostBuffer->getAllocation();
666 if (m_mode == ACCESS_MODE_READ)
667 deMemset(alloc.getHostPtr(), 0, static_cast<size_t>(m_resource.getBuffer().size));
669 fillPattern(alloc.getHostPtr(), m_resource.getBuffer().size);
671 flushAlloc(vk, device, alloc);
674 void recordCommands (const VkCommandBuffer cmdBuffer)
676 const DeviceInterface& vk = m_context.getDeviceInterface();
677 const VkBufferCopy copyRegion = makeBufferCopy(0u, 0u, m_resource.getBuffer().size);
679 if (m_mode == ACCESS_MODE_READ)
681 vk.cmdCopyBuffer(cmdBuffer, m_resource.getBuffer().handle, **m_hostBuffer, 1u, ©Region);
683 // Insert a barrier so copied data is available to the host
684 const VkBufferMemoryBarrier barrier = makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, **m_hostBuffer, 0u, m_resource.getBuffer().size);
685 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
689 // // Insert a barrier so buffer data is available to the device
690 // const VkBufferMemoryBarrier barrier = makeBufferMemoryBarrier(VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, **m_hostBuffer, 0u, m_resource.getBuffer().size);
691 // vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
693 vk.cmdCopyBuffer(cmdBuffer, **m_hostBuffer, m_resource.getBuffer().handle, 1u, ©Region);
697 SyncInfo getInSyncInfo (void) const
699 const VkAccessFlags access = (m_mode == ACCESS_MODE_READ ? VK_ACCESS_TRANSFER_READ_BIT : 0);
700 const SyncInfo syncInfo =
702 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
703 access, // VkAccessFlags accessMask;
704 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
709 SyncInfo getOutSyncInfo (void) const
711 const VkAccessFlags access = (m_mode == ACCESS_MODE_WRITE ? VK_ACCESS_TRANSFER_WRITE_BIT : 0);
712 const SyncInfo syncInfo =
714 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
715 access, // VkAccessFlags accessMask;
716 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
721 Data getData (void) const
723 return getHostBufferData(m_context, *m_hostBuffer, m_resource.getBuffer().size);
726 void setData (const Data& data)
728 DE_ASSERT(m_mode == ACCESS_MODE_WRITE);
729 setHostBufferData(m_context, *m_hostBuffer, data);
733 OperationContext& m_context;
734 Resource& m_resource;
735 const AccessMode m_mode;
736 de::MovePtr<Buffer> m_hostBuffer;
739 class Support : public OperationSupport
742 Support (const ResourceDescription& resourceDesc, const AccessMode mode)
745 DE_ASSERT(resourceDesc.type == RESOURCE_TYPE_BUFFER);
746 DE_UNREF(resourceDesc);
749 deUint32 getInResourceUsageFlags (void) const
751 return m_mode == ACCESS_MODE_READ ? VK_BUFFER_USAGE_TRANSFER_SRC_BIT : 0;
754 deUint32 getOutResourceUsageFlags (void) const
756 return m_mode == ACCESS_MODE_WRITE ? VK_BUFFER_USAGE_TRANSFER_DST_BIT : 0;
759 VkQueueFlags getQueueFlags (const OperationContext& context) const
762 return VK_QUEUE_TRANSFER_BIT;
765 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
767 return de::MovePtr<Operation>(new Implementation(context, resource, m_mode));
770 de::MovePtr<Operation> build (OperationContext&, Resource&, Resource&) const
773 return de::MovePtr<Operation>();
777 const AccessMode m_mode;
780 class CopyImplementation : public Operation
783 CopyImplementation (OperationContext& context, Resource& inResource, Resource& outResource)
784 : m_context (context)
785 , m_inResource (inResource)
786 , m_outResource (outResource)
790 void recordCommands (const VkCommandBuffer cmdBuffer)
792 const DeviceInterface& vk = m_context.getDeviceInterface();
793 const VkBufferCopy copyRegion = makeBufferCopy(0u, 0u, m_inResource.getBuffer().size);
795 vk.cmdCopyBuffer(cmdBuffer, m_inResource.getBuffer().handle, m_outResource.getBuffer().handle, 1u, ©Region);
798 SyncInfo getInSyncInfo (void) const
800 const SyncInfo syncInfo =
802 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
803 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags accessMask;
804 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
809 SyncInfo getOutSyncInfo (void) const
811 const SyncInfo syncInfo =
813 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
814 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags accessMask;
815 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
820 Data getData (void) const
822 Data data = { 0, DE_NULL };
826 void setData (const Data&)
832 OperationContext& m_context;
833 Resource& m_inResource;
834 Resource& m_outResource;
835 de::MovePtr<Buffer> m_hostBuffer;
838 class CopySupport : public OperationSupport
841 CopySupport (const ResourceDescription& resourceDesc)
843 DE_ASSERT(resourceDesc.type == RESOURCE_TYPE_BUFFER);
844 DE_UNREF(resourceDesc);
847 deUint32 getInResourceUsageFlags (void) const
849 return VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
852 deUint32 getOutResourceUsageFlags (void) const
854 return VK_BUFFER_USAGE_TRANSFER_DST_BIT;
857 VkQueueFlags getQueueFlags (const OperationContext& context) const
860 return VK_QUEUE_TRANSFER_BIT;
863 de::MovePtr<Operation> build (OperationContext&, Resource&) const
866 return de::MovePtr<Operation>();
869 de::MovePtr<Operation> build (OperationContext& context, Resource& inResource, Resource& outResource) const
871 return de::MovePtr<Operation>(new CopyImplementation(context, inResource, outResource));
877 namespace CopyBlitImage
880 class ImplementationBase : public Operation
883 //! Copy/Blit/Resolve etc. operation
884 virtual void recordCopyCommand (const VkCommandBuffer cmdBuffer) = 0;
886 ImplementationBase (OperationContext& context, Resource& resource, const AccessMode mode)
887 : m_context (context)
888 , m_resource (resource)
890 , m_bufferSize (getPixelBufferSize(m_resource.getImage().format, m_resource.getImage().extent))
892 const DeviceInterface& vk = m_context.getDeviceInterface();
893 const VkDevice device = m_context.getDevice();
894 Allocator& allocator = m_context.getAllocator();
896 m_hostBuffer = de::MovePtr<Buffer>(new Buffer(
897 vk, device, allocator, makeBufferCreateInfo(m_bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT),
898 MemoryRequirement::HostVisible));
900 const Allocation& alloc = m_hostBuffer->getAllocation();
901 if (m_mode == ACCESS_MODE_READ)
902 deMemset(alloc.getHostPtr(), 0, static_cast<size_t>(m_bufferSize));
904 fillPattern(alloc.getHostPtr(), m_bufferSize);
905 flushAlloc(vk, device, alloc);
908 m_image = de::MovePtr<Image>(new Image(
909 vk, device, allocator,
910 makeImageCreateInfo(m_resource.getImage().imageType, m_resource.getImage().extent, m_resource.getImage().format, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT),
911 MemoryRequirement::Any));
914 void recordCommands (const VkCommandBuffer cmdBuffer)
916 const DeviceInterface& vk = m_context.getDeviceInterface();
917 const VkBufferImageCopy bufferCopyRegion = makeBufferImageCopy(m_resource.getImage().extent, m_resource.getImage().subresourceLayers);
919 const VkImageMemoryBarrier stagingImageTransferSrcLayoutBarrier = makeImageMemoryBarrier(
920 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
921 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
922 **m_image, m_resource.getImage().subresourceRange);
924 // Staging image layout
926 const VkImageMemoryBarrier layoutBarrier = makeImageMemoryBarrier(
927 (VkAccessFlags)0, VK_ACCESS_TRANSFER_WRITE_BIT,
928 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
929 **m_image, m_resource.getImage().subresourceRange);
931 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
932 0u, DE_NULL, 0u, DE_NULL, 1u, &layoutBarrier);
935 if (m_mode == ACCESS_MODE_READ)
937 // Resource Image -> Staging image
938 recordCopyCommand(cmdBuffer);
940 // Staging image layout
941 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
942 0u, DE_NULL, 0u, DE_NULL, 1u, &stagingImageTransferSrcLayoutBarrier);
944 // Image -> Host buffer
945 vk.cmdCopyImageToBuffer(cmdBuffer, **m_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_hostBuffer, 1u, &bufferCopyRegion);
947 // Insert a barrier so copied data is available to the host
948 const VkBufferMemoryBarrier barrier = makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, **m_hostBuffer, 0u, m_bufferSize);
949 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
953 // Host buffer -> Staging image
954 vk.cmdCopyBufferToImage(cmdBuffer, **m_hostBuffer, **m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &bufferCopyRegion);
956 // Staging image layout
957 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
958 0u, DE_NULL, 0u, DE_NULL, 1u, &stagingImageTransferSrcLayoutBarrier);
960 // Resource image layout
962 const VkImageMemoryBarrier layoutBarrier = makeImageMemoryBarrier(
963 (VkAccessFlags)0, VK_ACCESS_TRANSFER_WRITE_BIT,
964 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
965 m_resource.getImage().handle, m_resource.getImage().subresourceRange);
967 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
968 0u, DE_NULL, 0u, DE_NULL, 1u, &layoutBarrier);
971 // Staging image -> Resource Image
972 recordCopyCommand(cmdBuffer);
976 SyncInfo getInSyncInfo (void) const
978 const VkAccessFlags access = (m_mode == ACCESS_MODE_READ ? VK_ACCESS_TRANSFER_READ_BIT : VK_ACCESS_TRANSFER_WRITE_BIT);
979 const VkImageLayout layout = (m_mode == ACCESS_MODE_READ ? VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL : VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
980 const SyncInfo syncInfo =
982 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
983 access, // VkAccessFlags accessMask;
984 layout, // VkImageLayout imageLayout;
989 SyncInfo getOutSyncInfo (void) const
991 const VkAccessFlags access = (m_mode == ACCESS_MODE_READ ? VK_ACCESS_TRANSFER_READ_BIT : VK_ACCESS_TRANSFER_WRITE_BIT);
992 const VkImageLayout layout = (m_mode == ACCESS_MODE_READ ? VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL : VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
993 const SyncInfo syncInfo =
995 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
996 access, // VkAccessFlags accessMask;
997 layout, // VkImageLayout imageLayout;
1002 Data getData (void) const
1004 return getHostBufferData(m_context, *m_hostBuffer, m_bufferSize);
1007 void setData (const Data& data)
1009 DE_ASSERT(m_mode == ACCESS_MODE_WRITE);
1010 setHostBufferData(m_context, *m_hostBuffer, data);
1014 OperationContext& m_context;
1015 Resource& m_resource;
1016 const AccessMode m_mode;
1017 const VkDeviceSize m_bufferSize;
1018 de::MovePtr<Buffer> m_hostBuffer;
1019 de::MovePtr<Image> m_image;
1022 VkOffset3D makeExtentOffset (const Resource& resource)
1024 DE_ASSERT(resource.getType() == RESOURCE_TYPE_IMAGE);
1025 const VkExtent3D extent = resource.getImage().extent;
1027 switch (resource.getImage().imageType)
1029 case VK_IMAGE_TYPE_1D: return makeOffset3D(extent.width, 1, 1);
1030 case VK_IMAGE_TYPE_2D: return makeOffset3D(extent.width, extent.height, 1);
1031 case VK_IMAGE_TYPE_3D: return makeOffset3D(extent.width, extent.height, extent.depth);
1034 return VkOffset3D();
1038 VkImageBlit makeBlitRegion (const Resource& resource)
1040 const VkImageBlit blitRegion =
1042 resource.getImage().subresourceLayers, // VkImageSubresourceLayers srcSubresource;
1043 { makeOffset3D(0, 0, 0), makeExtentOffset(resource) }, // VkOffset3D srcOffsets[2];
1044 resource.getImage().subresourceLayers, // VkImageSubresourceLayers dstSubresource;
1045 { makeOffset3D(0, 0, 0), makeExtentOffset(resource) }, // VkOffset3D dstOffsets[2];
1050 class BlitImplementation : public ImplementationBase
1053 BlitImplementation (OperationContext& context, Resource& resource, const AccessMode mode)
1054 : ImplementationBase (context, resource, mode)
1055 , m_blitRegion (makeBlitRegion(m_resource))
1057 const InstanceInterface& vki = m_context.getInstanceInterface();
1058 const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
1059 const VkFormatProperties formatProps = getPhysicalDeviceFormatProperties(vki, physDevice, m_resource.getImage().format);
1060 const VkFormatFeatureFlags requiredFlags = (VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT);
1062 // SRC and DST blit is required because both images are using the same format.
1063 if ((formatProps.optimalTilingFeatures & requiredFlags) != requiredFlags)
1064 TCU_THROW(NotSupportedError, "Format doesn't support blits");
1067 void recordCopyCommand (const VkCommandBuffer cmdBuffer)
1069 const DeviceInterface& vk = m_context.getDeviceInterface();
1071 if (m_mode == ACCESS_MODE_READ)
1073 // Resource Image -> Staging image
1074 vk.cmdBlitImage(cmdBuffer, m_resource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1075 1u, &m_blitRegion, VK_FILTER_NEAREST);
1079 // Staging image -> Resource Image
1080 vk.cmdBlitImage(cmdBuffer, **m_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_resource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1081 1u, &m_blitRegion, VK_FILTER_NEAREST);
1086 const VkImageBlit m_blitRegion;
1089 VkImageCopy makeImageCopyRegion (const Resource& resource)
1091 const VkImageCopy imageCopyRegion =
1093 resource.getImage().subresourceLayers, // VkImageSubresourceLayers srcSubresource;
1094 makeOffset3D(0, 0, 0), // VkOffset3D srcOffset;
1095 resource.getImage().subresourceLayers, // VkImageSubresourceLayers dstSubresource;
1096 makeOffset3D(0, 0, 0), // VkOffset3D dstOffset;
1097 resource.getImage().extent, // VkExtent3D extent;
1099 return imageCopyRegion;
1102 class CopyImplementation : public ImplementationBase
1105 CopyImplementation (OperationContext& context, Resource& resource, const AccessMode mode)
1106 : ImplementationBase (context, resource, mode)
1107 , m_imageCopyRegion (makeImageCopyRegion(m_resource))
1111 void recordCopyCommand (const VkCommandBuffer cmdBuffer)
1113 const DeviceInterface& vk = m_context.getDeviceInterface();
1115 if (m_mode == ACCESS_MODE_READ)
1117 // Resource Image -> Staging image
1118 vk.cmdCopyImage(cmdBuffer, m_resource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &m_imageCopyRegion);
1122 // Staging image -> Resource Image
1123 vk.cmdCopyImage(cmdBuffer, **m_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_resource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &m_imageCopyRegion);
1128 const VkImageCopy m_imageCopyRegion;
1137 class Support : public OperationSupport
1140 Support (const ResourceDescription& resourceDesc, const Type type, const AccessMode mode)
1144 DE_ASSERT(resourceDesc.type == RESOURCE_TYPE_IMAGE);
1146 const bool isDepthStencil = isDepthStencilFormat(resourceDesc.imageFormat);
1147 m_requiredQueueFlags = (isDepthStencil || m_type == TYPE_BLIT ? VK_QUEUE_GRAPHICS_BIT : VK_QUEUE_TRANSFER_BIT);
1149 // Don't blit depth/stencil images.
1150 DE_ASSERT(m_type != TYPE_BLIT || !isDepthStencil);
1153 deUint32 getInResourceUsageFlags (void) const
1155 return (m_mode == ACCESS_MODE_READ ? VK_IMAGE_USAGE_TRANSFER_SRC_BIT : 0);
1158 deUint32 getOutResourceUsageFlags (void) const
1160 return (m_mode == ACCESS_MODE_WRITE ? VK_IMAGE_USAGE_TRANSFER_DST_BIT : 0);
1163 VkQueueFlags getQueueFlags (const OperationContext& context) const
1166 return m_requiredQueueFlags;
1169 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
1171 if (m_type == TYPE_COPY)
1172 return de::MovePtr<Operation>(new CopyImplementation(context, resource, m_mode));
1174 return de::MovePtr<Operation>(new BlitImplementation(context, resource, m_mode));
1177 de::MovePtr<Operation> build (OperationContext&, Resource&, Resource&) const
1180 return de::MovePtr<Operation>();
1185 const AccessMode m_mode;
1186 VkQueueFlags m_requiredQueueFlags;
1189 class BlitCopyImplementation : public Operation
1192 BlitCopyImplementation (OperationContext& context, Resource& inResource, Resource& outResource)
1193 : m_context (context)
1194 , m_inResource (inResource)
1195 , m_outResource (outResource)
1196 , m_blitRegion (makeBlitRegion(m_inResource))
1198 DE_ASSERT(m_inResource.getType() == RESOURCE_TYPE_IMAGE);
1199 DE_ASSERT(m_outResource.getType() == RESOURCE_TYPE_IMAGE);
1201 const InstanceInterface& vki = m_context.getInstanceInterface();
1202 const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
1203 const VkFormatProperties formatProps = getPhysicalDeviceFormatProperties(vki, physDevice, m_inResource.getImage().format);
1204 const VkFormatFeatureFlags requiredFlags = (VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT);
1206 // SRC and DST blit is required because both images are using the same format.
1207 if ((formatProps.optimalTilingFeatures & requiredFlags) != requiredFlags)
1208 TCU_THROW(NotSupportedError, "Format doesn't support blits");
1211 void recordCommands (const VkCommandBuffer cmdBuffer)
1213 const DeviceInterface& vk = m_context.getDeviceInterface();
1216 const VkImageMemoryBarrier layoutBarrier =
1217 makeImageMemoryBarrier(
1218 (VkAccessFlags)0, VK_ACCESS_TRANSFER_WRITE_BIT,
1219 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1220 m_outResource.getImage().handle, m_outResource.getImage().subresourceRange);
1222 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
1223 0u, DE_NULL, 0u, DE_NULL, 1u, &layoutBarrier);
1226 vk.cmdBlitImage(cmdBuffer,
1227 m_inResource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1228 m_outResource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1229 1u, &m_blitRegion, VK_FILTER_NEAREST);
1232 SyncInfo getInSyncInfo (void) const
1234 const SyncInfo syncInfo =
1236 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
1237 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags accessMask;
1238 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout imageLayout;
1243 SyncInfo getOutSyncInfo (void) const
1245 const SyncInfo syncInfo =
1247 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
1248 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags accessMask;
1249 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout imageLayout;
1254 Data getData (void) const
1256 Data data = { 0, DE_NULL };
1260 void setData (const Data&)
1266 OperationContext& m_context;
1267 Resource& m_inResource;
1268 Resource& m_outResource;
1269 const VkImageBlit m_blitRegion;
1272 class CopyCopyImplementation : public Operation
1275 CopyCopyImplementation (OperationContext& context, Resource& inResource, Resource& outResource)
1276 : m_context (context)
1277 , m_inResource (inResource)
1278 , m_outResource (outResource)
1279 , m_imageCopyRegion (makeImageCopyRegion(m_inResource))
1281 DE_ASSERT(m_inResource.getType() == RESOURCE_TYPE_IMAGE);
1282 DE_ASSERT(m_outResource.getType() == RESOURCE_TYPE_IMAGE);
1285 void recordCommands (const VkCommandBuffer cmdBuffer)
1287 const DeviceInterface& vk = m_context.getDeviceInterface();
1290 const VkImageMemoryBarrier layoutBarrier =
1291 makeImageMemoryBarrier(
1292 (VkAccessFlags)0, VK_ACCESS_TRANSFER_WRITE_BIT,
1293 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1294 m_outResource.getImage().handle, m_outResource.getImage().subresourceRange);
1296 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
1297 0u, DE_NULL, 0u, DE_NULL, 1u, &layoutBarrier);
1300 vk.cmdCopyImage(cmdBuffer,
1301 m_inResource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1302 m_outResource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1303 1u, &m_imageCopyRegion);
1306 SyncInfo getInSyncInfo (void) const
1308 const SyncInfo syncInfo =
1310 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
1311 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags accessMask;
1312 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout imageLayout;
1317 SyncInfo getOutSyncInfo (void) const
1319 const SyncInfo syncInfo =
1321 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
1322 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags accessMask;
1323 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout imageLayout;
1328 Data getData (void) const
1330 Data data = { 0, DE_NULL };
1334 void setData (const Data&)
1340 OperationContext& m_context;
1341 Resource& m_inResource;
1342 Resource& m_outResource;
1343 const VkImageCopy m_imageCopyRegion;
1346 class CopySupport : public OperationSupport
1349 CopySupport (const ResourceDescription& resourceDesc, const Type type)
1352 DE_ASSERT(resourceDesc.type == RESOURCE_TYPE_IMAGE);
1354 const bool isDepthStencil = isDepthStencilFormat(resourceDesc.imageFormat);
1355 m_requiredQueueFlags = (isDepthStencil || m_type == TYPE_BLIT ? VK_QUEUE_GRAPHICS_BIT : VK_QUEUE_TRANSFER_BIT);
1357 // Don't blit depth/stencil images.
1358 DE_ASSERT(m_type != TYPE_BLIT || !isDepthStencil);
1361 deUint32 getInResourceUsageFlags (void) const
1363 return VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1366 deUint32 getOutResourceUsageFlags (void) const
1368 return VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1371 VkQueueFlags getQueueFlags (const OperationContext& context) const
1374 return m_requiredQueueFlags;
1377 de::MovePtr<Operation> build (OperationContext&, Resource&) const
1380 return de::MovePtr<Operation>();
1383 de::MovePtr<Operation> build (OperationContext& context, Resource& inResource, Resource& outResource) const
1385 if (m_type == TYPE_COPY)
1386 return de::MovePtr<Operation>(new CopyCopyImplementation(context, inResource, outResource));
1388 return de::MovePtr<Operation>(new BlitCopyImplementation(context, inResource, outResource));
1393 VkQueueFlags m_requiredQueueFlags;
1396 } // CopyBlitImage ns
1398 namespace ShaderAccess
1403 DISPATCH_CALL_DISPATCH,
1404 DISPATCH_CALL_DISPATCH_INDIRECT,
1407 class GraphicsPipeline : public Pipeline
1410 GraphicsPipeline (OperationContext& context, const VkShaderStageFlagBits stage, const std::string& shaderPrefix, const VkDescriptorSetLayout descriptorSetLayout)
1411 : m_vertices (context)
1413 const DeviceInterface& vk = context.getDeviceInterface();
1414 const VkDevice device = context.getDevice();
1415 Allocator& allocator = context.getAllocator();
1416 const VkShaderStageFlags requiredStages = getRequiredStages(stage);
1420 m_colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
1421 m_colorImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
1422 m_colorImageExtent = makeExtent3D(16u, 16u, 1u);
1423 m_colorAttachmentImage = de::MovePtr<Image>(new Image(vk, device, allocator,
1424 makeImageCreateInfo(VK_IMAGE_TYPE_2D, m_colorImageExtent, m_colorFormat, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT),
1425 MemoryRequirement::Any));
1429 m_colorAttachmentView = makeImageView (vk, device, **m_colorAttachmentImage, VK_IMAGE_VIEW_TYPE_2D, m_colorFormat, m_colorImageSubresourceRange);
1430 m_renderPass = makeRenderPass (vk, device, m_colorFormat);
1431 m_framebuffer = makeFramebuffer (vk, device, *m_renderPass, *m_colorAttachmentView, m_colorImageExtent.width, m_colorImageExtent.height);
1432 m_pipelineLayout = makePipelineLayout(vk, device, descriptorSetLayout);
1434 GraphicsPipelineBuilder pipelineBuilder;
1436 .setRenderSize (tcu::IVec2(m_colorImageExtent.width, m_colorImageExtent.height))
1437 .setVertexInputSingleAttribute (m_vertices.getVertexFormat(), m_vertices.getVertexStride())
1438 .setShader (vk, device, VK_SHADER_STAGE_VERTEX_BIT, context.getBinaryCollection().get(shaderPrefix + "vert"), DE_NULL)
1439 .setShader (vk, device, VK_SHADER_STAGE_FRAGMENT_BIT, context.getBinaryCollection().get(shaderPrefix + "frag"), DE_NULL);
1441 if (requiredStages & (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT))
1443 .setPatchControlPoints (m_vertices.getNumVertices())
1444 .setShader (vk, device, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, context.getBinaryCollection().get(shaderPrefix + "tesc"), DE_NULL)
1445 .setShader (vk, device, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, context.getBinaryCollection().get(shaderPrefix + "tese"), DE_NULL);
1447 if (requiredStages & VK_SHADER_STAGE_GEOMETRY_BIT)
1449 .setShader (vk, device, VK_SHADER_STAGE_GEOMETRY_BIT, context.getBinaryCollection().get(shaderPrefix + "geom"), DE_NULL);
1451 m_pipeline = pipelineBuilder.build(vk, device, *m_pipelineLayout, *m_renderPass, context.getPipelineCacheData());
1454 void recordCommands (OperationContext& context, const VkCommandBuffer cmdBuffer, const VkDescriptorSet descriptorSet)
1456 const DeviceInterface& vk = context.getDeviceInterface();
1458 // Change color attachment image layout
1460 const VkImageMemoryBarrier colorAttachmentLayoutBarrier = makeImageMemoryBarrier(
1461 (VkAccessFlags)0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1462 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
1463 **m_colorAttachmentImage, m_colorImageSubresourceRange);
1465 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0,
1466 0u, DE_NULL, 0u, DE_NULL, 1u, &colorAttachmentLayoutBarrier);
1470 const VkRect2D renderArea = makeRect2D(m_colorImageExtent);
1471 const tcu::Vec4 clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
1473 beginRenderPass(vk, cmdBuffer, *m_renderPass, *m_framebuffer, renderArea, clearColor);
1476 vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
1477 vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &descriptorSet, 0u, DE_NULL);
1479 const VkDeviceSize vertexBufferOffset = 0ull;
1480 const VkBuffer vertexBuffer = m_vertices.getVertexBuffer();
1481 vk.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer, &vertexBufferOffset);
1484 vk.cmdDraw(cmdBuffer, m_vertices.getNumVertices(), 1u, 0u, 0u);
1485 endRenderPass(vk, cmdBuffer);
1489 const VertexGrid m_vertices;
1490 VkFormat m_colorFormat;
1491 de::MovePtr<Image> m_colorAttachmentImage;
1492 Move<VkImageView> m_colorAttachmentView;
1493 VkExtent3D m_colorImageExtent;
1494 VkImageSubresourceRange m_colorImageSubresourceRange;
1495 Move<VkRenderPass> m_renderPass;
1496 Move<VkFramebuffer> m_framebuffer;
1497 Move<VkPipelineLayout> m_pipelineLayout;
1498 Move<VkPipeline> m_pipeline;
1501 class ComputePipeline : public Pipeline
1504 ComputePipeline (OperationContext& context, const DispatchCall dispatchCall, const std::string& shaderPrefix, const VkDescriptorSetLayout descriptorSetLayout)
1505 : m_dispatchCall (dispatchCall)
1507 const DeviceInterface& vk = context.getDeviceInterface();
1508 const VkDevice device = context.getDevice();
1509 Allocator& allocator = context.getAllocator();
1511 if (m_dispatchCall == DISPATCH_CALL_DISPATCH_INDIRECT)
1513 m_indirectBuffer = de::MovePtr<Buffer>(new Buffer(vk, device, allocator,
1514 makeBufferCreateInfo(sizeof(VkDispatchIndirectCommand), VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT), MemoryRequirement::HostVisible));
1516 const Allocation& alloc = m_indirectBuffer->getAllocation();
1517 VkDispatchIndirectCommand* const pIndirectCommand = static_cast<VkDispatchIndirectCommand*>(alloc.getHostPtr());
1519 pIndirectCommand->x = 1u;
1520 pIndirectCommand->y = 1u;
1521 pIndirectCommand->z = 1u;
1523 flushAlloc(vk, device, alloc);
1526 const Unique<VkShaderModule> shaderModule(createShaderModule(vk, device, context.getBinaryCollection().get(shaderPrefix + "comp"), (VkShaderModuleCreateFlags)0));
1528 m_pipelineLayout = makePipelineLayout(vk, device, descriptorSetLayout);
1529 m_pipeline = makeComputePipeline(vk, device, *m_pipelineLayout, *shaderModule, DE_NULL, context.getPipelineCacheData());
1532 void recordCommands (OperationContext& context, const VkCommandBuffer cmdBuffer, const VkDescriptorSet descriptorSet)
1534 const DeviceInterface& vk = context.getDeviceInterface();
1536 vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipeline);
1537 vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0u, 1u, &descriptorSet, 0u, DE_NULL);
1539 if (m_dispatchCall == DISPATCH_CALL_DISPATCH_INDIRECT)
1540 vk.cmdDispatchIndirect(cmdBuffer, **m_indirectBuffer, 0u);
1542 vk.cmdDispatch(cmdBuffer, 1u, 1u, 1u);
1546 const DispatchCall m_dispatchCall;
1547 de::MovePtr<Buffer> m_indirectBuffer;
1548 Move<VkPipelineLayout> m_pipelineLayout;
1549 Move<VkPipeline> m_pipeline;
1552 //! Read/write operation on a UBO/SSBO in graphics/compute pipeline.
1553 class BufferImplementation : public Operation
1556 BufferImplementation (OperationContext& context,
1558 const VkShaderStageFlagBits stage,
1559 const BufferType bufferType,
1560 const std::string& shaderPrefix,
1561 const AccessMode mode,
1562 const PipelineType pipelineType,
1563 const DispatchCall dispatchCall)
1564 : m_context (context)
1565 , m_resource (resource)
1567 , m_pipelineStage (pipelineStageFlagsFromShaderStageFlagBits(m_stage))
1568 , m_bufferType (bufferType)
1570 , m_dispatchCall (dispatchCall)
1572 requireFeaturesForSSBOAccess (m_context, m_stage);
1574 const DeviceInterface& vk = m_context.getDeviceInterface();
1575 const VkDevice device = m_context.getDevice();
1576 Allocator& allocator = m_context.getAllocator();
1578 m_hostBuffer = de::MovePtr<Buffer>(new Buffer(
1579 vk, device, allocator, makeBufferCreateInfo(m_resource.getBuffer().size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible));
1581 // Init host buffer data
1583 const Allocation& alloc = m_hostBuffer->getAllocation();
1584 if (m_mode == ACCESS_MODE_READ)
1585 deMemset(alloc.getHostPtr(), 0, static_cast<size_t>(m_resource.getBuffer().size));
1587 fillPattern(alloc.getHostPtr(), m_resource.getBuffer().size);
1588 flushAlloc(vk, device, alloc);
1591 // Prepare descriptors
1593 const VkDescriptorType bufferDescriptorType = (m_bufferType == BUFFER_TYPE_UNIFORM ? VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER : VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
1595 m_descriptorSetLayout = DescriptorSetLayoutBuilder()
1596 .addSingleBinding(bufferDescriptorType, m_stage)
1597 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, m_stage)
1600 m_descriptorPool = DescriptorPoolBuilder()
1601 .addType(bufferDescriptorType)
1602 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
1603 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1605 m_descriptorSet = makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout);
1607 const VkDescriptorBufferInfo bufferInfo = makeDescriptorBufferInfo(m_resource.getBuffer().handle, m_resource.getBuffer().offset, m_resource.getBuffer().size);
1608 const VkDescriptorBufferInfo hostBufferInfo = makeDescriptorBufferInfo(**m_hostBuffer, 0u, m_resource.getBuffer().size);
1610 if (m_mode == ACCESS_MODE_READ)
1612 DescriptorSetUpdateBuilder()
1613 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), bufferDescriptorType, &bufferInfo)
1614 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &hostBufferInfo)
1615 .update(vk, device);
1619 DescriptorSetUpdateBuilder()
1620 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &hostBufferInfo)
1621 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufferInfo)
1622 .update(vk, device);
1627 m_pipeline = (pipelineType == PIPELINE_TYPE_GRAPHICS ? de::MovePtr<Pipeline>(new GraphicsPipeline(context, stage, shaderPrefix, *m_descriptorSetLayout))
1628 : de::MovePtr<Pipeline>(new ComputePipeline(context, m_dispatchCall, shaderPrefix, *m_descriptorSetLayout)));
1631 void recordCommands (const VkCommandBuffer cmdBuffer)
1633 m_pipeline->recordCommands(m_context, cmdBuffer, *m_descriptorSet);
1635 // Post draw/dispatch commands
1637 if (m_mode == ACCESS_MODE_READ)
1639 const DeviceInterface& vk = m_context.getDeviceInterface();
1641 // Insert a barrier so data written by the shader is available to the host
1642 const VkBufferMemoryBarrier barrier = makeBufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, **m_hostBuffer, 0u, m_resource.getBuffer().size);
1643 vk.cmdPipelineBarrier(cmdBuffer, m_pipelineStage, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
1647 SyncInfo getInSyncInfo (void) const
1649 const VkAccessFlags accessFlags = (m_mode == ACCESS_MODE_READ ? (m_bufferType == BUFFER_TYPE_UNIFORM ? VK_ACCESS_UNIFORM_READ_BIT
1650 : VK_ACCESS_SHADER_READ_BIT)
1651 : VK_ACCESS_SHADER_WRITE_BIT);
1652 const SyncInfo syncInfo =
1654 m_pipelineStage, // VkPipelineStageFlags stageMask;
1655 accessFlags, // VkAccessFlags accessMask;
1656 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
1661 SyncInfo getOutSyncInfo (void) const
1663 const VkAccessFlags accessFlags = m_mode == ACCESS_MODE_WRITE ? VK_ACCESS_SHADER_WRITE_BIT : 0;
1664 const SyncInfo syncInfo =
1666 m_pipelineStage, // VkPipelineStageFlags stageMask;
1667 accessFlags, // VkAccessFlags accessMask;
1668 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
1673 Data getData (void) const
1675 return getHostBufferData(m_context, *m_hostBuffer, m_resource.getBuffer().size);
1678 void setData (const Data& data)
1680 DE_ASSERT(m_mode == ACCESS_MODE_WRITE);
1681 setHostBufferData(m_context, *m_hostBuffer, data);
1685 OperationContext& m_context;
1686 Resource& m_resource;
1687 const VkShaderStageFlagBits m_stage;
1688 const VkPipelineStageFlags m_pipelineStage;
1689 const BufferType m_bufferType;
1690 const AccessMode m_mode;
1691 const DispatchCall m_dispatchCall;
1692 de::MovePtr<Buffer> m_hostBuffer;
1693 Move<VkDescriptorPool> m_descriptorPool;
1694 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
1695 Move<VkDescriptorSet> m_descriptorSet;
1696 de::MovePtr<Pipeline> m_pipeline;
1699 class ImageImplementation : public Operation
1702 ImageImplementation (OperationContext& context,
1704 const VkShaderStageFlagBits stage,
1705 const std::string& shaderPrefix,
1706 const AccessMode mode,
1707 const PipelineType pipelineType,
1708 const DispatchCall dispatchCall)
1709 : m_context (context)
1710 , m_resource (resource)
1712 , m_pipelineStage (pipelineStageFlagsFromShaderStageFlagBits(m_stage))
1714 , m_dispatchCall (dispatchCall)
1715 , m_hostBufferSizeBytes (getPixelBufferSize(m_resource.getImage().format, m_resource.getImage().extent))
1717 const DeviceInterface& vk = m_context.getDeviceInterface();
1718 const InstanceInterface& vki = m_context.getInstanceInterface();
1719 const VkDevice device = m_context.getDevice();
1720 const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
1721 Allocator& allocator = m_context.getAllocator();
1723 // Image stores are always required, in either access mode.
1724 requireFeaturesForSSBOAccess(m_context, m_stage);
1726 // Some storage image formats require additional capability.
1727 if (isStorageImageExtendedFormat(m_resource.getImage().format))
1728 requireFeatures(vki, physDevice, FEATURE_SHADER_STORAGE_IMAGE_EXTENDED_FORMATS);
1730 m_hostBuffer = de::MovePtr<Buffer>(new Buffer(
1731 vk, device, allocator, makeBufferCreateInfo(m_hostBufferSizeBytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT),
1732 MemoryRequirement::HostVisible));
1734 // Init host buffer data
1736 const Allocation& alloc = m_hostBuffer->getAllocation();
1737 if (m_mode == ACCESS_MODE_READ)
1738 deMemset(alloc.getHostPtr(), 0, static_cast<size_t>(m_hostBufferSizeBytes));
1740 fillPattern(alloc.getHostPtr(), m_hostBufferSizeBytes);
1741 flushAlloc(vk, device, alloc);
1746 m_image = de::MovePtr<Image>(new Image(vk, device, allocator,
1747 makeImageCreateInfo(m_resource.getImage().imageType, m_resource.getImage().extent, m_resource.getImage().format,
1748 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_STORAGE_BIT),
1749 MemoryRequirement::Any));
1751 if (m_mode == ACCESS_MODE_READ)
1753 m_srcImage = &m_resource.getImage().handle;
1754 m_dstImage = &(**m_image);
1758 m_srcImage = &(**m_image);
1759 m_dstImage = &m_resource.getImage().handle;
1762 const VkImageViewType viewType = getImageViewType(m_resource.getImage().imageType);
1764 m_srcImageView = makeImageView(vk, device, *m_srcImage, viewType, m_resource.getImage().format, m_resource.getImage().subresourceRange);
1765 m_dstImageView = makeImageView(vk, device, *m_dstImage, viewType, m_resource.getImage().format, m_resource.getImage().subresourceRange);
1768 // Prepare descriptors
1770 m_descriptorSetLayout = DescriptorSetLayoutBuilder()
1771 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, m_stage)
1772 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, m_stage)
1775 m_descriptorPool = DescriptorPoolBuilder()
1776 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1777 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1778 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1780 m_descriptorSet = makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout);
1782 const VkDescriptorImageInfo srcImageInfo = makeDescriptorImageInfo(DE_NULL, *m_srcImageView, VK_IMAGE_LAYOUT_GENERAL);
1783 const VkDescriptorImageInfo dstImageInfo = makeDescriptorImageInfo(DE_NULL, *m_dstImageView, VK_IMAGE_LAYOUT_GENERAL);
1785 DescriptorSetUpdateBuilder()
1786 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &srcImageInfo)
1787 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &dstImageInfo)
1788 .update(vk, device);
1792 m_pipeline = (pipelineType == PIPELINE_TYPE_GRAPHICS ? de::MovePtr<Pipeline>(new GraphicsPipeline(context, stage, shaderPrefix, *m_descriptorSetLayout))
1793 : de::MovePtr<Pipeline>(new ComputePipeline(context, m_dispatchCall, shaderPrefix, *m_descriptorSetLayout)));
1796 void recordCommands (const VkCommandBuffer cmdBuffer)
1798 const DeviceInterface& vk = m_context.getDeviceInterface();
1799 const VkBufferImageCopy bufferCopyRegion = makeBufferImageCopy(m_resource.getImage().extent, m_resource.getImage().subresourceLayers);
1801 // Destination image layout
1803 const VkImageMemoryBarrier barrier = makeImageMemoryBarrier(
1804 (VkAccessFlags)0, VK_ACCESS_SHADER_WRITE_BIT,
1805 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
1806 *m_dstImage, m_resource.getImage().subresourceRange);
1808 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, m_pipelineStage, (VkDependencyFlags)0,
1809 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
1812 // In write mode, source image must be filled with data.
1813 if (m_mode == ACCESS_MODE_WRITE)
1815 // Layout for transfer
1817 const VkImageMemoryBarrier barrier = makeImageMemoryBarrier(
1818 (VkAccessFlags)0, VK_ACCESS_TRANSFER_WRITE_BIT,
1819 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1820 *m_srcImage, m_resource.getImage().subresourceRange);
1822 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
1823 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
1826 // Host buffer -> Src image
1827 vk.cmdCopyBufferToImage(cmdBuffer, **m_hostBuffer, *m_srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &bufferCopyRegion);
1829 // Layout for shader reading
1831 const VkImageMemoryBarrier barrier = makeImageMemoryBarrier(
1832 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT,
1833 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
1834 *m_srcImage, m_resource.getImage().subresourceRange);
1836 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, m_pipelineStage, (VkDependencyFlags)0,
1837 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
1843 m_pipeline->recordCommands(m_context, cmdBuffer, *m_descriptorSet);
1845 // Post draw/dispatch commands
1847 if (m_mode == ACCESS_MODE_READ)
1849 // Layout for transfer
1851 const VkImageMemoryBarrier barrier = makeImageMemoryBarrier(
1852 VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
1853 VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1854 *m_dstImage, m_resource.getImage().subresourceRange);
1856 vk.cmdPipelineBarrier(cmdBuffer, m_pipelineStage, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
1857 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
1860 // Dst image -> Host buffer
1861 vk.cmdCopyImageToBuffer(cmdBuffer, *m_dstImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_hostBuffer, 1u, &bufferCopyRegion);
1863 // Insert a barrier so data written by the shader is available to the host
1865 const VkBufferMemoryBarrier barrier = makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, **m_hostBuffer, 0u, m_hostBufferSizeBytes);
1866 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
1871 SyncInfo getInSyncInfo (void) const
1873 const VkAccessFlags accessFlags = (m_mode == ACCESS_MODE_READ ? VK_ACCESS_SHADER_READ_BIT : 0);
1874 const SyncInfo syncInfo =
1876 m_pipelineStage, // VkPipelineStageFlags stageMask;
1877 accessFlags, // VkAccessFlags accessMask;
1878 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout;
1883 SyncInfo getOutSyncInfo (void) const
1885 const VkAccessFlags accessFlags = (m_mode == ACCESS_MODE_WRITE ? VK_ACCESS_SHADER_WRITE_BIT : 0);
1886 const SyncInfo syncInfo =
1888 m_pipelineStage, // VkPipelineStageFlags stageMask;
1889 accessFlags, // VkAccessFlags accessMask;
1890 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout;
1895 Data getData (void) const
1897 return getHostBufferData(m_context, *m_hostBuffer, m_hostBufferSizeBytes);
1900 void setData (const Data& data)
1902 DE_ASSERT(m_mode == ACCESS_MODE_WRITE);
1903 setHostBufferData(m_context, *m_hostBuffer, data);
1907 OperationContext& m_context;
1908 Resource& m_resource;
1909 const VkShaderStageFlagBits m_stage;
1910 const VkPipelineStageFlags m_pipelineStage;
1911 const AccessMode m_mode;
1912 const DispatchCall m_dispatchCall;
1913 const VkDeviceSize m_hostBufferSizeBytes;
1914 de::MovePtr<Buffer> m_hostBuffer;
1915 de::MovePtr<Image> m_image; //! Additional image used as src or dst depending on operation mode.
1916 const VkImage* m_srcImage;
1917 const VkImage* m_dstImage;
1918 Move<VkImageView> m_srcImageView;
1919 Move<VkImageView> m_dstImageView;
1920 Move<VkDescriptorPool> m_descriptorPool;
1921 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
1922 Move<VkDescriptorSet> m_descriptorSet;
1923 de::MovePtr<Pipeline> m_pipeline;
1926 //! Create generic passthrough shaders with bits of custom code inserted in a specific shader stage.
1927 void initPassthroughPrograms (SourceCollections& programCollection,
1928 const std::string& shaderPrefix,
1929 const std::string& declCode,
1930 const std::string& mainCode,
1931 const VkShaderStageFlagBits stage)
1933 const VkShaderStageFlags requiredStages = getRequiredStages(stage);
1935 if (requiredStages & VK_SHADER_STAGE_VERTEX_BIT)
1937 std::ostringstream src;
1938 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
1940 << "layout(location = 0) in vec4 v_in_position;\n"
1942 << "out " << s_perVertexBlock << ";\n"
1944 << (stage & VK_SHADER_STAGE_VERTEX_BIT ? declCode + "\n" : "")
1945 << "void main (void)\n"
1947 << " gl_Position = v_in_position;\n"
1948 << (stage & VK_SHADER_STAGE_VERTEX_BIT ? mainCode : "")
1951 if (!programCollection.glslSources.contains(shaderPrefix + "vert"))
1952 programCollection.glslSources.add(shaderPrefix + "vert") << glu::VertexSource(src.str());
1955 if (requiredStages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
1957 std::ostringstream src;
1958 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
1960 << "layout(vertices = 3) out;\n"
1962 << "in " << s_perVertexBlock << " gl_in[gl_MaxPatchVertices];\n"
1964 << "out " << s_perVertexBlock << " gl_out[];\n"
1966 << (stage & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ? declCode + "\n" : "")
1967 << "void main (void)\n"
1969 << " gl_TessLevelInner[0] = 1.0;\n"
1970 << " gl_TessLevelInner[1] = 1.0;\n"
1972 << " gl_TessLevelOuter[0] = 1.0;\n"
1973 << " gl_TessLevelOuter[1] = 1.0;\n"
1974 << " gl_TessLevelOuter[2] = 1.0;\n"
1975 << " gl_TessLevelOuter[3] = 1.0;\n"
1977 << " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1978 << (stage & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ? "\n" + mainCode : "")
1981 if (!programCollection.glslSources.contains(shaderPrefix + "tesc"))
1982 programCollection.glslSources.add(shaderPrefix + "tesc") << glu::TessellationControlSource(src.str());
1985 if (requiredStages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
1987 std::ostringstream src;
1988 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
1990 << "layout(triangles, equal_spacing, ccw) in;\n"
1992 << "in " << s_perVertexBlock << " gl_in[gl_MaxPatchVertices];\n"
1994 << "out " << s_perVertexBlock << ";\n"
1996 << (stage & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT ? declCode + "\n" : "")
1997 << "void main (void)\n"
1999 << " vec3 px = gl_TessCoord.x * gl_in[0].gl_Position.xyz;\n"
2000 << " vec3 py = gl_TessCoord.y * gl_in[1].gl_Position.xyz;\n"
2001 << " vec3 pz = gl_TessCoord.z * gl_in[2].gl_Position.xyz;\n"
2002 << " gl_Position = vec4(px + py + pz, 1.0);\n"
2003 << (stage & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT ? mainCode : "")
2006 if (!programCollection.glslSources.contains(shaderPrefix + "tese"))
2007 programCollection.glslSources.add(shaderPrefix + "tese") << glu::TessellationEvaluationSource(src.str());
2010 if (requiredStages & VK_SHADER_STAGE_GEOMETRY_BIT)
2012 std::ostringstream src;
2013 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
2015 << "layout(triangles) in;\n"
2016 << "layout(triangle_strip, max_vertices = 3) out;\n"
2018 << "in " << s_perVertexBlock << " gl_in[];\n"
2020 << "out " << s_perVertexBlock << ";\n"
2022 << (stage & VK_SHADER_STAGE_GEOMETRY_BIT ? declCode + "\n" : "")
2023 << "void main (void)\n"
2025 << " gl_Position = gl_in[0].gl_Position;\n"
2026 << " EmitVertex();\n"
2028 << " gl_Position = gl_in[1].gl_Position;\n"
2029 << " EmitVertex();\n"
2031 << " gl_Position = gl_in[2].gl_Position;\n"
2032 << " EmitVertex();\n"
2033 << (stage & VK_SHADER_STAGE_GEOMETRY_BIT ? "\n" + mainCode : "")
2036 if (!programCollection.glslSources.contains(shaderPrefix + "geom"))
2037 programCollection.glslSources.add(shaderPrefix + "geom") << glu::GeometrySource(src.str());
2040 if (requiredStages & VK_SHADER_STAGE_FRAGMENT_BIT)
2042 std::ostringstream src;
2043 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
2045 << "layout(location = 0) out vec4 o_color;\n"
2047 << (stage & VK_SHADER_STAGE_FRAGMENT_BIT ? declCode + "\n" : "")
2048 << "void main (void)\n"
2050 << " o_color = vec4(1.0);\n"
2051 << (stage & VK_SHADER_STAGE_FRAGMENT_BIT ? "\n" + mainCode : "")
2054 if (!programCollection.glslSources.contains(shaderPrefix + "frag"))
2055 programCollection.glslSources.add(shaderPrefix + "frag") << glu::FragmentSource(src.str());
2058 if (requiredStages & VK_SHADER_STAGE_COMPUTE_BIT)
2060 std::ostringstream src;
2061 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
2063 << "layout(local_size_x = 1) in;\n"
2065 << (stage & VK_SHADER_STAGE_COMPUTE_BIT ? declCode + "\n" : "")
2066 << "void main (void)\n"
2068 << (stage & VK_SHADER_STAGE_COMPUTE_BIT ? mainCode : "")
2071 if (!programCollection.glslSources.contains(shaderPrefix + "comp"))
2072 programCollection.glslSources.add(shaderPrefix + "comp") << glu::ComputeSource(src.str());
2076 class BufferSupport : public OperationSupport
2079 BufferSupport (const ResourceDescription& resourceDesc,
2080 const BufferType bufferType,
2081 const AccessMode mode,
2082 const VkShaderStageFlagBits stage,
2083 const DispatchCall dispatchCall = DISPATCH_CALL_DISPATCH)
2084 : m_resourceDesc (resourceDesc)
2085 , m_bufferType (bufferType)
2088 , m_shaderPrefix (std::string(m_mode == ACCESS_MODE_READ ? "read_" : "write_") + (m_bufferType == BUFFER_TYPE_UNIFORM ? "ubo_" : "ssbo_"))
2089 , m_dispatchCall (dispatchCall)
2091 DE_ASSERT(m_resourceDesc.type == RESOURCE_TYPE_BUFFER);
2092 DE_ASSERT(m_bufferType == BUFFER_TYPE_UNIFORM || m_bufferType == BUFFER_TYPE_STORAGE);
2093 DE_ASSERT(m_mode == ACCESS_MODE_READ || m_mode == ACCESS_MODE_WRITE);
2094 DE_ASSERT(m_mode == ACCESS_MODE_READ || m_bufferType == BUFFER_TYPE_STORAGE);
2095 DE_ASSERT(m_bufferType != BUFFER_TYPE_UNIFORM || m_resourceDesc.size.x() <= MAX_UBO_RANGE);
2096 DE_ASSERT(m_dispatchCall == DISPATCH_CALL_DISPATCH || m_dispatchCall == DISPATCH_CALL_DISPATCH_INDIRECT);
2098 assertValidShaderStage(m_stage);
2101 void initPrograms (SourceCollections& programCollection) const
2103 DE_ASSERT((m_resourceDesc.size.x() % sizeof(tcu::UVec4)) == 0);
2105 const std::string bufferTypeStr = (m_bufferType == BUFFER_TYPE_UNIFORM ? "uniform" : "buffer");
2106 const int numVecElements = static_cast<int>(m_resourceDesc.size.x() / sizeof(tcu::UVec4)); // std140 must be aligned to a multiple of 16
2108 std::ostringstream declSrc;
2109 declSrc << "layout(set = 0, binding = 0, std140) readonly " << bufferTypeStr << " Input {\n"
2110 << " uvec4 data[" << numVecElements << "];\n"
2113 << "layout(set = 0, binding = 1, std140) writeonly buffer Output {\n"
2114 << " uvec4 data[" << numVecElements << "];\n"
2117 std::ostringstream copySrc;
2118 copySrc << " for (int i = 0; i < " << numVecElements << "; ++i) {\n"
2119 << " b_out.data[i] = b_in.data[i];\n"
2122 initPassthroughPrograms(programCollection, m_shaderPrefix, declSrc.str(), copySrc.str(), m_stage);
2125 deUint32 getInResourceUsageFlags (void) const
2127 if (m_bufferType == BUFFER_TYPE_UNIFORM)
2128 return m_mode == ACCESS_MODE_READ ? VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT : 0;
2130 return m_mode == ACCESS_MODE_READ ? VK_BUFFER_USAGE_STORAGE_BUFFER_BIT : 0;
2133 deUint32 getOutResourceUsageFlags (void) const
2135 if (m_bufferType == BUFFER_TYPE_UNIFORM)
2136 return m_mode == ACCESS_MODE_WRITE ? VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT : 0;
2138 return m_mode == ACCESS_MODE_WRITE ? VK_BUFFER_USAGE_STORAGE_BUFFER_BIT : 0;
2141 VkQueueFlags getQueueFlags (const OperationContext& context) const
2144 return (m_stage == VK_SHADER_STAGE_COMPUTE_BIT ? VK_QUEUE_COMPUTE_BIT : VK_QUEUE_GRAPHICS_BIT);
2147 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
2149 if (m_stage & VK_SHADER_STAGE_COMPUTE_BIT)
2150 return de::MovePtr<Operation>(new BufferImplementation(context, resource, m_stage, m_bufferType, m_shaderPrefix, m_mode, PIPELINE_TYPE_COMPUTE, m_dispatchCall));
2152 return de::MovePtr<Operation>(new BufferImplementation(context, resource, m_stage, m_bufferType, m_shaderPrefix, m_mode, PIPELINE_TYPE_GRAPHICS, m_dispatchCall));
2155 de::MovePtr<Operation> build (OperationContext&, Resource&, Resource&) const
2158 return de::MovePtr<Operation>();
2162 const ResourceDescription m_resourceDesc;
2163 const BufferType m_bufferType;
2164 const AccessMode m_mode;
2165 const VkShaderStageFlagBits m_stage;
2166 const std::string m_shaderPrefix;
2167 const DispatchCall m_dispatchCall;
2170 class ImageSupport : public OperationSupport
2173 ImageSupport (const ResourceDescription& resourceDesc,
2174 const AccessMode mode,
2175 const VkShaderStageFlagBits stage,
2176 const DispatchCall dispatchCall = DISPATCH_CALL_DISPATCH)
2177 : m_resourceDesc (resourceDesc)
2180 , m_shaderPrefix (m_mode == ACCESS_MODE_READ ? "read_image_" : "write_image_")
2181 , m_dispatchCall (dispatchCall)
2183 DE_ASSERT(m_resourceDesc.type == RESOURCE_TYPE_IMAGE);
2184 DE_ASSERT(m_mode == ACCESS_MODE_READ || m_mode == ACCESS_MODE_WRITE);
2185 DE_ASSERT(m_dispatchCall == DISPATCH_CALL_DISPATCH || m_dispatchCall == DISPATCH_CALL_DISPATCH_INDIRECT);
2187 assertValidShaderStage(m_stage);
2190 void initPrograms (SourceCollections& programCollection) const
2192 const std::string imageFormat = getShaderImageFormatQualifier(m_resourceDesc.imageFormat);
2193 const std::string imageType = getShaderImageType(m_resourceDesc.imageFormat, m_resourceDesc.imageType);
2195 std::ostringstream declSrc;
2196 declSrc << "layout(set = 0, binding = 0, " << imageFormat << ") readonly uniform " << imageType << " srcImg;\n"
2197 << "layout(set = 0, binding = 1, " << imageFormat << ") writeonly uniform " << imageType << " dstImg;\n";
2199 std::ostringstream mainSrc;
2200 if (m_resourceDesc.imageType == VK_IMAGE_TYPE_1D)
2201 mainSrc << " for (int x = 0; x < " << m_resourceDesc.size.x() << "; ++x)\n"
2202 << " imageStore(dstImg, x, imageLoad(srcImg, x));\n";
2203 else if (m_resourceDesc.imageType == VK_IMAGE_TYPE_2D)
2204 mainSrc << " for (int y = 0; y < " << m_resourceDesc.size.y() << "; ++y)\n"
2205 << " for (int x = 0; x < " << m_resourceDesc.size.x() << "; ++x)\n"
2206 << " imageStore(dstImg, ivec2(x, y), imageLoad(srcImg, ivec2(x, y)));\n";
2207 else if (m_resourceDesc.imageType == VK_IMAGE_TYPE_3D)
2208 mainSrc << " for (int z = 0; z < " << m_resourceDesc.size.z() << "; ++z)\n"
2209 << " for (int y = 0; y < " << m_resourceDesc.size.y() << "; ++y)\n"
2210 << " for (int x = 0; x < " << m_resourceDesc.size.x() << "; ++x)\n"
2211 << " imageStore(dstImg, ivec3(x, y, z), imageLoad(srcImg, ivec3(x, y, z)));\n";
2215 initPassthroughPrograms(programCollection, m_shaderPrefix, declSrc.str(), mainSrc.str(), m_stage);
2218 deUint32 getInResourceUsageFlags (void) const
2220 return VK_IMAGE_USAGE_STORAGE_BIT;
2223 deUint32 getOutResourceUsageFlags (void) const
2225 return VK_IMAGE_USAGE_STORAGE_BIT;
2228 VkQueueFlags getQueueFlags (const OperationContext& context) const
2231 return (m_stage == VK_SHADER_STAGE_COMPUTE_BIT ? VK_QUEUE_COMPUTE_BIT : VK_QUEUE_GRAPHICS_BIT);
2234 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
2236 if (m_stage & VK_SHADER_STAGE_COMPUTE_BIT)
2237 return de::MovePtr<Operation>(new ImageImplementation(context, resource, m_stage, m_shaderPrefix, m_mode, PIPELINE_TYPE_COMPUTE, m_dispatchCall));
2239 return de::MovePtr<Operation>(new ImageImplementation(context, resource, m_stage, m_shaderPrefix, m_mode, PIPELINE_TYPE_GRAPHICS, m_dispatchCall));
2242 de::MovePtr<Operation> build (OperationContext&, Resource&, Resource&) const
2245 return de::MovePtr<Operation>();
2249 const ResourceDescription m_resourceDesc;
2250 const AccessMode m_mode;
2251 const VkShaderStageFlagBits m_stage;
2252 const std::string m_shaderPrefix;
2253 const DispatchCall m_dispatchCall;
2256 //! Copy operation on a UBO/SSBO in graphics/compute pipeline.
2257 class BufferCopyImplementation : public Operation
2260 BufferCopyImplementation (OperationContext& context,
2261 Resource& inResource,
2262 Resource& outResource,
2263 const VkShaderStageFlagBits stage,
2264 const BufferType bufferType,
2265 const std::string& shaderPrefix,
2266 const PipelineType pipelineType,
2267 const DispatchCall dispatchCall)
2268 : m_context (context)
2269 , m_inResource (inResource)
2270 , m_outResource (outResource)
2272 , m_pipelineStage (pipelineStageFlagsFromShaderStageFlagBits(m_stage))
2273 , m_bufferType (bufferType)
2274 , m_dispatchCall (dispatchCall)
2276 requireFeaturesForSSBOAccess (m_context, m_stage);
2278 const DeviceInterface& vk = m_context.getDeviceInterface();
2279 const VkDevice device = m_context.getDevice();
2281 // Prepare descriptors
2283 const VkDescriptorType bufferDescriptorType = (m_bufferType == BUFFER_TYPE_UNIFORM ? VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER : VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2285 m_descriptorSetLayout = DescriptorSetLayoutBuilder()
2286 .addSingleBinding(bufferDescriptorType, m_stage)
2287 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, m_stage)
2290 m_descriptorPool = DescriptorPoolBuilder()
2291 .addType(bufferDescriptorType)
2292 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
2293 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
2295 m_descriptorSet = makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout);
2297 const VkDescriptorBufferInfo inBufferInfo = makeDescriptorBufferInfo(m_inResource.getBuffer().handle, m_inResource.getBuffer().offset, m_inResource.getBuffer().size);
2298 const VkDescriptorBufferInfo outBufferInfo = makeDescriptorBufferInfo(m_outResource.getBuffer().handle, m_outResource.getBuffer().offset, m_outResource.getBuffer().size);
2300 DescriptorSetUpdateBuilder()
2301 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &inBufferInfo)
2302 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outBufferInfo)
2303 .update(vk, device);
2307 m_pipeline = (pipelineType == PIPELINE_TYPE_GRAPHICS ? de::MovePtr<Pipeline>(new GraphicsPipeline(context, stage, shaderPrefix, *m_descriptorSetLayout))
2308 : de::MovePtr<Pipeline>(new ComputePipeline(context, m_dispatchCall, shaderPrefix, *m_descriptorSetLayout)));
2311 void recordCommands (const VkCommandBuffer cmdBuffer)
2313 m_pipeline->recordCommands(m_context, cmdBuffer, *m_descriptorSet);
2316 SyncInfo getInSyncInfo (void) const
2318 const SyncInfo syncInfo =
2320 m_pipelineStage, // VkPipelineStageFlags stageMask;
2321 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags accessMask;
2322 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
2327 SyncInfo getOutSyncInfo (void) const
2329 const SyncInfo syncInfo =
2331 m_pipelineStage, // VkPipelineStageFlags stageMask;
2332 VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags accessMask;
2333 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
2338 Data getData (void) const
2340 Data data = { 0, DE_NULL };
2344 void setData (const Data&)
2350 OperationContext& m_context;
2351 Resource& m_inResource;
2352 Resource& m_outResource;
2353 const VkShaderStageFlagBits m_stage;
2354 const VkPipelineStageFlags m_pipelineStage;
2355 const BufferType m_bufferType;
2356 const DispatchCall m_dispatchCall;
2357 Move<VkDescriptorPool> m_descriptorPool;
2358 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
2359 Move<VkDescriptorSet> m_descriptorSet;
2360 de::MovePtr<Pipeline> m_pipeline;
2363 class CopyBufferSupport : public OperationSupport
2366 CopyBufferSupport (const ResourceDescription& resourceDesc,
2367 const BufferType bufferType,
2368 const VkShaderStageFlagBits stage,
2369 const DispatchCall dispatchCall = DISPATCH_CALL_DISPATCH)
2370 : m_resourceDesc (resourceDesc)
2371 , m_bufferType (bufferType)
2373 , m_shaderPrefix (std::string("copy_") + getShaderStageName(stage) + (m_bufferType == BUFFER_TYPE_UNIFORM ? "_ubo_" : "_ssbo_"))
2374 , m_dispatchCall (dispatchCall)
2376 DE_ASSERT(m_resourceDesc.type == RESOURCE_TYPE_BUFFER);
2377 DE_ASSERT(m_bufferType == BUFFER_TYPE_UNIFORM || m_bufferType == BUFFER_TYPE_STORAGE);
2378 DE_ASSERT(m_bufferType != BUFFER_TYPE_UNIFORM || m_resourceDesc.size.x() <= MAX_UBO_RANGE);
2379 DE_ASSERT(m_dispatchCall == DISPATCH_CALL_DISPATCH || m_dispatchCall == DISPATCH_CALL_DISPATCH_INDIRECT);
2381 assertValidShaderStage(m_stage);
2384 void initPrograms (SourceCollections& programCollection) const
2386 DE_ASSERT((m_resourceDesc.size.x() % sizeof(tcu::UVec4)) == 0);
2388 const std::string bufferTypeStr = (m_bufferType == BUFFER_TYPE_UNIFORM ? "uniform" : "buffer");
2389 const int numVecElements = static_cast<int>(m_resourceDesc.size.x() / sizeof(tcu::UVec4)); // std140 must be aligned to a multiple of 16
2391 std::ostringstream declSrc;
2392 declSrc << "layout(set = 0, binding = 0, std140) readonly " << bufferTypeStr << " Input {\n"
2393 << " uvec4 data[" << numVecElements << "];\n"
2396 << "layout(set = 0, binding = 1, std140) writeonly buffer Output {\n"
2397 << " uvec4 data[" << numVecElements << "];\n"
2400 std::ostringstream copySrc;
2401 copySrc << " for (int i = 0; i < " << numVecElements << "; ++i) {\n"
2402 << " b_out.data[i] = b_in.data[i];\n"
2405 initPassthroughPrograms(programCollection, m_shaderPrefix, declSrc.str(), copySrc.str(), m_stage);
2408 deUint32 getInResourceUsageFlags (void) const
2410 return (m_bufferType == BUFFER_TYPE_UNIFORM ? VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT : VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
2413 deUint32 getOutResourceUsageFlags (void) const
2415 return VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
2418 VkQueueFlags getQueueFlags (const OperationContext& context) const
2421 return (m_stage == VK_SHADER_STAGE_COMPUTE_BIT ? VK_QUEUE_COMPUTE_BIT : VK_QUEUE_GRAPHICS_BIT);
2424 de::MovePtr<Operation> build (OperationContext&, Resource&) const
2427 return de::MovePtr<Operation>();
2430 de::MovePtr<Operation> build (OperationContext& context, Resource& inResource, Resource& outResource) const
2432 if (m_stage & VK_SHADER_STAGE_COMPUTE_BIT)
2433 return de::MovePtr<Operation>(new BufferCopyImplementation(context, inResource, outResource, m_stage, m_bufferType, m_shaderPrefix, PIPELINE_TYPE_COMPUTE, m_dispatchCall));
2435 return de::MovePtr<Operation>(new BufferCopyImplementation(context, inResource, outResource, m_stage, m_bufferType, m_shaderPrefix, PIPELINE_TYPE_GRAPHICS, m_dispatchCall));
2439 const ResourceDescription m_resourceDesc;
2440 const BufferType m_bufferType;
2441 const VkShaderStageFlagBits m_stage;
2442 const std::string m_shaderPrefix;
2443 const DispatchCall m_dispatchCall;
2446 class CopyImageImplementation : public Operation
2449 CopyImageImplementation (OperationContext& context,
2450 Resource& inResource,
2451 Resource& outResource,
2452 const VkShaderStageFlagBits stage,
2453 const std::string& shaderPrefix,
2454 const PipelineType pipelineType,
2455 const DispatchCall dispatchCall)
2456 : m_context (context)
2457 , m_inResource (inResource)
2458 , m_outResource (outResource)
2460 , m_pipelineStage (pipelineStageFlagsFromShaderStageFlagBits(m_stage))
2461 , m_dispatchCall (dispatchCall)
2463 const DeviceInterface& vk = m_context.getDeviceInterface();
2464 const InstanceInterface& vki = m_context.getInstanceInterface();
2465 const VkDevice device = m_context.getDevice();
2466 const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
2468 // Image stores are always required, in either access mode.
2469 requireFeaturesForSSBOAccess(m_context, m_stage);
2471 // Some storage image formats require additional capability.
2472 if (isStorageImageExtendedFormat(m_inResource.getImage().format))
2473 requireFeatures(vki, physDevice, FEATURE_SHADER_STORAGE_IMAGE_EXTENDED_FORMATS);
2477 const VkImageViewType viewType = getImageViewType(m_inResource.getImage().imageType);
2479 m_srcImageView = makeImageView(vk, device, m_inResource.getImage().handle, viewType, m_inResource.getImage().format, m_inResource.getImage().subresourceRange);
2480 m_dstImageView = makeImageView(vk, device, m_outResource.getImage().handle, viewType, m_outResource.getImage().format, m_outResource.getImage().subresourceRange);
2483 // Prepare descriptors
2485 m_descriptorSetLayout = DescriptorSetLayoutBuilder()
2486 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, m_stage)
2487 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, m_stage)
2490 m_descriptorPool = DescriptorPoolBuilder()
2491 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
2492 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
2493 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
2495 m_descriptorSet = makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout);
2497 const VkDescriptorImageInfo srcImageInfo = makeDescriptorImageInfo(DE_NULL, *m_srcImageView, VK_IMAGE_LAYOUT_GENERAL);
2498 const VkDescriptorImageInfo dstImageInfo = makeDescriptorImageInfo(DE_NULL, *m_dstImageView, VK_IMAGE_LAYOUT_GENERAL);
2500 DescriptorSetUpdateBuilder()
2501 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &srcImageInfo)
2502 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &dstImageInfo)
2503 .update(vk, device);
2507 m_pipeline = (pipelineType == PIPELINE_TYPE_GRAPHICS ? de::MovePtr<Pipeline>(new GraphicsPipeline(context, stage, shaderPrefix, *m_descriptorSetLayout))
2508 : de::MovePtr<Pipeline>(new ComputePipeline(context, m_dispatchCall, shaderPrefix, *m_descriptorSetLayout)));
2511 void recordCommands (const VkCommandBuffer cmdBuffer)
2514 const DeviceInterface& vk = m_context.getDeviceInterface();
2515 const VkImageMemoryBarrier barriers[] = {
2516 makeImageMemoryBarrier(
2517 (VkAccessFlags)0, VK_ACCESS_SHADER_WRITE_BIT,
2518 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
2519 m_outResource.getImage().handle, m_outResource.getImage().subresourceRange),
2520 makeImageMemoryBarrier(
2521 (VkAccessFlags) 0, VK_ACCESS_SHADER_READ_BIT,
2522 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
2523 m_inResource.getImage().handle, m_inResource.getImage().subresourceRange),
2526 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, m_pipelineStage, (VkDependencyFlags)0,
2527 0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(barriers), barriers);
2532 m_pipeline->recordCommands(m_context, cmdBuffer, *m_descriptorSet);
2535 SyncInfo getInSyncInfo (void) const
2537 const SyncInfo syncInfo =
2539 m_pipelineStage, // VkPipelineStageFlags stageMask;
2540 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags accessMask;
2541 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout;
2546 SyncInfo getOutSyncInfo (void) const
2548 const SyncInfo syncInfo =
2550 m_pipelineStage, // VkPipelineStageFlags stageMask;
2551 VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags accessMask;
2552 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout;
2557 Data getData (void) const
2559 Data data = { 0, DE_NULL };
2563 void setData (const Data&)
2569 OperationContext& m_context;
2570 Resource& m_inResource;
2571 Resource& m_outResource;
2572 const VkShaderStageFlagBits m_stage;
2573 const VkPipelineStageFlags m_pipelineStage;
2574 const DispatchCall m_dispatchCall;
2575 Move<VkImageView> m_srcImageView;
2576 Move<VkImageView> m_dstImageView;
2577 Move<VkDescriptorPool> m_descriptorPool;
2578 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
2579 Move<VkDescriptorSet> m_descriptorSet;
2580 de::MovePtr<Pipeline> m_pipeline;
2583 class CopyImageSupport : public OperationSupport
2586 CopyImageSupport (const ResourceDescription& resourceDesc,
2587 const VkShaderStageFlagBits stage,
2588 const DispatchCall dispatchCall = DISPATCH_CALL_DISPATCH)
2589 : m_resourceDesc (resourceDesc)
2591 , m_shaderPrefix (std::string("copy_image_") + getShaderStageName(stage) + "_")
2592 , m_dispatchCall (dispatchCall)
2594 DE_ASSERT(m_resourceDesc.type == RESOURCE_TYPE_IMAGE);
2595 DE_ASSERT(m_dispatchCall == DISPATCH_CALL_DISPATCH || m_dispatchCall == DISPATCH_CALL_DISPATCH_INDIRECT);
2597 assertValidShaderStage(m_stage);
2600 void initPrograms (SourceCollections& programCollection) const
2602 const std::string imageFormat = getShaderImageFormatQualifier(m_resourceDesc.imageFormat);
2603 const std::string imageType = getShaderImageType(m_resourceDesc.imageFormat, m_resourceDesc.imageType);
2605 std::ostringstream declSrc;
2606 declSrc << "layout(set = 0, binding = 0, " << imageFormat << ") readonly uniform " << imageType << " srcImg;\n"
2607 << "layout(set = 0, binding = 1, " << imageFormat << ") writeonly uniform " << imageType << " dstImg;\n";
2609 std::ostringstream mainSrc;
2610 if (m_resourceDesc.imageType == VK_IMAGE_TYPE_1D)
2611 mainSrc << " for (int x = 0; x < " << m_resourceDesc.size.x() << "; ++x)\n"
2612 << " imageStore(dstImg, x, imageLoad(srcImg, x));\n";
2613 else if (m_resourceDesc.imageType == VK_IMAGE_TYPE_2D)
2614 mainSrc << " for (int y = 0; y < " << m_resourceDesc.size.y() << "; ++y)\n"
2615 << " for (int x = 0; x < " << m_resourceDesc.size.x() << "; ++x)\n"
2616 << " imageStore(dstImg, ivec2(x, y), imageLoad(srcImg, ivec2(x, y)));\n";
2617 else if (m_resourceDesc.imageType == VK_IMAGE_TYPE_3D)
2618 mainSrc << " for (int z = 0; z < " << m_resourceDesc.size.z() << "; ++z)\n"
2619 << " for (int y = 0; y < " << m_resourceDesc.size.y() << "; ++y)\n"
2620 << " for (int x = 0; x < " << m_resourceDesc.size.x() << "; ++x)\n"
2621 << " imageStore(dstImg, ivec3(x, y, z), imageLoad(srcImg, ivec3(x, y, z)));\n";
2625 initPassthroughPrograms(programCollection, m_shaderPrefix, declSrc.str(), mainSrc.str(), m_stage);
2628 deUint32 getInResourceUsageFlags (void) const
2630 return VK_IMAGE_USAGE_STORAGE_BIT;
2633 deUint32 getOutResourceUsageFlags (void) const
2635 return VK_IMAGE_USAGE_STORAGE_BIT;
2638 VkQueueFlags getQueueFlags (const OperationContext& context) const
2641 return (m_stage == VK_SHADER_STAGE_COMPUTE_BIT ? VK_QUEUE_COMPUTE_BIT : VK_QUEUE_GRAPHICS_BIT);
2644 de::MovePtr<Operation> build (OperationContext&, Resource&) const
2647 return de::MovePtr<Operation>();
2650 de::MovePtr<Operation> build (OperationContext& context, Resource& inResource, Resource& outResource) const
2652 if (m_stage & VK_SHADER_STAGE_COMPUTE_BIT)
2653 return de::MovePtr<Operation>(new CopyImageImplementation(context, inResource, outResource, m_stage, m_shaderPrefix, PIPELINE_TYPE_COMPUTE, m_dispatchCall));
2655 return de::MovePtr<Operation>(new CopyImageImplementation(context, inResource, outResource, m_stage, m_shaderPrefix, PIPELINE_TYPE_GRAPHICS, m_dispatchCall));
2659 const ResourceDescription m_resourceDesc;
2660 const VkShaderStageFlagBits m_stage;
2661 const std::string m_shaderPrefix;
2662 const DispatchCall m_dispatchCall;
2665 } // ShaderAccess ns
2667 namespace CopyBufferToImage
2670 class WriteImplementation : public Operation
2673 WriteImplementation (OperationContext& context, Resource& resource)
2674 : m_context (context)
2675 , m_resource (resource)
2676 , m_bufferSize (getPixelBufferSize(m_resource.getImage().format, m_resource.getImage().extent))
2678 DE_ASSERT(m_resource.getType() == RESOURCE_TYPE_IMAGE);
2680 const DeviceInterface& vk = m_context.getDeviceInterface();
2681 const VkDevice device = m_context.getDevice();
2682 Allocator& allocator = m_context.getAllocator();
2684 m_hostBuffer = de::MovePtr<Buffer>(new Buffer(
2685 vk, device, allocator, makeBufferCreateInfo(m_bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT), MemoryRequirement::HostVisible));
2687 const Allocation& alloc = m_hostBuffer->getAllocation();
2688 fillPattern(alloc.getHostPtr(), m_bufferSize);
2689 flushAlloc(vk, device, alloc);
2692 void recordCommands (const VkCommandBuffer cmdBuffer)
2694 const DeviceInterface& vk = m_context.getDeviceInterface();
2695 const VkBufferImageCopy copyRegion = makeBufferImageCopy(m_resource.getImage().extent, m_resource.getImage().subresourceLayers);
2697 const VkImageMemoryBarrier layoutBarrier = makeImageMemoryBarrier(
2698 (VkAccessFlags)0, VK_ACCESS_TRANSFER_WRITE_BIT,
2699 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
2700 m_resource.getImage().handle, m_resource.getImage().subresourceRange);
2701 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 0u, DE_NULL, 1u, &layoutBarrier);
2703 vk.cmdCopyBufferToImage(cmdBuffer, **m_hostBuffer, m_resource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ©Region);
2706 SyncInfo getInSyncInfo (void) const
2708 return emptySyncInfo;
2711 SyncInfo getOutSyncInfo (void) const
2713 const SyncInfo syncInfo =
2715 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
2716 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags accessMask;
2717 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout imageLayout;
2722 Data getData (void) const
2724 return getHostBufferData(m_context, *m_hostBuffer, m_bufferSize);
2727 void setData (const Data& data)
2729 setHostBufferData(m_context, *m_hostBuffer, data);
2733 OperationContext& m_context;
2734 Resource& m_resource;
2735 de::MovePtr<Buffer> m_hostBuffer;
2736 const VkDeviceSize m_bufferSize;
2739 class ReadImplementation : public Operation
2742 ReadImplementation (OperationContext& context, Resource& resource)
2743 : m_context (context)
2744 , m_resource (resource)
2745 , m_subresourceRange (makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u))
2746 , m_subresourceLayers (makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u))
2748 DE_ASSERT(m_resource.getType() == RESOURCE_TYPE_BUFFER);
2750 const DeviceInterface& vk = m_context.getDeviceInterface();
2751 const VkDevice device = m_context.getDevice();
2752 Allocator& allocator = m_context.getAllocator();
2753 const VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
2754 const deUint32 pixelSize = tcu::getPixelSize(mapVkFormat(format));
2756 DE_ASSERT((m_resource.getBuffer().size % pixelSize) == 0);
2757 m_imageExtent = get2DImageExtentWithSize(m_resource.getBuffer().size, pixelSize); // there may be some unused space at the end
2759 // Copy destination image.
2760 m_image = de::MovePtr<Image>(new Image(
2761 vk, device, allocator, makeImageCreateInfo(VK_IMAGE_TYPE_2D, m_imageExtent, format, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT), MemoryRequirement::Any));
2763 // Image data will be copied here, so it can be read on the host.
2764 m_hostBuffer = de::MovePtr<Buffer>(new Buffer(
2765 vk, device, allocator, makeBufferCreateInfo(m_resource.getBuffer().size, VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible));
2768 void recordCommands (const VkCommandBuffer cmdBuffer)
2770 const DeviceInterface& vk = m_context.getDeviceInterface();
2771 const VkBufferImageCopy copyRegion = makeBufferImageCopy(m_imageExtent, m_subresourceLayers);
2773 // Resource -> Image
2775 const VkImageMemoryBarrier layoutBarrier = makeImageMemoryBarrier(
2776 (VkAccessFlags)0, VK_ACCESS_TRANSFER_WRITE_BIT,
2777 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
2778 **m_image, m_subresourceRange);
2779 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 0u, DE_NULL, 1u, &layoutBarrier);
2781 vk.cmdCopyBufferToImage(cmdBuffer, m_resource.getBuffer().handle, **m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ©Region);
2783 // Image -> Host buffer
2785 const VkImageMemoryBarrier layoutBarrier = makeImageMemoryBarrier(
2786 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
2787 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
2788 **m_image, m_subresourceRange);
2789 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 0u, DE_NULL, 1u, &layoutBarrier);
2791 vk.cmdCopyImageToBuffer(cmdBuffer, **m_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_hostBuffer, 1u, ©Region);
2793 const VkBufferMemoryBarrier barrier = makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, **m_hostBuffer, 0u, m_resource.getBuffer().size);
2794 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
2798 SyncInfo getInSyncInfo (void) const
2800 const SyncInfo syncInfo =
2802 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
2803 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags accessMask;
2804 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
2809 SyncInfo getOutSyncInfo (void) const
2811 return emptySyncInfo;
2814 Data getData (void) const
2816 return getHostBufferData(m_context, *m_hostBuffer, m_resource.getBuffer().size);
2819 void setData (const Data& data)
2821 setHostBufferData(m_context, *m_hostBuffer, data);
2825 OperationContext& m_context;
2826 Resource& m_resource;
2827 const VkImageSubresourceRange m_subresourceRange;
2828 const VkImageSubresourceLayers m_subresourceLayers;
2829 de::MovePtr<Buffer> m_hostBuffer;
2830 de::MovePtr<Image> m_image;
2831 VkExtent3D m_imageExtent;
2834 class Support : public OperationSupport
2837 Support (const ResourceDescription& resourceDesc, const AccessMode mode)
2839 , m_resourceType (resourceDesc.type)
2840 , m_requiredQueueFlags (resourceDesc.type == RESOURCE_TYPE_IMAGE && isDepthStencilFormat(resourceDesc.imageFormat) ? VK_QUEUE_GRAPHICS_BIT : VK_QUEUE_TRANSFER_BIT)
2843 // Because depth or stencil aspect buffer to image copies may require format conversions on some implementations,
2844 // they are not supported on queues that do not support graphics.
2846 DE_ASSERT(m_mode == ACCESS_MODE_READ || m_mode == ACCESS_MODE_WRITE);
2847 DE_ASSERT(m_mode == ACCESS_MODE_READ || resourceDesc.type != RESOURCE_TYPE_BUFFER);
2848 DE_ASSERT(m_mode == ACCESS_MODE_WRITE || resourceDesc.type != RESOURCE_TYPE_IMAGE);
2851 deUint32 getInResourceUsageFlags (void) const
2853 if (m_resourceType == RESOURCE_TYPE_IMAGE)
2854 return m_mode == ACCESS_MODE_READ ? VK_IMAGE_USAGE_TRANSFER_SRC_BIT : 0;
2856 return m_mode == ACCESS_MODE_READ ? VK_BUFFER_USAGE_TRANSFER_SRC_BIT : 0;
2859 deUint32 getOutResourceUsageFlags (void) const
2861 if (m_resourceType == RESOURCE_TYPE_IMAGE)
2862 return m_mode == ACCESS_MODE_WRITE ? VK_IMAGE_USAGE_TRANSFER_DST_BIT : 0;
2864 return m_mode == ACCESS_MODE_WRITE ? VK_BUFFER_USAGE_TRANSFER_DST_BIT : 0;
2867 VkQueueFlags getQueueFlags (const OperationContext& context) const
2870 return m_requiredQueueFlags;
2873 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
2875 if (m_mode == ACCESS_MODE_READ)
2876 return de::MovePtr<Operation>(new ReadImplementation(context, resource));
2878 return de::MovePtr<Operation>(new WriteImplementation(context, resource));
2881 de::MovePtr<Operation> build (OperationContext&, Resource&, Resource&) const
2884 return de::MovePtr<Operation>();
2888 const AccessMode m_mode;
2889 const enum ResourceType m_resourceType;
2890 const VkQueueFlags m_requiredQueueFlags;
2893 class CopyImplementation : public Operation
2896 CopyImplementation (OperationContext& context, Resource& inResource, Resource& outResource)
2897 : m_context (context)
2898 , m_inResource (inResource)
2899 , m_outResource (outResource)
2901 DE_ASSERT(m_inResource.getType() == RESOURCE_TYPE_BUFFER);
2902 DE_ASSERT(m_outResource.getType() == RESOURCE_TYPE_IMAGE);
2905 void recordCommands (const VkCommandBuffer cmdBuffer)
2907 const DeviceInterface& vk = m_context.getDeviceInterface();
2908 const VkBufferImageCopy copyRegion = makeBufferImageCopy(m_outResource.getImage().extent, m_outResource.getImage().subresourceLayers);
2910 const VkBufferMemoryBarrier bufferLayoutBarrier =
2911 makeBufferMemoryBarrier(
2912 (VkAccessFlags)0, VK_ACCESS_TRANSFER_READ_BIT,
2913 m_inResource.getBuffer().handle, 0, m_inResource.getBuffer().size);
2914 const VkImageMemoryBarrier imageLayoutBarrier =
2915 makeImageMemoryBarrier(
2916 (VkAccessFlags)0, VK_ACCESS_TRANSFER_WRITE_BIT,
2917 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
2918 m_outResource.getImage().handle, m_outResource.getImage().subresourceRange);
2919 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0u, DE_NULL,
2920 1u, &bufferLayoutBarrier, 1u, &imageLayoutBarrier);
2922 vk.cmdCopyBufferToImage(cmdBuffer, m_inResource.getBuffer().handle, m_outResource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ©Region);
2925 SyncInfo getInSyncInfo (void) const
2927 const SyncInfo syncInfo =
2929 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
2930 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags accessMask;
2931 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout imageLayout;
2936 SyncInfo getOutSyncInfo (void) const
2938 const SyncInfo syncInfo =
2940 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
2941 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags accessMask;
2942 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout imageLayout;
2947 Data getData (void) const
2949 Data data = { 0, DE_NULL };
2953 void setData (const Data&)
2959 OperationContext& m_context;
2960 Resource& m_inResource;
2961 Resource& m_outResource;
2964 class CopySupport : public OperationSupport
2967 CopySupport (const ResourceDescription& resourceDesc)
2968 : m_resourceType (resourceDesc.type)
2969 , m_requiredQueueFlags (resourceDesc.type == RESOURCE_TYPE_IMAGE && isDepthStencilFormat(resourceDesc.imageFormat) ? VK_QUEUE_GRAPHICS_BIT : VK_QUEUE_TRANSFER_BIT)
2973 deUint32 getInResourceUsageFlags (void) const
2975 if (m_resourceType == RESOURCE_TYPE_IMAGE)
2976 return VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
2978 return VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
2981 deUint32 getOutResourceUsageFlags (void) const
2983 if (m_resourceType == RESOURCE_TYPE_IMAGE)
2984 return VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2986 return VK_BUFFER_USAGE_TRANSFER_DST_BIT;
2989 VkQueueFlags getQueueFlags (const OperationContext& context) const
2992 return m_requiredQueueFlags;
2995 de::MovePtr<Operation> build (OperationContext&, Resource&) const
2998 return de::MovePtr<Operation>();
3001 de::MovePtr<Operation> build (OperationContext& context, Resource& inResource, Resource& outResource) const
3003 return de::MovePtr<Operation>(new CopyImplementation(context, inResource, outResource));
3007 const enum ResourceType m_resourceType;
3008 const VkQueueFlags m_requiredQueueFlags;
3011 } // CopyBufferToImage ns
3013 namespace CopyImageToBuffer
3016 class WriteImplementation : public Operation
3019 WriteImplementation (OperationContext& context, Resource& resource)
3020 : m_context (context)
3021 , m_resource (resource)
3022 , m_subresourceRange (makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u))
3023 , m_subresourceLayers (makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u))
3025 DE_ASSERT(m_resource.getType() == RESOURCE_TYPE_BUFFER);
3027 const DeviceInterface& vk = m_context.getDeviceInterface();
3028 const VkDevice device = m_context.getDevice();
3029 Allocator& allocator = m_context.getAllocator();
3030 const VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
3031 const deUint32 pixelSize = tcu::getPixelSize(mapVkFormat(format));
3033 DE_ASSERT((m_resource.getBuffer().size % pixelSize) == 0);
3034 m_imageExtent = get2DImageExtentWithSize(m_resource.getBuffer().size, pixelSize);
3036 // Source data staging buffer
3037 m_hostBuffer = de::MovePtr<Buffer>(new Buffer(
3038 vk, device, allocator, makeBufferCreateInfo(m_resource.getBuffer().size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT), MemoryRequirement::HostVisible));
3040 const Allocation& alloc = m_hostBuffer->getAllocation();
3041 fillPattern(alloc.getHostPtr(), m_resource.getBuffer().size);
3042 flushAlloc(vk, device, alloc);
3044 // Source data image
3045 m_image = de::MovePtr<Image>(new Image(
3046 vk, device, allocator, makeImageCreateInfo(VK_IMAGE_TYPE_2D, m_imageExtent, format, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT), MemoryRequirement::Any));
3049 void recordCommands (const VkCommandBuffer cmdBuffer)
3051 const DeviceInterface& vk = m_context.getDeviceInterface();
3052 const VkBufferImageCopy copyRegion = makeBufferImageCopy(m_imageExtent, m_subresourceLayers);
3054 // Host buffer -> Image
3056 const VkImageMemoryBarrier layoutBarrier = makeImageMemoryBarrier(
3057 (VkAccessFlags)0, VK_ACCESS_TRANSFER_WRITE_BIT,
3058 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
3059 **m_image, m_subresourceRange);
3060 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 0u, DE_NULL, 1u, &layoutBarrier);
3062 vk.cmdCopyBufferToImage(cmdBuffer, **m_hostBuffer, **m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ©Region);
3064 // Image -> Resource
3066 const VkImageMemoryBarrier layoutBarrier = makeImageMemoryBarrier(
3067 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
3068 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
3069 **m_image, m_subresourceRange);
3070 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 0u, DE_NULL, 1u, &layoutBarrier);
3072 vk.cmdCopyImageToBuffer(cmdBuffer, **m_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_resource.getBuffer().handle, 1u, ©Region);
3076 SyncInfo getInSyncInfo (void) const
3078 return emptySyncInfo;
3081 SyncInfo getOutSyncInfo (void) const
3083 const SyncInfo syncInfo =
3085 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
3086 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags accessMask;
3087 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
3092 Data getData (void) const
3094 return getHostBufferData(m_context, *m_hostBuffer, m_resource.getBuffer().size);
3097 void setData (const Data& data)
3099 setHostBufferData(m_context, *m_hostBuffer, data);
3103 OperationContext& m_context;
3104 Resource& m_resource;
3105 const VkImageSubresourceRange m_subresourceRange;
3106 const VkImageSubresourceLayers m_subresourceLayers;
3107 de::MovePtr<Buffer> m_hostBuffer;
3108 de::MovePtr<Image> m_image;
3109 VkExtent3D m_imageExtent;
3112 class ReadImplementation : public Operation
3115 ReadImplementation (OperationContext& context, Resource& resource)
3116 : m_context (context)
3117 , m_resource (resource)
3118 , m_bufferSize (getPixelBufferSize(m_resource.getImage().format, m_resource.getImage().extent))
3120 DE_ASSERT(m_resource.getType() == RESOURCE_TYPE_IMAGE);
3122 const DeviceInterface& vk = m_context.getDeviceInterface();
3123 const VkDevice device = m_context.getDevice();
3124 Allocator& allocator = m_context.getAllocator();
3126 m_hostBuffer = de::MovePtr<Buffer>(new Buffer(
3127 vk, device, allocator, makeBufferCreateInfo(m_bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible));
3129 const Allocation& alloc = m_hostBuffer->getAllocation();
3130 deMemset(alloc.getHostPtr(), 0, static_cast<size_t>(m_bufferSize));
3131 flushAlloc(vk, device, alloc);
3134 void recordCommands (const VkCommandBuffer cmdBuffer)
3136 const DeviceInterface& vk = m_context.getDeviceInterface();
3137 const VkBufferImageCopy copyRegion = makeBufferImageCopy(m_resource.getImage().extent, m_resource.getImage().subresourceLayers);
3139 vk.cmdCopyImageToBuffer(cmdBuffer, m_resource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_hostBuffer, 1u, ©Region);
3141 // Insert a barrier so data written by the transfer is available to the host
3143 const VkBufferMemoryBarrier barrier = makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, **m_hostBuffer, 0u, VK_WHOLE_SIZE);
3144 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
3148 SyncInfo getInSyncInfo (void) const
3150 const SyncInfo syncInfo =
3152 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
3153 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags accessMask;
3154 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout imageLayout;
3159 SyncInfo getOutSyncInfo (void) const
3161 return emptySyncInfo;
3164 Data getData (void) const
3166 return getHostBufferData(m_context, *m_hostBuffer, m_bufferSize);
3169 void setData (const Data&)
3175 OperationContext& m_context;
3176 Resource& m_resource;
3177 de::MovePtr<Buffer> m_hostBuffer;
3178 const VkDeviceSize m_bufferSize;
3181 class CopyImplementation : public Operation
3184 CopyImplementation (OperationContext& context, Resource& inResource, Resource& outResource)
3185 : m_context (context)
3186 , m_inResource (inResource)
3187 , m_outResource (outResource)
3188 , m_subresourceRange (makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u))
3189 , m_subresourceLayers (makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u))
3191 DE_ASSERT(m_inResource.getType() == RESOURCE_TYPE_IMAGE);
3192 DE_ASSERT(m_outResource.getType() == RESOURCE_TYPE_BUFFER);
3195 void recordCommands (const VkCommandBuffer cmdBuffer)
3197 const DeviceInterface& vk = m_context.getDeviceInterface();
3198 const VkBufferImageCopy copyRegion = makeBufferImageCopy(m_inResource.getImage().extent, m_subresourceLayers);
3201 const VkImageMemoryBarrier imageLayoutBarrier = makeImageMemoryBarrier(
3202 (VkAccessFlags)0, VK_ACCESS_TRANSFER_READ_BIT,
3203 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
3204 m_inResource.getImage().handle, m_subresourceRange);
3205 const VkBufferMemoryBarrier bufferLayoutBarrier = makeBufferMemoryBarrier(
3206 (VkAccessFlags)0, VK_ACCESS_TRANSFER_WRITE_BIT,
3207 m_outResource.getBuffer().handle, 0, m_outResource.getBuffer().size);
3209 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0u, DE_NULL,
3210 1u, &bufferLayoutBarrier, 1u, &imageLayoutBarrier);
3213 vk.cmdCopyImageToBuffer(cmdBuffer, m_inResource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_outResource.getBuffer().handle, 1u, ©Region);
3216 SyncInfo getInSyncInfo (void) const
3218 const SyncInfo syncInfo =
3220 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
3221 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags accessMask;
3222 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
3227 SyncInfo getOutSyncInfo (void) const
3229 const SyncInfo syncInfo =
3231 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
3232 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags accessMask;
3233 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
3238 Data getData (void) const
3240 Data data = { 0, DE_NULL };
3244 void setData (const Data&)
3250 OperationContext& m_context;
3251 Resource& m_inResource;
3252 Resource& m_outResource;
3253 const VkImageSubresourceRange m_subresourceRange;
3254 const VkImageSubresourceLayers m_subresourceLayers;
3257 class Support : public OperationSupport
3260 Support (const ResourceDescription& resourceDesc, const AccessMode mode)
3262 , m_requiredQueueFlags (resourceDesc.type == RESOURCE_TYPE_IMAGE && isDepthStencilFormat(resourceDesc.imageFormat) ? VK_QUEUE_GRAPHICS_BIT : VK_QUEUE_TRANSFER_BIT)
3264 DE_ASSERT(m_mode == ACCESS_MODE_READ || m_mode == ACCESS_MODE_WRITE);
3265 DE_ASSERT(m_mode == ACCESS_MODE_READ || resourceDesc.type != RESOURCE_TYPE_IMAGE);
3266 DE_ASSERT(m_mode == ACCESS_MODE_WRITE || resourceDesc.type != RESOURCE_TYPE_BUFFER);
3269 deUint32 getInResourceUsageFlags (void) const
3271 return m_mode == ACCESS_MODE_READ ? VK_BUFFER_USAGE_TRANSFER_SRC_BIT : 0;
3274 deUint32 getOutResourceUsageFlags (void) const
3276 return m_mode == ACCESS_MODE_WRITE ? VK_BUFFER_USAGE_TRANSFER_DST_BIT : 0;
3279 VkQueueFlags getQueueFlags (const OperationContext& context) const
3282 return m_requiredQueueFlags;
3285 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
3287 if (m_mode == ACCESS_MODE_READ)
3288 return de::MovePtr<Operation>(new ReadImplementation(context, resource));
3290 return de::MovePtr<Operation>(new WriteImplementation(context, resource));
3293 de::MovePtr<Operation> build (OperationContext&, Resource&, Resource&) const
3296 return de::MovePtr<Operation>();
3300 const AccessMode m_mode;
3301 const VkQueueFlags m_requiredQueueFlags;
3304 } // CopyImageToBuffer ns
3306 namespace ClearImage
3312 CLEAR_MODE_DEPTH_STENCIL,
3315 class Implementation : public Operation
3318 Implementation (OperationContext& context, Resource& resource, const ClearMode mode)
3319 : m_context (context)
3320 , m_resource (resource)
3321 , m_clearValue (makeClearValue(m_resource.getImage().format))
3324 const VkDeviceSize size = getPixelBufferSize(m_resource.getImage().format, m_resource.getImage().extent);
3325 const VkExtent3D& extent = m_resource.getImage().extent;
3326 const VkFormat format = m_resource.getImage().format;
3327 const tcu::TextureFormat texFormat = mapVkFormat(format);
3329 m_data.resize(static_cast<std::size_t>(size));
3330 tcu::PixelBufferAccess imagePixels(texFormat, extent.width, extent.height, extent.depth, &m_data[0]);
3331 clearPixelBuffer(imagePixels, m_clearValue);
3334 void recordCommands (const VkCommandBuffer cmdBuffer)
3336 const DeviceInterface& vk = m_context.getDeviceInterface();
3338 const VkImageMemoryBarrier layoutBarrier = makeImageMemoryBarrier(
3339 (VkAccessFlags)0, VK_ACCESS_TRANSFER_WRITE_BIT,
3340 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
3341 m_resource.getImage().handle, m_resource.getImage().subresourceRange);
3343 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 0u, DE_NULL, 1u, &layoutBarrier);
3345 if (m_mode == CLEAR_MODE_COLOR)
3346 vk.cmdClearColorImage(cmdBuffer, m_resource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &m_clearValue.color, 1u, &m_resource.getImage().subresourceRange);
3348 vk.cmdClearDepthStencilImage(cmdBuffer, m_resource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &m_clearValue.depthStencil, 1u, &m_resource.getImage().subresourceRange);
3351 SyncInfo getInSyncInfo (void) const
3353 return emptySyncInfo;
3356 SyncInfo getOutSyncInfo (void) const
3358 const SyncInfo syncInfo =
3360 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
3361 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags accessMask;
3362 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout imageLayout;
3367 Data getData (void) const
3371 m_data.size(), // std::size_t size;
3372 &m_data[0], // const deUint8* data;
3377 void setData (const Data&)
3383 OperationContext& m_context;
3384 Resource& m_resource;
3385 std::vector<deUint8> m_data;
3386 const VkClearValue m_clearValue;
3387 const ClearMode m_mode;
3390 class Support : public OperationSupport
3393 Support (const ResourceDescription& resourceDesc, const ClearMode mode)
3394 : m_resourceDesc (resourceDesc)
3397 DE_ASSERT(m_mode == CLEAR_MODE_COLOR || m_mode == CLEAR_MODE_DEPTH_STENCIL);
3398 DE_ASSERT(m_resourceDesc.type == RESOURCE_TYPE_IMAGE);
3399 DE_ASSERT(m_resourceDesc.imageAspect == VK_IMAGE_ASPECT_COLOR_BIT || (m_mode != CLEAR_MODE_COLOR));
3400 DE_ASSERT((m_resourceDesc.imageAspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) || (m_mode != CLEAR_MODE_DEPTH_STENCIL));
3403 deUint32 getInResourceUsageFlags (void) const
3408 deUint32 getOutResourceUsageFlags (void) const
3410 return VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3413 VkQueueFlags getQueueFlags (const OperationContext& context) const
3416 if (m_mode == CLEAR_MODE_COLOR)
3417 return VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT;
3419 return VK_QUEUE_GRAPHICS_BIT;
3422 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
3424 return de::MovePtr<Operation>(new Implementation(context, resource, m_mode));
3427 de::MovePtr<Operation> build (OperationContext&, Resource&, Resource&) const
3430 return de::MovePtr<Operation>();
3434 const ResourceDescription m_resourceDesc;
3435 const ClearMode m_mode;
3446 DRAW_CALL_DRAW_INDEXED,
3447 DRAW_CALL_DRAW_INDIRECT,
3448 DRAW_CALL_DRAW_INDEXED_INDIRECT,
3451 //! A write operation that is a result of drawing to an image.
3452 //! \todo Add support for depth/stencil too?
3453 class Implementation : public Operation
3456 Implementation (OperationContext& context, Resource& resource, const DrawCall drawCall)
3457 : m_context (context)
3458 , m_resource (resource)
3459 , m_drawCall (drawCall)
3460 , m_vertices (context)
3462 const DeviceInterface& vk = context.getDeviceInterface();
3463 const VkDevice device = context.getDevice();
3464 Allocator& allocator = context.getAllocator();
3468 if (m_drawCall == DRAW_CALL_DRAW_INDIRECT)
3470 m_indirectBuffer = de::MovePtr<Buffer>(new Buffer(vk, device, allocator,
3471 makeBufferCreateInfo(sizeof(VkDrawIndirectCommand), VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT), MemoryRequirement::HostVisible));
3473 const Allocation& alloc = m_indirectBuffer->getAllocation();
3474 VkDrawIndirectCommand* const pIndirectCommand = static_cast<VkDrawIndirectCommand*>(alloc.getHostPtr());
3476 pIndirectCommand->vertexCount = m_vertices.getNumVertices();
3477 pIndirectCommand->instanceCount = 1u;
3478 pIndirectCommand->firstVertex = 0u;
3479 pIndirectCommand->firstInstance = 0u;
3481 flushAlloc(vk, device, alloc);
3483 else if (m_drawCall == DRAW_CALL_DRAW_INDEXED_INDIRECT)
3485 m_indirectBuffer = de::MovePtr<Buffer>(new Buffer(vk, device, allocator,
3486 makeBufferCreateInfo(sizeof(VkDrawIndexedIndirectCommand), VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT), MemoryRequirement::HostVisible));
3488 const Allocation& alloc = m_indirectBuffer->getAllocation();
3489 VkDrawIndexedIndirectCommand* const pIndirectCommand = static_cast<VkDrawIndexedIndirectCommand*>(alloc.getHostPtr());
3491 pIndirectCommand->indexCount = m_vertices.getNumIndices();
3492 pIndirectCommand->instanceCount = 1u;
3493 pIndirectCommand->firstIndex = 0u;
3494 pIndirectCommand->vertexOffset = 0u;
3495 pIndirectCommand->firstInstance = 0u;
3497 flushAlloc(vk, device, alloc);
3500 // Resource image is the color attachment
3502 m_colorFormat = m_resource.getImage().format;
3503 m_colorSubresourceRange = m_resource.getImage().subresourceRange;
3504 m_colorImage = m_resource.getImage().handle;
3505 m_attachmentExtent = m_resource.getImage().extent;
3509 m_colorAttachmentView = makeImageView (vk, device, m_colorImage, VK_IMAGE_VIEW_TYPE_2D, m_colorFormat, m_colorSubresourceRange);
3510 m_renderPass = makeRenderPass (vk, device, m_colorFormat);
3511 m_framebuffer = makeFramebuffer (vk, device, *m_renderPass, *m_colorAttachmentView, m_attachmentExtent.width, m_attachmentExtent.height);
3512 m_pipelineLayout = makePipelineLayout(vk, device);
3514 GraphicsPipelineBuilder pipelineBuilder;
3516 .setRenderSize (tcu::IVec2(m_attachmentExtent.width, m_attachmentExtent.height))
3517 .setVertexInputSingleAttribute (m_vertices.getVertexFormat(), m_vertices.getVertexStride())
3518 .setShader (vk, device, VK_SHADER_STAGE_VERTEX_BIT, context.getBinaryCollection().get("draw_vert"), DE_NULL)
3519 .setShader (vk, device, VK_SHADER_STAGE_FRAGMENT_BIT, context.getBinaryCollection().get("draw_frag"), DE_NULL);
3521 m_pipeline = pipelineBuilder.build(vk, device, *m_pipelineLayout, *m_renderPass, context.getPipelineCacheData());
3523 // Set expected draw values
3525 m_expectedData.resize(static_cast<size_t>(getPixelBufferSize(m_resource.getImage().format, m_resource.getImage().extent)));
3526 tcu::PixelBufferAccess imagePixels(mapVkFormat(m_colorFormat), m_attachmentExtent.width, m_attachmentExtent.height, m_attachmentExtent.depth, &m_expectedData[0]);
3527 clearPixelBuffer(imagePixels, makeClearValue(m_colorFormat));
3530 void recordCommands (const VkCommandBuffer cmdBuffer)
3532 const DeviceInterface& vk = m_context.getDeviceInterface();
3534 // Change color attachment image layout
3536 const VkImageMemoryBarrier colorAttachmentLayoutBarrier = makeImageMemoryBarrier(
3537 (VkAccessFlags)0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
3538 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
3539 m_colorImage, m_colorSubresourceRange);
3541 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0,
3542 0u, DE_NULL, 0u, DE_NULL, 1u, &colorAttachmentLayoutBarrier);
3546 const VkRect2D renderArea = makeRect2D(m_attachmentExtent);
3547 const tcu::Vec4 clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
3549 beginRenderPass(vk, cmdBuffer, *m_renderPass, *m_framebuffer, renderArea, clearColor);
3552 vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
3554 const VkDeviceSize vertexBufferOffset = 0ull;
3555 const VkBuffer vertexBuffer = m_vertices.getVertexBuffer();
3556 vk.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer, &vertexBufferOffset);
3559 if (m_drawCall == DRAW_CALL_DRAW_INDEXED || m_drawCall == DRAW_CALL_DRAW_INDEXED_INDIRECT)
3560 vk.cmdBindIndexBuffer(cmdBuffer, m_vertices.getIndexBuffer(), 0u, m_vertices.getIndexType());
3564 case DRAW_CALL_DRAW:
3565 vk.cmdDraw(cmdBuffer, m_vertices.getNumVertices(), 1u, 0u, 0u);
3568 case DRAW_CALL_DRAW_INDEXED:
3569 vk.cmdDrawIndexed(cmdBuffer, m_vertices.getNumIndices(), 1u, 0u, 0, 0u);
3572 case DRAW_CALL_DRAW_INDIRECT:
3573 vk.cmdDrawIndirect(cmdBuffer, **m_indirectBuffer, 0u, 1u, 0u);
3576 case DRAW_CALL_DRAW_INDEXED_INDIRECT:
3577 vk.cmdDrawIndexedIndirect(cmdBuffer, **m_indirectBuffer, 0u, 1u, 0u);
3581 endRenderPass(vk, cmdBuffer);
3584 SyncInfo getInSyncInfo (void) const
3586 return emptySyncInfo;
3589 SyncInfo getOutSyncInfo (void) const
3591 const SyncInfo syncInfo =
3593 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags stageMask;
3594 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags accessMask;
3595 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout imageLayout;
3600 Data getData (void) const
3604 m_expectedData.size(), // std::size_t size;
3605 &m_expectedData[0], // const deUint8* data;
3610 void setData (const Data& data)
3612 DE_ASSERT(m_expectedData.size() == data.size);
3613 deMemcpy(&m_expectedData[0], data.data, data.size);
3617 OperationContext& m_context;
3618 Resource& m_resource;
3619 const DrawCall m_drawCall;
3620 const VertexGrid m_vertices;
3621 std::vector<deUint8> m_expectedData;
3622 de::MovePtr<Buffer> m_indirectBuffer;
3623 VkFormat m_colorFormat;
3624 VkImage m_colorImage;
3625 Move<VkImageView> m_colorAttachmentView;
3626 VkImageSubresourceRange m_colorSubresourceRange;
3627 VkExtent3D m_attachmentExtent;
3628 Move<VkRenderPass> m_renderPass;
3629 Move<VkFramebuffer> m_framebuffer;
3630 Move<VkPipelineLayout> m_pipelineLayout;
3631 Move<VkPipeline> m_pipeline;
3634 template<typename T, std::size_t N>
3635 std::string toString (const T (&values)[N])
3637 std::ostringstream str;
3638 for (std::size_t i = 0; i < N; ++i)
3639 str << (i != 0 ? ", " : "") << values[i];
3643 class Support : public OperationSupport
3646 Support (const ResourceDescription& resourceDesc, const DrawCall drawCall)
3647 : m_resourceDesc (resourceDesc)
3648 , m_drawCall (drawCall)
3650 DE_ASSERT(m_resourceDesc.type == RESOURCE_TYPE_IMAGE && m_resourceDesc.imageType == VK_IMAGE_TYPE_2D);
3651 DE_ASSERT(!isDepthStencilFormat(m_resourceDesc.imageFormat));
3654 void initPrograms (SourceCollections& programCollection) const
3658 std::ostringstream src;
3659 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
3661 << "layout(location = 0) in vec4 v_in_position;\n"
3663 << "out " << s_perVertexBlock << ";\n"
3665 << "void main (void)\n"
3667 << " gl_Position = v_in_position;\n"
3670 programCollection.glslSources.add("draw_vert") << glu::VertexSource(src.str());
3675 const VkClearValue clearValue = makeClearValue(m_resourceDesc.imageFormat);
3676 const bool isIntegerFormat = isIntFormat(m_resourceDesc.imageFormat) || isUintFormat(m_resourceDesc.imageFormat);
3677 const std::string colorType = (isIntegerFormat ? "uvec4" : "vec4");
3679 std::ostringstream src;
3680 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
3682 << "layout(location = 0) out " << colorType << " o_color;\n"
3684 << "void main (void)\n"
3686 << " o_color = " << colorType << "(" << (isIntegerFormat ? toString(clearValue.color.uint32) : toString(clearValue.color.float32)) << ");\n"
3689 programCollection.glslSources.add("draw_frag") << glu::FragmentSource(src.str());
3693 deUint32 getInResourceUsageFlags (void) const
3698 deUint32 getOutResourceUsageFlags (void) const
3700 return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
3703 VkQueueFlags getQueueFlags (const OperationContext& context) const
3706 return VK_QUEUE_GRAPHICS_BIT;
3709 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
3711 return de::MovePtr<Operation>(new Implementation(context, resource, m_drawCall));
3714 de::MovePtr<Operation> build (OperationContext&, Resource&, Resource&) const
3717 return de::MovePtr<Operation>();
3721 const ResourceDescription m_resourceDesc;
3722 const DrawCall m_drawCall;
3727 namespace ClearAttachments
3730 class Implementation : public Operation
3733 Implementation (OperationContext& context, Resource& resource)
3734 : m_context (context)
3735 , m_resource (resource)
3736 , m_clearValue (makeClearValue(m_resource.getImage().format))
3738 const DeviceInterface& vk = context.getDeviceInterface();
3739 const VkDevice device = context.getDevice();
3741 const VkDeviceSize size = getPixelBufferSize(m_resource.getImage().format, m_resource.getImage().extent);
3742 const VkExtent3D& extent = m_resource.getImage().extent;
3743 const VkFormat format = m_resource.getImage().format;
3744 const tcu::TextureFormat texFormat = mapVkFormat(format);
3745 const SyncInfo syncInfo = getOutSyncInfo();
3747 m_data.resize(static_cast<std::size_t>(size));
3748 tcu::PixelBufferAccess imagePixels(texFormat, extent.width, extent.height, extent.depth, &m_data[0]);
3749 clearPixelBuffer(imagePixels, m_clearValue);
3751 m_attachmentView = makeImageView(vk, device, m_resource.getImage().handle, getImageViewType(m_resource.getImage().imageType), m_resource.getImage().format, m_resource.getImage().subresourceRange);
3753 switch (m_resource.getImage().subresourceRange.aspectMask)
3755 case VK_IMAGE_ASPECT_COLOR_BIT:
3756 m_renderPass = makeRenderPass(vk, device, m_resource.getImage().format, VK_FORMAT_UNDEFINED, VK_ATTACHMENT_LOAD_OP_DONT_CARE, syncInfo.imageLayout);
3758 case VK_IMAGE_ASPECT_STENCIL_BIT:
3759 case VK_IMAGE_ASPECT_DEPTH_BIT:
3760 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);
3767 m_frameBuffer = makeFramebuffer(vk, device, *m_renderPass, *m_attachmentView, m_resource.getImage().extent.width, m_resource.getImage().extent.height);
3770 void recordCommands (const VkCommandBuffer cmdBuffer)
3772 const DeviceInterface& vk = m_context.getDeviceInterface();
3773 beginRenderPass(vk, cmdBuffer, *m_renderPass, *m_frameBuffer, makeRect2D(0 ,0, m_resource.getImage().extent.width, m_resource.getImage().extent.height), m_clearValue);
3775 const VkClearAttachment clearAttachment =
3777 m_resource.getImage().subresourceRange.aspectMask, // VkImageAspectFlags aspectMask;
3778 0, // deUint32 colorAttachment;
3779 m_clearValue // VkClearValue clearValue;
3782 const VkRect2D rect2D = makeRect2D(m_resource.getImage().extent);
3784 const VkClearRect clearRect =
3786 rect2D, // VkRect2D rect;
3787 0u, // deUint32 baseArrayLayer;
3788 m_resource.getImage().subresourceLayers.layerCount // deUint32 layerCount;
3791 vk.cmdClearAttachments(cmdBuffer, 1, &clearAttachment, 1, &clearRect);
3793 endRenderPass(vk, cmdBuffer);
3796 SyncInfo getInSyncInfo (void) const
3798 return emptySyncInfo;
3801 SyncInfo getOutSyncInfo (void) const
3804 syncInfo.stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
3806 switch (m_resource.getImage().subresourceRange.aspectMask)
3808 case VK_IMAGE_ASPECT_COLOR_BIT:
3809 syncInfo.accessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
3810 syncInfo.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
3812 case VK_IMAGE_ASPECT_STENCIL_BIT:
3813 case VK_IMAGE_ASPECT_DEPTH_BIT:
3814 syncInfo.accessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
3815 syncInfo.imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
3825 Data getData (void) const
3829 m_data.size(), // std::size_t size;
3830 &m_data[0], // const deUint8* data;
3835 void setData (const Data&)
3841 OperationContext& m_context;
3842 Resource& m_resource;
3843 std::vector<deUint8> m_data;
3844 const VkClearValue m_clearValue;
3845 Move<VkImageView> m_attachmentView;
3846 Move<VkRenderPass> m_renderPass;
3847 Move<VkFramebuffer> m_frameBuffer;
3850 class Support : public OperationSupport
3853 Support (const ResourceDescription& resourceDesc)
3854 : m_resourceDesc (resourceDesc)
3856 DE_ASSERT(m_resourceDesc.type == RESOURCE_TYPE_IMAGE);
3859 deUint32 getInResourceUsageFlags (void) const
3864 deUint32 getOutResourceUsageFlags (void) const
3866 switch (m_resourceDesc.imageAspect)
3868 case VK_IMAGE_ASPECT_COLOR_BIT:
3869 return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
3870 case VK_IMAGE_ASPECT_STENCIL_BIT:
3871 case VK_IMAGE_ASPECT_DEPTH_BIT:
3872 return VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
3879 VkQueueFlags getQueueFlags (const OperationContext& context) const
3882 return VK_QUEUE_GRAPHICS_BIT;
3885 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
3887 return de::MovePtr<Operation>(new Implementation(context, resource));
3890 de::MovePtr<Operation> build (OperationContext&, Resource&, Resource&) const
3893 return de::MovePtr<Operation>();
3897 const ResourceDescription m_resourceDesc;
3900 } // ClearAttachments
3902 namespace IndirectBuffer
3905 class GraphicsPipeline : public Pipeline
3908 GraphicsPipeline (OperationContext& context,
3909 const ResourceType resourceType,
3910 const VkBuffer indirectBuffer,
3911 const std::string& shaderPrefix,
3912 const VkDescriptorSetLayout descriptorSetLayout)
3913 : m_resourceType (resourceType)
3914 , m_indirectBuffer (indirectBuffer)
3915 , m_vertices (context)
3917 const DeviceInterface& vk = context.getDeviceInterface();
3918 const VkDevice device = context.getDevice();
3919 Allocator& allocator = context.getAllocator();
3923 m_colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
3924 m_colorImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
3925 m_colorImageExtent = makeExtent3D(16u, 16u, 1u);
3926 m_colorAttachmentImage = de::MovePtr<Image>(new Image(vk, device, allocator,
3927 makeImageCreateInfo(VK_IMAGE_TYPE_2D, m_colorImageExtent, m_colorFormat, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT),
3928 MemoryRequirement::Any));
3932 m_colorAttachmentView = makeImageView (vk, device, **m_colorAttachmentImage, VK_IMAGE_VIEW_TYPE_2D, m_colorFormat, m_colorImageSubresourceRange);
3933 m_renderPass = makeRenderPass (vk, device, m_colorFormat);
3934 m_framebuffer = makeFramebuffer (vk, device, *m_renderPass, *m_colorAttachmentView, m_colorImageExtent.width, m_colorImageExtent.height);
3935 m_pipelineLayout = makePipelineLayout(vk, device, descriptorSetLayout);
3937 GraphicsPipelineBuilder pipelineBuilder;
3939 .setRenderSize (tcu::IVec2(m_colorImageExtent.width, m_colorImageExtent.height))
3940 .setVertexInputSingleAttribute (m_vertices.getVertexFormat(), m_vertices.getVertexStride())
3941 .setShader (vk, device, VK_SHADER_STAGE_VERTEX_BIT, context.getBinaryCollection().get(shaderPrefix + "vert"), DE_NULL)
3942 .setShader (vk, device, VK_SHADER_STAGE_FRAGMENT_BIT, context.getBinaryCollection().get(shaderPrefix + "frag"), DE_NULL);
3944 m_pipeline = pipelineBuilder.build(vk, device, *m_pipelineLayout, *m_renderPass, context.getPipelineCacheData());
3947 void recordCommands (OperationContext& context, const VkCommandBuffer cmdBuffer, const VkDescriptorSet descriptorSet)
3949 const DeviceInterface& vk = context.getDeviceInterface();
3951 // Change color attachment image layout
3953 const VkImageMemoryBarrier colorAttachmentLayoutBarrier = makeImageMemoryBarrier(
3954 (VkAccessFlags)0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
3955 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
3956 **m_colorAttachmentImage, m_colorImageSubresourceRange);
3958 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0,
3959 0u, DE_NULL, 0u, DE_NULL, 1u, &colorAttachmentLayoutBarrier);
3963 const VkRect2D renderArea = makeRect2D(m_colorImageExtent);
3964 const tcu::Vec4 clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
3966 beginRenderPass(vk, cmdBuffer, *m_renderPass, *m_framebuffer, renderArea, clearColor);
3969 vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
3970 vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &descriptorSet, 0u, DE_NULL);
3972 const VkDeviceSize vertexBufferOffset = 0ull;
3973 const VkBuffer vertexBuffer = m_vertices.getVertexBuffer();
3974 vk.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer, &vertexBufferOffset);
3977 switch (m_resourceType)
3979 case RESOURCE_TYPE_INDIRECT_BUFFER_DRAW:
3980 vk.cmdDrawIndirect(cmdBuffer, m_indirectBuffer, 0u, 1u, 0u);
3983 case RESOURCE_TYPE_INDIRECT_BUFFER_DRAW_INDEXED:
3984 vk.cmdBindIndexBuffer(cmdBuffer, m_vertices.getIndexBuffer(), 0u, m_vertices.getIndexType());
3985 vk.cmdDrawIndexedIndirect(cmdBuffer, m_indirectBuffer, 0u, 1u, 0u);
3992 endRenderPass(vk, cmdBuffer);
3996 const ResourceType m_resourceType;
3997 const VkBuffer m_indirectBuffer;
3998 const VertexGrid m_vertices;
3999 VkFormat m_colorFormat;
4000 de::MovePtr<Image> m_colorAttachmentImage;
4001 Move<VkImageView> m_colorAttachmentView;
4002 VkExtent3D m_colorImageExtent;
4003 VkImageSubresourceRange m_colorImageSubresourceRange;
4004 Move<VkRenderPass> m_renderPass;
4005 Move<VkFramebuffer> m_framebuffer;
4006 Move<VkPipelineLayout> m_pipelineLayout;
4007 Move<VkPipeline> m_pipeline;
4010 class ComputePipeline : public Pipeline
4013 ComputePipeline (OperationContext& context,
4014 const VkBuffer indirectBuffer,
4015 const std::string& shaderPrefix,
4016 const VkDescriptorSetLayout descriptorSetLayout)
4017 : m_indirectBuffer (indirectBuffer)
4019 const DeviceInterface& vk = context.getDeviceInterface();
4020 const VkDevice device = context.getDevice();
4022 const Unique<VkShaderModule> shaderModule(createShaderModule(vk, device, context.getBinaryCollection().get(shaderPrefix + "comp"), (VkShaderModuleCreateFlags)0));
4024 m_pipelineLayout = makePipelineLayout(vk, device, descriptorSetLayout);
4025 m_pipeline = makeComputePipeline(vk, device, *m_pipelineLayout, *shaderModule, DE_NULL, context.getPipelineCacheData());
4028 void recordCommands (OperationContext& context, const VkCommandBuffer cmdBuffer, const VkDescriptorSet descriptorSet)
4030 const DeviceInterface& vk = context.getDeviceInterface();
4032 vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipeline);
4033 vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0u, 1u, &descriptorSet, 0u, DE_NULL);
4034 vk.cmdDispatchIndirect(cmdBuffer, m_indirectBuffer, 0u);
4038 const VkBuffer m_indirectBuffer;
4039 Move<VkPipelineLayout> m_pipelineLayout;
4040 Move<VkPipeline> m_pipeline;
4043 //! Read indirect buffer by executing an indirect draw or dispatch command.
4044 class ReadImplementation : public Operation
4047 ReadImplementation (OperationContext& context, Resource& resource)
4048 : m_context (context)
4049 , m_resource (resource)
4050 , m_stage (resource.getType() == RESOURCE_TYPE_INDIRECT_BUFFER_DISPATCH ? VK_SHADER_STAGE_COMPUTE_BIT : VK_SHADER_STAGE_VERTEX_BIT)
4051 , m_pipelineStage (pipelineStageFlagsFromShaderStageFlagBits(m_stage))
4052 , m_hostBufferSizeBytes (sizeof(deUint32))
4054 requireFeaturesForSSBOAccess (m_context, m_stage);
4056 const DeviceInterface& vk = m_context.getDeviceInterface();
4057 const VkDevice device = m_context.getDevice();
4058 Allocator& allocator = m_context.getAllocator();
4060 m_hostBuffer = de::MovePtr<Buffer>(new Buffer(
4061 vk, device, allocator, makeBufferCreateInfo(m_hostBufferSizeBytes, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible));
4063 // Init host buffer data
4065 const Allocation& alloc = m_hostBuffer->getAllocation();
4066 deMemset(alloc.getHostPtr(), 0, static_cast<size_t>(m_hostBufferSizeBytes));
4067 flushAlloc(vk, device, alloc);
4070 // Prepare descriptors
4072 m_descriptorSetLayout = DescriptorSetLayoutBuilder()
4073 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, m_stage)
4076 m_descriptorPool = DescriptorPoolBuilder()
4077 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
4078 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
4080 m_descriptorSet = makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout);
4082 const VkDescriptorBufferInfo hostBufferInfo = makeDescriptorBufferInfo(**m_hostBuffer, 0u, m_hostBufferSizeBytes);
4084 DescriptorSetUpdateBuilder()
4085 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &hostBufferInfo)
4086 .update(vk, device);
4090 m_pipeline = (m_resource.getType() == RESOURCE_TYPE_INDIRECT_BUFFER_DISPATCH
4091 ? de::MovePtr<Pipeline>(new ComputePipeline(context, m_resource.getBuffer().handle, "read_ib_", *m_descriptorSetLayout))
4092 : de::MovePtr<Pipeline>(new GraphicsPipeline(context, m_resource.getType(), m_resource.getBuffer().handle, "read_ib_", *m_descriptorSetLayout)));
4095 void recordCommands (const VkCommandBuffer cmdBuffer)
4097 const DeviceInterface& vk = m_context.getDeviceInterface();
4099 m_pipeline->recordCommands(m_context, cmdBuffer, *m_descriptorSet);
4101 // Insert a barrier so data written by the shader is available to the host
4102 const VkBufferMemoryBarrier barrier = makeBufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, **m_hostBuffer, 0u, m_hostBufferSizeBytes);
4103 vk.cmdPipelineBarrier(cmdBuffer, m_pipelineStage, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
4106 SyncInfo getInSyncInfo (void) const
4108 const SyncInfo syncInfo =
4110 VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, // VkPipelineStageFlags stageMask;
4111 VK_ACCESS_INDIRECT_COMMAND_READ_BIT, // VkAccessFlags accessMask;
4112 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
4117 SyncInfo getOutSyncInfo (void) const
4119 return emptySyncInfo;
4122 Data getData (void) const
4124 return getHostBufferData(m_context, *m_hostBuffer, m_hostBufferSizeBytes);
4127 void setData (const Data&)
4133 OperationContext& m_context;
4134 Resource& m_resource;
4135 const VkShaderStageFlagBits m_stage;
4136 const VkPipelineStageFlags m_pipelineStage;
4137 const VkDeviceSize m_hostBufferSizeBytes;
4138 de::MovePtr<Buffer> m_hostBuffer;
4139 Move<VkDescriptorPool> m_descriptorPool;
4140 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
4141 Move<VkDescriptorSet> m_descriptorSet;
4142 de::MovePtr<Pipeline> m_pipeline;
4145 //! Prepare indirect buffer for a draw/dispatch call.
4146 class WriteImplementation : public Operation
4149 WriteImplementation (OperationContext& context, Resource& resource)
4150 : m_context (context)
4151 , m_resource (resource)
4153 switch (m_resource.getType())
4155 case RESOURCE_TYPE_INDIRECT_BUFFER_DRAW:
4157 m_drawIndirect.vertexCount = 6u;
4158 m_drawIndirect.instanceCount = 1u;
4159 m_drawIndirect.firstVertex = 0u;
4160 m_drawIndirect.firstInstance = 0u;
4162 m_indirectData = reinterpret_cast<deUint32*>(&m_drawIndirect);
4163 m_expectedValue = 6u;
4167 case RESOURCE_TYPE_INDIRECT_BUFFER_DRAW_INDEXED:
4169 m_drawIndexedIndirect.indexCount = 6u;
4170 m_drawIndexedIndirect.instanceCount = 1u;
4171 m_drawIndexedIndirect.firstIndex = 0u;
4172 m_drawIndexedIndirect.vertexOffset = 0u;
4173 m_drawIndexedIndirect.firstInstance = 0u;
4175 m_indirectData = reinterpret_cast<deUint32*>(&m_drawIndexedIndirect);
4176 m_expectedValue = 6u;
4180 case RESOURCE_TYPE_INDIRECT_BUFFER_DISPATCH:
4182 m_dispatchIndirect.x = 7u;
4183 m_dispatchIndirect.y = 2u;
4184 m_dispatchIndirect.z = 1u;
4186 m_indirectData = reinterpret_cast<deUint32*>(&m_dispatchIndirect);
4187 m_expectedValue = 14u;
4197 void recordCommands (const VkCommandBuffer cmdBuffer)
4199 const DeviceInterface& vk = m_context.getDeviceInterface();
4201 vk.cmdUpdateBuffer(cmdBuffer, m_resource.getBuffer().handle, m_resource.getBuffer().offset, m_resource.getBuffer().size, m_indirectData);
4204 SyncInfo getInSyncInfo (void) const
4206 return emptySyncInfo;
4209 SyncInfo getOutSyncInfo (void) const
4211 const SyncInfo syncInfo =
4213 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags stageMask;
4214 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags accessMask;
4215 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
4220 Data getData (void) const
4224 sizeof(deUint32), // std::size_t size;
4225 reinterpret_cast<const deUint8*>(&m_expectedValue), // const deUint8* data;
4230 void setData (const Data&)
4236 OperationContext& m_context;
4237 Resource& m_resource;
4238 VkDrawIndirectCommand m_drawIndirect;
4239 VkDrawIndexedIndirectCommand m_drawIndexedIndirect;
4240 VkDispatchIndirectCommand m_dispatchIndirect;
4241 deUint32* m_indirectData;
4242 deUint32 m_expectedValue; //! Side-effect value expected to be computed by a read (draw/dispatch) command.
4245 class ReadSupport : public OperationSupport
4248 ReadSupport (const ResourceDescription& resourceDesc)
4249 : m_resourceDesc (resourceDesc)
4251 DE_ASSERT(isIndirectBuffer(m_resourceDesc.type));
4254 void initPrograms (SourceCollections& programCollection) const
4256 std::ostringstream decl;
4257 decl << "layout(set = 0, binding = 0, std140) coherent buffer Data {\n"
4261 std::ostringstream main;
4262 main << " atomicAdd(sb_out.value, 1u);\n";
4266 std::ostringstream src;
4267 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
4269 << "layout(location = 0) in vec4 v_in_position;\n"
4271 << "out " << s_perVertexBlock << ";\n"
4275 << "void main (void)\n"
4277 << " gl_Position = v_in_position;\n"
4281 programCollection.glslSources.add("read_ib_vert") << glu::VertexSource(src.str());
4286 std::ostringstream src;
4287 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
4289 << "layout(location = 0) out vec4 o_color;\n"
4291 << "void main (void)\n"
4293 << " o_color = vec4(1.0);\n"
4296 programCollection.glslSources.add("read_ib_frag") << glu::FragmentSource(src.str());
4301 std::ostringstream src;
4302 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
4304 << "layout(local_size_x = 1) in;\n"
4308 << "void main (void)\n"
4313 programCollection.glslSources.add("read_ib_comp") << glu::ComputeSource(src.str());
4317 deUint32 getInResourceUsageFlags (void) const
4319 return VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
4322 deUint32 getOutResourceUsageFlags (void) const
4327 VkQueueFlags getQueueFlags (const OperationContext& context) const
4330 return (m_resourceDesc.type == RESOURCE_TYPE_INDIRECT_BUFFER_DISPATCH ? VK_QUEUE_COMPUTE_BIT : VK_QUEUE_GRAPHICS_BIT);
4333 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
4335 return de::MovePtr<Operation>(new ReadImplementation(context, resource));
4338 de::MovePtr<Operation> build (OperationContext&, Resource&, Resource&) const
4341 return de::MovePtr<Operation>();
4345 const ResourceDescription m_resourceDesc;
4349 class WriteSupport : public OperationSupport
4352 WriteSupport (const ResourceDescription& resourceDesc)
4354 DE_ASSERT(isIndirectBuffer(resourceDesc.type));
4355 DE_UNREF(resourceDesc);
4358 deUint32 getInResourceUsageFlags (void) const
4363 deUint32 getOutResourceUsageFlags (void) const
4365 return VK_BUFFER_USAGE_TRANSFER_DST_BIT;
4368 VkQueueFlags getQueueFlags (const OperationContext& context) const
4371 return VK_QUEUE_TRANSFER_BIT;
4374 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
4376 return de::MovePtr<Operation>(new WriteImplementation(context, resource));
4379 de::MovePtr<Operation> build (OperationContext&, Resource&, Resource&) const
4382 return de::MovePtr<Operation>();
4386 } // IndirectBuffer ns
4388 namespace VertexInput
4391 class Implementation : public Operation
4394 Implementation (OperationContext& context, Resource& resource)
4395 : m_context (context)
4396 , m_resource (resource)
4398 requireFeaturesForSSBOAccess (m_context, VK_SHADER_STAGE_VERTEX_BIT);
4400 const DeviceInterface& vk = context.getDeviceInterface();
4401 const VkDevice device = context.getDevice();
4402 Allocator& allocator = context.getAllocator();
4403 const VkDeviceSize dataSizeBytes = m_resource.getBuffer().size;
4405 m_outputBuffer = de::MovePtr<Buffer>(new Buffer(vk, device, allocator,
4406 makeBufferCreateInfo(dataSizeBytes, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible));
4409 const Allocation& alloc = m_outputBuffer->getAllocation();
4410 deMemset(alloc.getHostPtr(), 0, static_cast<size_t>(dataSizeBytes));
4411 flushAlloc(vk, device, alloc);
4414 m_descriptorSetLayout = DescriptorSetLayoutBuilder()
4415 .addSingleBinding (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_VERTEX_BIT)
4416 .build (vk, device);
4418 m_descriptorPool = DescriptorPoolBuilder()
4419 .addType (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
4420 .build (vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
4422 m_descriptorSet = makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout);
4424 const VkDescriptorBufferInfo outputBufferDescriptorInfo = makeDescriptorBufferInfo(m_outputBuffer->get(), 0ull, dataSizeBytes);
4425 DescriptorSetUpdateBuilder()
4426 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outputBufferDescriptorInfo)
4427 .update (vk, device);
4430 m_colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
4431 m_colorImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
4432 m_colorImageExtent = makeExtent3D(16u, 16u, 1u);
4433 m_colorAttachmentImage = de::MovePtr<Image>(new Image(vk, device, allocator,
4434 makeImageCreateInfo(VK_IMAGE_TYPE_2D, m_colorImageExtent, m_colorFormat, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT),
4435 MemoryRequirement::Any));
4438 m_colorAttachmentView = makeImageView (vk, device, **m_colorAttachmentImage, VK_IMAGE_VIEW_TYPE_2D, m_colorFormat, m_colorImageSubresourceRange);
4439 m_renderPass = makeRenderPass (vk, device, m_colorFormat);
4440 m_framebuffer = makeFramebuffer (vk, device, *m_renderPass, *m_colorAttachmentView, m_colorImageExtent.width, m_colorImageExtent.height);
4441 m_pipelineLayout = makePipelineLayout(vk, device, *m_descriptorSetLayout);
4443 m_pipeline = GraphicsPipelineBuilder()
4444 .setPrimitiveTopology (VK_PRIMITIVE_TOPOLOGY_POINT_LIST)
4445 .setRenderSize (tcu::IVec2(static_cast<int>(m_colorImageExtent.width), static_cast<int>(m_colorImageExtent.height)))
4446 .setVertexInputSingleAttribute (VK_FORMAT_R32G32B32A32_UINT, tcu::getPixelSize(mapVkFormat(VK_FORMAT_R32G32B32A32_UINT)))
4447 .setShader (vk, device, VK_SHADER_STAGE_VERTEX_BIT, context.getBinaryCollection().get("input_vert"), DE_NULL)
4448 .setShader (vk, device, VK_SHADER_STAGE_FRAGMENT_BIT, context.getBinaryCollection().get("input_frag"), DE_NULL)
4449 .build (vk, device, *m_pipelineLayout, *m_renderPass, context.getPipelineCacheData());
4452 void recordCommands (const VkCommandBuffer cmdBuffer)
4454 const DeviceInterface& vk = m_context.getDeviceInterface();
4455 const VkDeviceSize dataSizeBytes = m_resource.getBuffer().size;
4457 // Change color attachment image layout
4459 const VkImageMemoryBarrier colorAttachmentLayoutBarrier = makeImageMemoryBarrier(
4460 (VkAccessFlags)0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4461 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4462 **m_colorAttachmentImage, m_colorImageSubresourceRange);
4464 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0,
4465 0u, DE_NULL, 0u, DE_NULL, 1u, &colorAttachmentLayoutBarrier);
4469 const VkRect2D renderArea = makeRect2D(m_colorImageExtent);
4470 const tcu::Vec4 clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
4472 beginRenderPass(vk, cmdBuffer, *m_renderPass, *m_framebuffer, renderArea, clearColor);
4475 vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
4476 vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &m_descriptorSet.get(), 0u, DE_NULL);
4478 const VkDeviceSize vertexBufferOffset = 0ull;
4479 vk.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &m_resource.getBuffer().handle, &vertexBufferOffset);
4482 vk.cmdDraw(cmdBuffer, static_cast<deUint32>(dataSizeBytes / sizeof(tcu::UVec4)), 1u, 0u, 0u);
4484 endRenderPass(vk, cmdBuffer);
4486 // Insert a barrier so data written by the shader is available to the host
4488 const VkBufferMemoryBarrier barrier = makeBufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, **m_outputBuffer, 0u, m_resource.getBuffer().size);
4489 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
4493 SyncInfo getInSyncInfo (void) const
4495 const SyncInfo syncInfo =
4497 VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, // VkPipelineStageFlags stageMask;
4498 VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, // VkAccessFlags accessMask;
4499 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout;
4504 SyncInfo getOutSyncInfo (void) const
4506 return emptySyncInfo;
4509 Data getData (void) const
4511 return getHostBufferData(m_context, *m_outputBuffer, m_resource.getBuffer().size);
4514 void setData (const Data& data)
4516 setHostBufferData(m_context, *m_outputBuffer, data);
4520 OperationContext& m_context;
4521 Resource& m_resource;
4522 de::MovePtr<Buffer> m_outputBuffer;
4523 de::MovePtr<Buffer> m_indexBuffer;
4524 de::MovePtr<Buffer> m_indirectBuffer;
4525 Move<VkRenderPass> m_renderPass;
4526 Move<VkFramebuffer> m_framebuffer;
4527 Move<VkPipelineLayout> m_pipelineLayout;
4528 Move<VkPipeline> m_pipeline;
4529 VkFormat m_colorFormat;
4530 de::MovePtr<Image> m_colorAttachmentImage;
4531 Move<VkImageView> m_colorAttachmentView;
4532 VkExtent3D m_colorImageExtent;
4533 VkImageSubresourceRange m_colorImageSubresourceRange;
4534 Move<VkDescriptorPool> m_descriptorPool;
4535 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
4536 Move<VkDescriptorSet> m_descriptorSet;
4539 class Support : public OperationSupport
4542 Support (const ResourceDescription& resourceDesc)
4543 : m_resourceDesc (resourceDesc)
4545 DE_ASSERT(m_resourceDesc.type == RESOURCE_TYPE_BUFFER);
4548 void initPrograms (SourceCollections& programCollection) const
4552 int vertexStride = sizeof(tcu::UVec4);
4553 std::ostringstream src;
4554 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
4556 << "layout(location = 0) in uvec4 v_in_data;\n"
4557 << "layout(set = 0, binding = 0, std140) writeonly buffer Output {\n"
4558 << " uvec4 data[" << m_resourceDesc.size.x()/vertexStride << "];\n"
4561 << "void main (void)\n"
4563 << " b_out.data[gl_VertexIndex] = v_in_data;\n"
4564 << " gl_PointSize = 1.0f;\n"
4566 programCollection.glslSources.add("input_vert") << glu::VertexSource(src.str());
4571 std::ostringstream src;
4572 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
4574 << "layout(location = 0) out vec4 o_color;\n"
4576 << "void main (void)\n"
4578 << " o_color = vec4(1.0);\n"
4580 programCollection.glslSources.add("input_frag") << glu::FragmentSource(src.str());
4584 deUint32 getInResourceUsageFlags (void) const
4586 return VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
4589 deUint32 getOutResourceUsageFlags (void) const
4591 return VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
4594 VkQueueFlags getQueueFlags (const OperationContext& context) const
4597 return VK_QUEUE_GRAPHICS_BIT;
4600 de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const
4602 return de::MovePtr<Operation>(new Implementation(context, resource));
4605 de::MovePtr<Operation> build (OperationContext&, Resource&, Resource&) const
4608 return de::MovePtr<Operation>();
4612 const ResourceDescription m_resourceDesc;
4619 OperationContext::OperationContext (Context& context, PipelineCacheData& pipelineCacheData)
4620 : m_context (context)
4621 , m_vki (context.getInstanceInterface())
4622 , m_vk (context.getDeviceInterface())
4623 , m_physicalDevice (context.getPhysicalDevice())
4624 , m_device (context.getDevice())
4625 , m_allocator (context.getDefaultAllocator())
4626 , m_progCollection (context.getBinaryCollection())
4627 , m_pipelineCacheData (pipelineCacheData)
4631 OperationContext::OperationContext (Context& context, PipelineCacheData& pipelineCacheData, const DeviceInterface& vk, const VkDevice device, vk::Allocator& allocator)
4632 : m_context (context)
4633 , m_vki (context.getInstanceInterface())
4635 , m_physicalDevice (context.getPhysicalDevice())
4637 , m_allocator (allocator)
4638 , m_progCollection (context.getBinaryCollection())
4639 , m_pipelineCacheData (pipelineCacheData)
4643 OperationContext::OperationContext (Context& context,
4644 const vk::InstanceInterface& vki,
4645 const vk::DeviceInterface& vkd,
4646 vk::VkPhysicalDevice physicalDevice,
4647 vk::VkDevice device,
4648 vk::Allocator& allocator,
4649 vk::BinaryCollection& programCollection,
4650 PipelineCacheData& pipelineCacheData)
4651 : m_context (context)
4654 , m_physicalDevice (physicalDevice)
4656 , m_allocator (allocator)
4657 , m_progCollection (programCollection)
4658 , m_pipelineCacheData (pipelineCacheData)
4662 Resource::Resource (OperationContext& context, const ResourceDescription& desc, const deUint32 usage, const vk::VkSharingMode sharingMode, const std::vector<deUint32>& queueFamilyIndex)
4663 : m_type (desc.type)
4665 const DeviceInterface& vk = context.getDeviceInterface();
4666 const InstanceInterface& vki = context.getInstanceInterface();
4667 const VkDevice device = context.getDevice();
4668 const VkPhysicalDevice physDevice = context.getPhysicalDevice();
4669 Allocator& allocator = context.getAllocator();
4671 if (m_type == RESOURCE_TYPE_BUFFER || isIndirectBuffer(m_type))
4673 m_bufferData.offset = 0u;
4674 m_bufferData.size = static_cast<VkDeviceSize>(desc.size.x());
4675 VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(m_bufferData.size, usage);
4676 bufferCreateInfo.sharingMode = sharingMode;
4677 if (queueFamilyIndex.size() > 0)
4679 bufferCreateInfo.queueFamilyIndexCount = static_cast<deUint32>(queueFamilyIndex.size());
4680 bufferCreateInfo.pQueueFamilyIndices = &queueFamilyIndex[0];
4682 m_buffer = de::MovePtr<Buffer>(new Buffer(vk, device, allocator, bufferCreateInfo, MemoryRequirement::Any));
4683 m_bufferData.handle = **m_buffer;
4685 else if (m_type == RESOURCE_TYPE_IMAGE)
4687 m_imageData.extent = makeExtent3D(desc.size.x(), std::max(1, desc.size.y()), std::max(1, desc.size.z()));
4688 m_imageData.imageType = desc.imageType;
4689 m_imageData.format = desc.imageFormat;
4690 m_imageData.subresourceRange = makeImageSubresourceRange(desc.imageAspect, 0u, 1u, 0u, 1u);
4691 m_imageData.subresourceLayers = makeImageSubresourceLayers(desc.imageAspect, 0u, 0u, 1u);
4692 VkImageCreateInfo imageInfo = makeImageCreateInfo(m_imageData.imageType, m_imageData.extent, m_imageData.format, usage);
4693 imageInfo.sharingMode = sharingMode;
4694 if (queueFamilyIndex.size() > 0)
4696 imageInfo.queueFamilyIndexCount = static_cast<deUint32>(queueFamilyIndex.size());
4697 imageInfo.pQueueFamilyIndices = &queueFamilyIndex[0];
4700 VkImageFormatProperties imageFormatProperties;
4701 const VkResult formatResult = vki.getPhysicalDeviceImageFormatProperties(physDevice, imageInfo.format, imageInfo.imageType, imageInfo.tiling, imageInfo.usage, imageInfo.flags, &imageFormatProperties);
4703 if (formatResult != VK_SUCCESS)
4704 TCU_THROW(NotSupportedError, "Image format is not supported");
4706 m_image = de::MovePtr<Image>(new Image(vk, device, allocator, imageInfo, MemoryRequirement::Any));
4707 m_imageData.handle = **m_image;
4713 Resource::Resource (ResourceType type,
4714 vk::Move<vk::VkBuffer> buffer,
4715 de::MovePtr<vk::Allocation> allocation,
4716 vk::VkDeviceSize offset,
4717 vk::VkDeviceSize size)
4719 , m_buffer (new Buffer(buffer, allocation))
4721 DE_ASSERT(type != RESOURCE_TYPE_IMAGE);
4723 m_bufferData.handle = m_buffer->get();
4724 m_bufferData.offset = offset;
4725 m_bufferData.size = size;
4728 Resource::Resource (vk::Move<vk::VkImage> image,
4729 de::MovePtr<vk::Allocation> allocation,
4730 const vk::VkExtent3D& extent,
4731 vk::VkImageType imageType,
4732 vk::VkFormat format,
4733 vk::VkImageSubresourceRange subresourceRange,
4734 vk::VkImageSubresourceLayers subresourceLayers)
4735 : m_type (RESOURCE_TYPE_IMAGE)
4736 , m_image (new Image(image, allocation))
4738 m_imageData.handle = m_image->get();
4739 m_imageData.extent = extent;
4740 m_imageData.imageType = imageType;
4741 m_imageData.format = format;
4742 m_imageData.subresourceRange = subresourceRange;
4743 m_imageData.subresourceLayers = subresourceLayers;
4746 vk::VkDeviceMemory Resource::getMemory (void) const
4748 if (m_type == RESOURCE_TYPE_IMAGE)
4749 return m_image->getAllocation().getMemory();
4751 return m_buffer->getAllocation().getMemory();
4754 //! \note This function exists for performance reasons. We're creating a lot of tests and checking requirements here
4755 //! before creating an OperationSupport object is faster.
4756 bool isResourceSupported (const OperationName opName, const ResourceDescription& resourceDesc)
4760 case OPERATION_NAME_WRITE_FILL_BUFFER:
4761 case OPERATION_NAME_WRITE_COPY_BUFFER:
4762 case OPERATION_NAME_WRITE_COPY_IMAGE_TO_BUFFER:
4763 case OPERATION_NAME_WRITE_SSBO_VERTEX:
4764 case OPERATION_NAME_WRITE_SSBO_TESSELLATION_CONTROL:
4765 case OPERATION_NAME_WRITE_SSBO_TESSELLATION_EVALUATION:
4766 case OPERATION_NAME_WRITE_SSBO_GEOMETRY:
4767 case OPERATION_NAME_WRITE_SSBO_FRAGMENT:
4768 case OPERATION_NAME_WRITE_SSBO_COMPUTE:
4769 case OPERATION_NAME_WRITE_SSBO_COMPUTE_INDIRECT:
4770 case OPERATION_NAME_READ_COPY_BUFFER:
4771 case OPERATION_NAME_READ_COPY_BUFFER_TO_IMAGE:
4772 case OPERATION_NAME_READ_SSBO_VERTEX:
4773 case OPERATION_NAME_READ_SSBO_TESSELLATION_CONTROL:
4774 case OPERATION_NAME_READ_SSBO_TESSELLATION_EVALUATION:
4775 case OPERATION_NAME_READ_SSBO_GEOMETRY:
4776 case OPERATION_NAME_READ_SSBO_FRAGMENT:
4777 case OPERATION_NAME_READ_SSBO_COMPUTE:
4778 case OPERATION_NAME_READ_SSBO_COMPUTE_INDIRECT:
4779 case OPERATION_NAME_READ_VERTEX_INPUT:
4780 return resourceDesc.type == RESOURCE_TYPE_BUFFER;
4782 case OPERATION_NAME_WRITE_INDIRECT_BUFFER_DRAW:
4783 case OPERATION_NAME_READ_INDIRECT_BUFFER_DRAW:
4784 return resourceDesc.type == RESOURCE_TYPE_INDIRECT_BUFFER_DRAW;
4786 case OPERATION_NAME_WRITE_INDIRECT_BUFFER_DRAW_INDEXED:
4787 case OPERATION_NAME_READ_INDIRECT_BUFFER_DRAW_INDEXED:
4788 return resourceDesc.type == RESOURCE_TYPE_INDIRECT_BUFFER_DRAW_INDEXED;
4790 case OPERATION_NAME_WRITE_INDIRECT_BUFFER_DISPATCH:
4791 case OPERATION_NAME_READ_INDIRECT_BUFFER_DISPATCH:
4792 return resourceDesc.type == RESOURCE_TYPE_INDIRECT_BUFFER_DISPATCH;
4794 case OPERATION_NAME_WRITE_UPDATE_BUFFER:
4795 return resourceDesc.type == RESOURCE_TYPE_BUFFER && resourceDesc.size.x() <= MAX_UPDATE_BUFFER_SIZE;
4797 case OPERATION_NAME_WRITE_COPY_IMAGE:
4798 case OPERATION_NAME_WRITE_COPY_BUFFER_TO_IMAGE:
4799 case OPERATION_NAME_READ_COPY_IMAGE:
4800 case OPERATION_NAME_READ_COPY_IMAGE_TO_BUFFER:
4801 return resourceDesc.type == RESOURCE_TYPE_IMAGE;
4803 case OPERATION_NAME_WRITE_CLEAR_ATTACHMENTS:
4804 return resourceDesc.type == RESOURCE_TYPE_IMAGE && resourceDesc.imageType != VK_IMAGE_TYPE_3D;
4806 case OPERATION_NAME_WRITE_BLIT_IMAGE:
4807 case OPERATION_NAME_READ_BLIT_IMAGE:
4808 case OPERATION_NAME_WRITE_IMAGE_VERTEX:
4809 case OPERATION_NAME_WRITE_IMAGE_TESSELLATION_CONTROL:
4810 case OPERATION_NAME_WRITE_IMAGE_TESSELLATION_EVALUATION:
4811 case OPERATION_NAME_WRITE_IMAGE_GEOMETRY:
4812 case OPERATION_NAME_WRITE_IMAGE_FRAGMENT:
4813 case OPERATION_NAME_WRITE_IMAGE_COMPUTE:
4814 case OPERATION_NAME_WRITE_IMAGE_COMPUTE_INDIRECT:
4815 case OPERATION_NAME_READ_IMAGE_VERTEX:
4816 case OPERATION_NAME_READ_IMAGE_TESSELLATION_CONTROL:
4817 case OPERATION_NAME_READ_IMAGE_TESSELLATION_EVALUATION:
4818 case OPERATION_NAME_READ_IMAGE_GEOMETRY:
4819 case OPERATION_NAME_READ_IMAGE_FRAGMENT:
4820 case OPERATION_NAME_READ_IMAGE_COMPUTE:
4821 case OPERATION_NAME_READ_IMAGE_COMPUTE_INDIRECT:
4822 return resourceDesc.type == RESOURCE_TYPE_IMAGE && resourceDesc.imageAspect == VK_IMAGE_ASPECT_COLOR_BIT;
4824 case OPERATION_NAME_READ_UBO_VERTEX:
4825 case OPERATION_NAME_READ_UBO_TESSELLATION_CONTROL:
4826 case OPERATION_NAME_READ_UBO_TESSELLATION_EVALUATION:
4827 case OPERATION_NAME_READ_UBO_GEOMETRY:
4828 case OPERATION_NAME_READ_UBO_FRAGMENT:
4829 case OPERATION_NAME_READ_UBO_COMPUTE:
4830 case OPERATION_NAME_READ_UBO_COMPUTE_INDIRECT:
4831 return resourceDesc.type == RESOURCE_TYPE_BUFFER && resourceDesc.size.x() <= MAX_UBO_RANGE;
4833 case OPERATION_NAME_WRITE_CLEAR_COLOR_IMAGE:
4834 return resourceDesc.type == RESOURCE_TYPE_IMAGE && resourceDesc.imageAspect == VK_IMAGE_ASPECT_COLOR_BIT;
4836 case OPERATION_NAME_WRITE_CLEAR_DEPTH_STENCIL_IMAGE:
4837 return resourceDesc.type == RESOURCE_TYPE_IMAGE && (resourceDesc.imageAspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT));
4839 case OPERATION_NAME_WRITE_DRAW:
4840 case OPERATION_NAME_WRITE_DRAW_INDEXED:
4841 case OPERATION_NAME_WRITE_DRAW_INDIRECT:
4842 case OPERATION_NAME_WRITE_DRAW_INDEXED_INDIRECT:
4843 return resourceDesc.type == RESOURCE_TYPE_IMAGE && resourceDesc.imageType == VK_IMAGE_TYPE_2D
4844 && (resourceDesc.imageAspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) == 0;
4846 case OPERATION_NAME_COPY_BUFFER:
4847 case OPERATION_NAME_COPY_SSBO_VERTEX:
4848 case OPERATION_NAME_COPY_SSBO_TESSELLATION_CONTROL:
4849 case OPERATION_NAME_COPY_SSBO_TESSELLATION_EVALUATION:
4850 case OPERATION_NAME_COPY_SSBO_GEOMETRY:
4851 case OPERATION_NAME_COPY_SSBO_FRAGMENT:
4852 case OPERATION_NAME_COPY_SSBO_COMPUTE:
4853 case OPERATION_NAME_COPY_SSBO_COMPUTE_INDIRECT:
4854 return resourceDesc.type == RESOURCE_TYPE_BUFFER;
4856 case OPERATION_NAME_COPY_IMAGE:
4857 case OPERATION_NAME_BLIT_IMAGE:
4858 case OPERATION_NAME_COPY_IMAGE_VERTEX:
4859 case OPERATION_NAME_COPY_IMAGE_TESSELLATION_CONTROL:
4860 case OPERATION_NAME_COPY_IMAGE_TESSELLATION_EVALUATION:
4861 case OPERATION_NAME_COPY_IMAGE_GEOMETRY:
4862 case OPERATION_NAME_COPY_IMAGE_FRAGMENT:
4863 case OPERATION_NAME_COPY_IMAGE_COMPUTE:
4864 case OPERATION_NAME_COPY_IMAGE_COMPUTE_INDIRECT:
4865 return resourceDesc.type == RESOURCE_TYPE_IMAGE && resourceDesc.imageAspect == VK_IMAGE_ASPECT_COLOR_BIT;
4873 std::string getOperationName (const OperationName opName)
4877 case OPERATION_NAME_WRITE_FILL_BUFFER: return "write_fill_buffer";
4878 case OPERATION_NAME_WRITE_UPDATE_BUFFER: return "write_update_buffer";
4879 case OPERATION_NAME_WRITE_COPY_BUFFER: return "write_copy_buffer";
4880 case OPERATION_NAME_WRITE_COPY_BUFFER_TO_IMAGE: return "write_copy_buffer_to_image";
4881 case OPERATION_NAME_WRITE_COPY_IMAGE_TO_BUFFER: return "write_copy_image_to_buffer";
4882 case OPERATION_NAME_WRITE_COPY_IMAGE: return "write_copy_image";
4883 case OPERATION_NAME_WRITE_BLIT_IMAGE: return "write_blit_image";
4884 case OPERATION_NAME_WRITE_SSBO_VERTEX: return "write_ssbo_vertex";
4885 case OPERATION_NAME_WRITE_SSBO_TESSELLATION_CONTROL: return "write_ssbo_tess_control";
4886 case OPERATION_NAME_WRITE_SSBO_TESSELLATION_EVALUATION: return "write_ssbo_tess_eval";
4887 case OPERATION_NAME_WRITE_SSBO_GEOMETRY: return "write_ssbo_geometry";
4888 case OPERATION_NAME_WRITE_SSBO_FRAGMENT: return "write_ssbo_fragment";
4889 case OPERATION_NAME_WRITE_SSBO_COMPUTE: return "write_ssbo_compute";
4890 case OPERATION_NAME_WRITE_SSBO_COMPUTE_INDIRECT: return "write_ssbo_compute_indirect";
4891 case OPERATION_NAME_WRITE_IMAGE_VERTEX: return "write_image_vertex";
4892 case OPERATION_NAME_WRITE_IMAGE_TESSELLATION_CONTROL: return "write_image_tess_control";
4893 case OPERATION_NAME_WRITE_IMAGE_TESSELLATION_EVALUATION: return "write_image_tess_eval";
4894 case OPERATION_NAME_WRITE_IMAGE_GEOMETRY: return "write_image_geometry";
4895 case OPERATION_NAME_WRITE_IMAGE_FRAGMENT: return "write_image_fragment";
4896 case OPERATION_NAME_WRITE_IMAGE_COMPUTE: return "write_image_compute";
4897 case OPERATION_NAME_WRITE_IMAGE_COMPUTE_INDIRECT: return "write_image_compute_indirect";
4898 case OPERATION_NAME_WRITE_CLEAR_COLOR_IMAGE: return "write_clear_color_image";
4899 case OPERATION_NAME_WRITE_CLEAR_DEPTH_STENCIL_IMAGE: return "write_clear_depth_stencil_image";
4900 case OPERATION_NAME_WRITE_DRAW: return "write_draw";
4901 case OPERATION_NAME_WRITE_DRAW_INDEXED: return "write_draw_indexed";
4902 case OPERATION_NAME_WRITE_DRAW_INDIRECT: return "write_draw_indirect";
4903 case OPERATION_NAME_WRITE_DRAW_INDEXED_INDIRECT: return "write_draw_indexed_indirect";
4904 case OPERATION_NAME_WRITE_CLEAR_ATTACHMENTS: return "write_clear_attachments";
4905 case OPERATION_NAME_WRITE_INDIRECT_BUFFER_DRAW: return "write_indirect_buffer_draw";
4906 case OPERATION_NAME_WRITE_INDIRECT_BUFFER_DRAW_INDEXED: return "write_indirect_buffer_draw_indexed";
4907 case OPERATION_NAME_WRITE_INDIRECT_BUFFER_DISPATCH: return "write_indirect_buffer_dispatch";
4909 case OPERATION_NAME_READ_COPY_BUFFER: return "read_copy_buffer";
4910 case OPERATION_NAME_READ_COPY_BUFFER_TO_IMAGE: return "read_copy_buffer_to_image";
4911 case OPERATION_NAME_READ_COPY_IMAGE_TO_BUFFER: return "read_copy_image_to_buffer";
4912 case OPERATION_NAME_READ_COPY_IMAGE: return "read_copy_image";
4913 case OPERATION_NAME_READ_BLIT_IMAGE: return "read_blit_image";
4914 case OPERATION_NAME_READ_UBO_VERTEX: return "read_ubo_vertex";
4915 case OPERATION_NAME_READ_UBO_TESSELLATION_CONTROL: return "read_ubo_tess_control";
4916 case OPERATION_NAME_READ_UBO_TESSELLATION_EVALUATION: return "read_ubo_tess_eval";
4917 case OPERATION_NAME_READ_UBO_GEOMETRY: return "read_ubo_geometry";
4918 case OPERATION_NAME_READ_UBO_FRAGMENT: return "read_ubo_fragment";
4919 case OPERATION_NAME_READ_UBO_COMPUTE: return "read_ubo_compute";
4920 case OPERATION_NAME_READ_UBO_COMPUTE_INDIRECT: return "read_ubo_compute_indirect";
4921 case OPERATION_NAME_READ_SSBO_VERTEX: return "read_ssbo_vertex";
4922 case OPERATION_NAME_READ_SSBO_TESSELLATION_CONTROL: return "read_ssbo_tess_control";
4923 case OPERATION_NAME_READ_SSBO_TESSELLATION_EVALUATION: return "read_ssbo_tess_eval";
4924 case OPERATION_NAME_READ_SSBO_GEOMETRY: return "read_ssbo_geometry";
4925 case OPERATION_NAME_READ_SSBO_FRAGMENT: return "read_ssbo_fragment";
4926 case OPERATION_NAME_READ_SSBO_COMPUTE: return "read_ssbo_compute";
4927 case OPERATION_NAME_READ_SSBO_COMPUTE_INDIRECT: return "read_ssbo_compute_indirect";
4928 case OPERATION_NAME_READ_IMAGE_VERTEX: return "read_image_vertex";
4929 case OPERATION_NAME_READ_IMAGE_TESSELLATION_CONTROL: return "read_image_tess_control";
4930 case OPERATION_NAME_READ_IMAGE_TESSELLATION_EVALUATION: return "read_image_tess_eval";
4931 case OPERATION_NAME_READ_IMAGE_GEOMETRY: return "read_image_geometry";
4932 case OPERATION_NAME_READ_IMAGE_FRAGMENT: return "read_image_fragment";
4933 case OPERATION_NAME_READ_IMAGE_COMPUTE: return "read_image_compute";
4934 case OPERATION_NAME_READ_IMAGE_COMPUTE_INDIRECT: return "read_image_compute_indirect";
4935 case OPERATION_NAME_READ_INDIRECT_BUFFER_DRAW: return "read_indirect_buffer_draw";
4936 case OPERATION_NAME_READ_INDIRECT_BUFFER_DRAW_INDEXED: return "read_indirect_buffer_draw_indexed";
4937 case OPERATION_NAME_READ_INDIRECT_BUFFER_DISPATCH: return "read_indirect_buffer_dispatch";
4938 case OPERATION_NAME_READ_VERTEX_INPUT: return "read_vertex_input";
4940 case OPERATION_NAME_COPY_BUFFER: return "copy_buffer";
4941 case OPERATION_NAME_COPY_IMAGE: return "copy_image";
4942 case OPERATION_NAME_BLIT_IMAGE: return "blit_image";
4943 case OPERATION_NAME_COPY_SSBO_VERTEX: return "copy_buffer_vertex";
4944 case OPERATION_NAME_COPY_SSBO_TESSELLATION_CONTROL: return "copy_ssbo_tess_control";
4945 case OPERATION_NAME_COPY_SSBO_TESSELLATION_EVALUATION: return "copy_ssbo_tess_eval";
4946 case OPERATION_NAME_COPY_SSBO_GEOMETRY: return "copy_ssbo_geometry";
4947 case OPERATION_NAME_COPY_SSBO_FRAGMENT: return "copy_ssbo_fragment";
4948 case OPERATION_NAME_COPY_SSBO_COMPUTE: return "copy_ssbo_compute";
4949 case OPERATION_NAME_COPY_SSBO_COMPUTE_INDIRECT: return "copy_ssbo_compute_indirect";
4950 case OPERATION_NAME_COPY_IMAGE_VERTEX: return "copy_image_vertex";
4951 case OPERATION_NAME_COPY_IMAGE_TESSELLATION_CONTROL: return "copy_image_tess_control";
4952 case OPERATION_NAME_COPY_IMAGE_TESSELLATION_EVALUATION: return "copy_image_tess_eval";
4953 case OPERATION_NAME_COPY_IMAGE_GEOMETRY: return "copy_image_geometry";
4954 case OPERATION_NAME_COPY_IMAGE_FRAGMENT: return "copy_image_fragment";
4955 case OPERATION_NAME_COPY_IMAGE_COMPUTE: return "copy_image_compute";
4956 case OPERATION_NAME_COPY_IMAGE_COMPUTE_INDIRECT: return "copy_image_compute_indirect";
4963 de::MovePtr<OperationSupport> makeOperationSupport (const OperationName opName, const ResourceDescription& resourceDesc)
4967 case OPERATION_NAME_WRITE_FILL_BUFFER: return de::MovePtr<OperationSupport>(new FillUpdateBuffer ::Support (resourceDesc, FillUpdateBuffer::BUFFER_OP_FILL));
4968 case OPERATION_NAME_WRITE_UPDATE_BUFFER: return de::MovePtr<OperationSupport>(new FillUpdateBuffer ::Support (resourceDesc, FillUpdateBuffer::BUFFER_OP_UPDATE));
4969 case OPERATION_NAME_WRITE_COPY_BUFFER: return de::MovePtr<OperationSupport>(new CopyBuffer ::Support (resourceDesc, ACCESS_MODE_WRITE));
4970 case OPERATION_NAME_WRITE_COPY_BUFFER_TO_IMAGE: return de::MovePtr<OperationSupport>(new CopyBufferToImage ::Support (resourceDesc, ACCESS_MODE_WRITE));
4971 case OPERATION_NAME_WRITE_COPY_IMAGE_TO_BUFFER: return de::MovePtr<OperationSupport>(new CopyImageToBuffer ::Support (resourceDesc, ACCESS_MODE_WRITE));
4972 case OPERATION_NAME_WRITE_COPY_IMAGE: return de::MovePtr<OperationSupport>(new CopyBlitImage ::Support (resourceDesc, CopyBlitImage::TYPE_COPY, ACCESS_MODE_WRITE));
4973 case OPERATION_NAME_WRITE_BLIT_IMAGE: return de::MovePtr<OperationSupport>(new CopyBlitImage ::Support (resourceDesc, CopyBlitImage::TYPE_BLIT, ACCESS_MODE_WRITE));
4974 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));
4975 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));
4976 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));
4977 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));
4978 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));
4979 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));
4980 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));
4981 case OPERATION_NAME_WRITE_IMAGE_VERTEX: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_WRITE, VK_SHADER_STAGE_VERTEX_BIT));
4982 case OPERATION_NAME_WRITE_IMAGE_TESSELLATION_CONTROL: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_WRITE, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT));
4983 case OPERATION_NAME_WRITE_IMAGE_TESSELLATION_EVALUATION: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_WRITE, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT));
4984 case OPERATION_NAME_WRITE_IMAGE_GEOMETRY: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_WRITE, VK_SHADER_STAGE_GEOMETRY_BIT));
4985 case OPERATION_NAME_WRITE_IMAGE_FRAGMENT: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_WRITE, VK_SHADER_STAGE_FRAGMENT_BIT));
4986 case OPERATION_NAME_WRITE_IMAGE_COMPUTE: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_WRITE, VK_SHADER_STAGE_COMPUTE_BIT));
4987 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));
4988 case OPERATION_NAME_WRITE_CLEAR_COLOR_IMAGE: return de::MovePtr<OperationSupport>(new ClearImage ::Support (resourceDesc, ClearImage::CLEAR_MODE_COLOR));
4989 case OPERATION_NAME_WRITE_CLEAR_DEPTH_STENCIL_IMAGE: return de::MovePtr<OperationSupport>(new ClearImage ::Support (resourceDesc, ClearImage::CLEAR_MODE_DEPTH_STENCIL));
4990 case OPERATION_NAME_WRITE_DRAW: return de::MovePtr<OperationSupport>(new Draw ::Support (resourceDesc, Draw::DRAW_CALL_DRAW));
4991 case OPERATION_NAME_WRITE_DRAW_INDEXED: return de::MovePtr<OperationSupport>(new Draw ::Support (resourceDesc, Draw::DRAW_CALL_DRAW_INDEXED));
4992 case OPERATION_NAME_WRITE_DRAW_INDIRECT: return de::MovePtr<OperationSupport>(new Draw ::Support (resourceDesc, Draw::DRAW_CALL_DRAW_INDIRECT));
4993 case OPERATION_NAME_WRITE_DRAW_INDEXED_INDIRECT: return de::MovePtr<OperationSupport>(new Draw ::Support (resourceDesc, Draw::DRAW_CALL_DRAW_INDEXED_INDIRECT));
4994 case OPERATION_NAME_WRITE_CLEAR_ATTACHMENTS: return de::MovePtr<OperationSupport>(new ClearAttachments ::Support (resourceDesc));
4995 case OPERATION_NAME_WRITE_INDIRECT_BUFFER_DRAW: return de::MovePtr<OperationSupport>(new IndirectBuffer ::WriteSupport (resourceDesc));
4996 case OPERATION_NAME_WRITE_INDIRECT_BUFFER_DRAW_INDEXED: return de::MovePtr<OperationSupport>(new IndirectBuffer ::WriteSupport (resourceDesc));
4997 case OPERATION_NAME_WRITE_INDIRECT_BUFFER_DISPATCH: return de::MovePtr<OperationSupport>(new IndirectBuffer ::WriteSupport (resourceDesc));
4999 case OPERATION_NAME_READ_COPY_BUFFER: return de::MovePtr<OperationSupport>(new CopyBuffer ::Support (resourceDesc, ACCESS_MODE_READ));
5000 case OPERATION_NAME_READ_COPY_BUFFER_TO_IMAGE: return de::MovePtr<OperationSupport>(new CopyBufferToImage ::Support (resourceDesc, ACCESS_MODE_READ));
5001 case OPERATION_NAME_READ_COPY_IMAGE_TO_BUFFER: return de::MovePtr<OperationSupport>(new CopyImageToBuffer ::Support (resourceDesc, ACCESS_MODE_READ));
5002 case OPERATION_NAME_READ_COPY_IMAGE: return de::MovePtr<OperationSupport>(new CopyBlitImage ::Support (resourceDesc, CopyBlitImage::TYPE_COPY, ACCESS_MODE_READ));
5003 case OPERATION_NAME_READ_BLIT_IMAGE: return de::MovePtr<OperationSupport>(new CopyBlitImage ::Support (resourceDesc, CopyBlitImage::TYPE_BLIT, ACCESS_MODE_READ));
5004 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));
5005 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));
5006 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));
5007 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));
5008 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));
5009 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));
5010 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));
5011 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));
5012 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));
5013 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));
5014 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));
5015 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));
5016 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));
5017 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));
5018 case OPERATION_NAME_READ_IMAGE_VERTEX: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_READ, VK_SHADER_STAGE_VERTEX_BIT));
5019 case OPERATION_NAME_READ_IMAGE_TESSELLATION_CONTROL: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_READ, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT));
5020 case OPERATION_NAME_READ_IMAGE_TESSELLATION_EVALUATION: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_READ, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT));
5021 case OPERATION_NAME_READ_IMAGE_GEOMETRY: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_READ, VK_SHADER_STAGE_GEOMETRY_BIT));
5022 case OPERATION_NAME_READ_IMAGE_FRAGMENT: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_READ, VK_SHADER_STAGE_FRAGMENT_BIT));
5023 case OPERATION_NAME_READ_IMAGE_COMPUTE: return de::MovePtr<OperationSupport>(new ShaderAccess ::ImageSupport (resourceDesc, ACCESS_MODE_READ, VK_SHADER_STAGE_COMPUTE_BIT));
5024 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));
5025 case OPERATION_NAME_READ_INDIRECT_BUFFER_DRAW: return de::MovePtr<OperationSupport>(new IndirectBuffer ::ReadSupport (resourceDesc));
5026 case OPERATION_NAME_READ_INDIRECT_BUFFER_DRAW_INDEXED: return de::MovePtr<OperationSupport>(new IndirectBuffer ::ReadSupport (resourceDesc));
5027 case OPERATION_NAME_READ_INDIRECT_BUFFER_DISPATCH: return de::MovePtr<OperationSupport>(new IndirectBuffer ::ReadSupport (resourceDesc));
5028 case OPERATION_NAME_READ_VERTEX_INPUT: return de::MovePtr<OperationSupport>(new VertexInput ::Support (resourceDesc));
5030 case OPERATION_NAME_COPY_BUFFER: return de::MovePtr<OperationSupport>(new CopyBuffer ::CopySupport (resourceDesc));
5031 case OPERATION_NAME_COPY_IMAGE: return de::MovePtr<OperationSupport>(new CopyBlitImage ::CopySupport (resourceDesc, CopyBlitImage::TYPE_COPY));
5032 case OPERATION_NAME_BLIT_IMAGE: return de::MovePtr<OperationSupport>(new CopyBlitImage ::CopySupport (resourceDesc, CopyBlitImage::TYPE_BLIT));
5033 case OPERATION_NAME_COPY_SSBO_VERTEX: return de::MovePtr<OperationSupport>(new ShaderAccess ::CopyBufferSupport (resourceDesc, BUFFER_TYPE_STORAGE, VK_SHADER_STAGE_VERTEX_BIT));
5034 case OPERATION_NAME_COPY_SSBO_TESSELLATION_CONTROL: return de::MovePtr<OperationSupport>(new ShaderAccess ::CopyBufferSupport (resourceDesc, BUFFER_TYPE_STORAGE, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT));
5035 case OPERATION_NAME_COPY_SSBO_TESSELLATION_EVALUATION: return de::MovePtr<OperationSupport>(new ShaderAccess ::CopyBufferSupport (resourceDesc, BUFFER_TYPE_STORAGE, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT));
5036 case OPERATION_NAME_COPY_SSBO_GEOMETRY: return de::MovePtr<OperationSupport>(new ShaderAccess ::CopyBufferSupport (resourceDesc, BUFFER_TYPE_STORAGE, VK_SHADER_STAGE_GEOMETRY_BIT));
5037 case OPERATION_NAME_COPY_SSBO_FRAGMENT: return de::MovePtr<OperationSupport>(new ShaderAccess ::CopyBufferSupport (resourceDesc, BUFFER_TYPE_STORAGE, VK_SHADER_STAGE_FRAGMENT_BIT));
5038 case OPERATION_NAME_COPY_SSBO_COMPUTE: return de::MovePtr<OperationSupport>(new ShaderAccess ::CopyBufferSupport (resourceDesc, BUFFER_TYPE_STORAGE, VK_SHADER_STAGE_COMPUTE_BIT));
5039 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));
5040 case OPERATION_NAME_COPY_IMAGE_VERTEX: return de::MovePtr<OperationSupport>(new ShaderAccess ::CopyImageSupport (resourceDesc, VK_SHADER_STAGE_VERTEX_BIT));
5041 case OPERATION_NAME_COPY_IMAGE_TESSELLATION_CONTROL: return de::MovePtr<OperationSupport>(new ShaderAccess ::CopyImageSupport (resourceDesc, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT));
5042 case OPERATION_NAME_COPY_IMAGE_TESSELLATION_EVALUATION: return de::MovePtr<OperationSupport>(new ShaderAccess ::CopyImageSupport (resourceDesc, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT));
5043 case OPERATION_NAME_COPY_IMAGE_GEOMETRY: return de::MovePtr<OperationSupport>(new ShaderAccess ::CopyImageSupport (resourceDesc, VK_SHADER_STAGE_GEOMETRY_BIT));
5044 case OPERATION_NAME_COPY_IMAGE_FRAGMENT: return de::MovePtr<OperationSupport>(new ShaderAccess ::CopyImageSupport (resourceDesc, VK_SHADER_STAGE_FRAGMENT_BIT));
5045 case OPERATION_NAME_COPY_IMAGE_COMPUTE: return de::MovePtr<OperationSupport>(new ShaderAccess ::CopyImageSupport (resourceDesc, VK_SHADER_STAGE_COMPUTE_BIT));
5046 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));
5050 return de::MovePtr<OperationSupport>();
5054 } // synchronization