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.
20 * \file vktPipelineMultisampleBaseResolveAndPerSampleFetch.cpp
21 * \brief Base class for tests that check results of multisample resolve
22 * and/or values of individual samples
23 *//*--------------------------------------------------------------------*/
25 #include "vktPipelineMultisampleBaseResolveAndPerSampleFetch.hpp"
26 #include "vktPipelineMakeUtil.hpp"
27 #include "vkBuilderUtil.hpp"
28 #include "vkQueryUtil.hpp"
29 #include "tcuTestLog.hpp"
41 void MSCaseBaseResolveAndPerSampleFetch::initPrograms (vk::SourceCollections& programCollection) const
43 // Create vertex shader
44 std::ostringstream vs;
46 vs << "#version 440\n"
47 << "layout(location = 0) in vec4 vs_in_position_ndc;\n"
49 << "out gl_PerVertex {\n"
50 << " vec4 gl_Position;\n"
52 << "void main (void)\n"
54 << " gl_Position = vs_in_position_ndc;\n"
57 programCollection.glslSources.add("per_sample_fetch_vs") << glu::VertexSource(vs.str());
59 // Create fragment shader
60 std::ostringstream fs;
62 fs << "#version 440\n"
64 << "layout(location = 0) out vec4 fs_out_color;\n"
66 << "layout(set = 0, binding = 0, input_attachment_index = 0) uniform subpassInputMS imageMS;\n"
68 << "layout(set = 0, binding = 1, std140) uniform SampleBlock {\n"
69 << " int sampleNdx;\n"
71 << "void main (void)\n"
73 << " fs_out_color = subpassLoad(imageMS, sampleNdx);\n"
76 programCollection.glslSources.add("per_sample_fetch_fs") << glu::FragmentSource(fs.str());
79 VkPipelineMultisampleStateCreateInfo MSInstanceBaseResolveAndPerSampleFetch::getMSStateCreateInfo (const ImageMSParams& imageMSParams) const
81 const VkPipelineMultisampleStateCreateInfo multisampleStateInfo =
83 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
84 DE_NULL, // const void* pNext;
85 (VkPipelineMultisampleStateCreateFlags)0u, // VkPipelineMultisampleStateCreateFlags flags;
86 imageMSParams.numSamples, // VkSampleCountFlagBits rasterizationSamples;
87 VK_TRUE, // VkBool32 sampleShadingEnable;
88 1.0f, // float minSampleShading;
89 DE_NULL, // const VkSampleMask* pSampleMask;
90 VK_FALSE, // VkBool32 alphaToCoverageEnable;
91 VK_FALSE, // VkBool32 alphaToOneEnable;
94 return multisampleStateInfo;
97 const VkDescriptorSetLayout* MSInstanceBaseResolveAndPerSampleFetch::createMSPassDescSetLayout(const ImageMSParams& imageMSParams)
99 DE_UNREF(imageMSParams);
104 const VkDescriptorSet* MSInstanceBaseResolveAndPerSampleFetch::createMSPassDescSet(const ImageMSParams& imageMSParams, const VkDescriptorSetLayout* descSetLayout)
106 DE_UNREF(imageMSParams);
107 DE_UNREF(descSetLayout);
112 tcu::TestStatus MSInstanceBaseResolveAndPerSampleFetch::iterate (void)
114 const InstanceInterface& instance = m_context.getInstanceInterface();
115 const DeviceInterface& deviceInterface = m_context.getDeviceInterface();
116 const VkDevice device = m_context.getDevice();
117 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
118 Allocator& allocator = m_context.getDefaultAllocator();
119 const VkQueue queue = m_context.getUniversalQueue();
120 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
122 VkImageCreateInfo imageMSInfo;
123 VkImageCreateInfo imageRSInfo;
124 const deUint32 firstSubpassAttachmentsCount = 2u;
126 // Check if image size does not exceed device limits
127 validateImageSize(instance, physicalDevice, m_imageType, m_imageMSParams.imageSize);
129 // Check if device supports image format as color attachment
130 validateImageFeatureFlags(instance, physicalDevice, mapTextureFormat(m_imageFormat), VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT);
132 imageMSInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
133 imageMSInfo.pNext = DE_NULL;
134 imageMSInfo.flags = 0u;
135 imageMSInfo.imageType = mapImageType(m_imageType);
136 imageMSInfo.format = mapTextureFormat(m_imageFormat);
137 imageMSInfo.extent = makeExtent3D(getLayerSize(m_imageType, m_imageMSParams.imageSize));
138 imageMSInfo.arrayLayers = getNumLayers(m_imageType, m_imageMSParams.imageSize);
139 imageMSInfo.mipLevels = 1u;
140 imageMSInfo.samples = m_imageMSParams.numSamples;
141 imageMSInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
142 imageMSInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
143 imageMSInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
144 imageMSInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
145 imageMSInfo.queueFamilyIndexCount = 0u;
146 imageMSInfo.pQueueFamilyIndices = DE_NULL;
148 if (m_imageType == IMAGE_TYPE_CUBE || m_imageType == IMAGE_TYPE_CUBE_ARRAY)
150 imageMSInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
153 validateImageInfo(instance, physicalDevice, imageMSInfo);
155 const de::UniquePtr<Image> imageMS(new Image(deviceInterface, device, allocator, imageMSInfo, MemoryRequirement::Any));
157 imageRSInfo = imageMSInfo;
158 imageRSInfo.samples = VK_SAMPLE_COUNT_1_BIT;
159 imageRSInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
161 validateImageInfo(instance, physicalDevice, imageRSInfo);
163 const de::UniquePtr<Image> imageRS(new Image(deviceInterface, device, allocator, imageRSInfo, MemoryRequirement::Any));
165 const deUint32 numSamples = static_cast<deUint32>(imageMSInfo.samples);
167 std::vector<de::SharedPtr<Image> > imagesPerSampleVec(numSamples);
169 for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
171 imagesPerSampleVec[sampleNdx] = de::SharedPtr<Image>(new Image(deviceInterface, device, allocator, imageRSInfo, MemoryRequirement::Any));
174 // Create render pass
175 std::vector<VkAttachmentDescription> attachments(firstSubpassAttachmentsCount + numSamples);
178 const VkAttachmentDescription attachmentMSDesc =
180 (VkAttachmentDescriptionFlags)0u, // VkAttachmentDescriptionFlags flags;
181 imageMSInfo.format, // VkFormat format;
182 imageMSInfo.samples, // VkSampleCountFlagBits samples;
183 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
184 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
185 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
186 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
187 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
188 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout finalLayout;
191 attachments[0] = attachmentMSDesc;
193 const VkAttachmentDescription attachmentRSDesc =
195 (VkAttachmentDescriptionFlags)0u, // VkAttachmentDescriptionFlags flags;
196 imageRSInfo.format, // VkFormat format;
197 imageRSInfo.samples, // VkSampleCountFlagBits samples;
198 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
199 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
200 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
201 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
202 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
203 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout;
206 attachments[1] = attachmentRSDesc;
208 for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
210 attachments[firstSubpassAttachmentsCount + sampleNdx] = attachmentRSDesc;
214 const VkAttachmentReference attachmentMSColorRef =
216 0u, // deUint32 attachment;
217 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
220 const VkAttachmentReference attachmentMSInputRef =
222 0u, // deUint32 attachment;
223 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout layout;
226 const VkAttachmentReference attachmentRSColorRef =
228 1u, // deUint32 attachment;
229 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
232 std::vector<VkAttachmentReference> perSampleAttachmentRef(numSamples);
234 for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
236 const VkAttachmentReference attachmentRef =
238 firstSubpassAttachmentsCount + sampleNdx, // deUint32 attachment;
239 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
242 perSampleAttachmentRef[sampleNdx] = attachmentRef;
245 std::vector<deUint32> preserveAttachments(1u + numSamples);
247 for (deUint32 attachNdx = 0u; attachNdx < 1u + numSamples; ++attachNdx)
249 preserveAttachments[attachNdx] = 1u + attachNdx;
252 std::vector<VkSubpassDescription> subpasses(1u + numSamples);
253 std::vector<VkSubpassDependency> subpassDependencies(numSamples);
255 const VkSubpassDescription firstSubpassDesc =
257 (VkSubpassDescriptionFlags)0u, // VkSubpassDescriptionFlags flags;
258 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
259 0u, // deUint32 inputAttachmentCount;
260 DE_NULL, // const VkAttachmentReference* pInputAttachments;
261 1u, // deUint32 colorAttachmentCount;
262 &attachmentMSColorRef, // const VkAttachmentReference* pColorAttachments;
263 &attachmentRSColorRef, // const VkAttachmentReference* pResolveAttachments;
264 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
265 0u, // deUint32 preserveAttachmentCount;
266 DE_NULL // const deUint32* pPreserveAttachments;
269 subpasses[0] = firstSubpassDesc;
271 for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
273 const VkSubpassDescription subpassDesc =
275 (VkSubpassDescriptionFlags)0u, // VkSubpassDescriptionFlags flags;
276 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
277 1u, // deUint32 inputAttachmentCount;
278 &attachmentMSInputRef, // const VkAttachmentReference* pInputAttachments;
279 1u, // deUint32 colorAttachmentCount;
280 &perSampleAttachmentRef[sampleNdx], // const VkAttachmentReference* pColorAttachments;
281 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
282 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
283 1u + sampleNdx, // deUint32 preserveAttachmentCount;
284 dataPointer(preserveAttachments) // const deUint32* pPreserveAttachments;
287 subpasses[1u + sampleNdx] = subpassDesc;
289 const VkSubpassDependency subpassDependency =
291 0u, // uint32_t srcSubpass;
292 1u + sampleNdx, // uint32_t dstSubpass;
293 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags srcStageMask;
294 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // VkPipelineStageFlags dstStageMask;
295 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask;
296 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // VkAccessFlags dstAccessMask;
297 0u, // VkDependencyFlags dependencyFlags;
300 subpassDependencies[sampleNdx] = subpassDependency;
303 const VkRenderPassCreateInfo renderPassInfo =
305 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
306 DE_NULL, // const void* pNext;
307 (VkRenderPassCreateFlags)0u, // VkRenderPassCreateFlags flags;
308 static_cast<deUint32>(attachments.size()), // deUint32 attachmentCount;
309 dataPointer(attachments), // const VkAttachmentDescription* pAttachments;
310 static_cast<deUint32>(subpasses.size()), // deUint32 subpassCount;
311 dataPointer(subpasses), // const VkSubpassDescription* pSubpasses;
312 static_cast<deUint32>(subpassDependencies.size()), // deUint32 dependencyCount;
313 dataPointer(subpassDependencies) // const VkSubpassDependency* pDependencies;
316 const Unique<VkRenderPass> renderPass(createRenderPass(deviceInterface, device, &renderPassInfo));
318 const VkImageSubresourceRange fullImageRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageMSInfo.mipLevels, 0u, imageMSInfo.arrayLayers);
320 // Create color attachments image views
321 typedef de::SharedPtr<Unique<VkImageView> > VkImageViewSp;
322 std::vector<VkImageViewSp> imageViewsShPtrs(firstSubpassAttachmentsCount + numSamples);
323 std::vector<VkImageView> imageViews(firstSubpassAttachmentsCount + numSamples);
325 imageViewsShPtrs[0] = makeVkSharedPtr(makeImageView(deviceInterface, device, **imageMS, mapImageViewType(m_imageType), imageMSInfo.format, fullImageRange));
326 imageViewsShPtrs[1] = makeVkSharedPtr(makeImageView(deviceInterface, device, **imageRS, mapImageViewType(m_imageType), imageRSInfo.format, fullImageRange));
328 imageViews[0] = **imageViewsShPtrs[0];
329 imageViews[1] = **imageViewsShPtrs[1];
331 for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
333 imageViewsShPtrs[firstSubpassAttachmentsCount + sampleNdx] = makeVkSharedPtr(makeImageView(deviceInterface, device, **imagesPerSampleVec[sampleNdx], mapImageViewType(m_imageType), imageRSInfo.format, fullImageRange));
334 imageViews[firstSubpassAttachmentsCount + sampleNdx] = **imageViewsShPtrs[firstSubpassAttachmentsCount + sampleNdx];
337 // Create framebuffer
338 const VkFramebufferCreateInfo framebufferInfo =
340 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
341 DE_NULL, // const void* pNext;
342 (VkFramebufferCreateFlags)0u, // VkFramebufferCreateFlags flags;
343 *renderPass, // VkRenderPass renderPass;
344 static_cast<deUint32>(imageViews.size()), // uint32_t attachmentCount;
345 dataPointer(imageViews), // const VkImageView* pAttachments;
346 imageMSInfo.extent.width, // uint32_t width;
347 imageMSInfo.extent.height, // uint32_t height;
348 imageMSInfo.arrayLayers, // uint32_t layers;
351 const Unique<VkFramebuffer> framebuffer(createFramebuffer(deviceInterface, device, &framebufferInfo));
353 const VkDescriptorSetLayout* descriptorSetLayoutMSPass = createMSPassDescSetLayout(m_imageMSParams);
355 // Create pipeline layout
356 const VkPipelineLayoutCreateInfo pipelineLayoutMSPassParams =
358 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
359 DE_NULL, // const void* pNext;
360 (VkPipelineLayoutCreateFlags)0u, // VkPipelineLayoutCreateFlags flags;
361 descriptorSetLayoutMSPass ? 1u : 0u, // deUint32 setLayoutCount;
362 descriptorSetLayoutMSPass, // const VkDescriptorSetLayout* pSetLayouts;
363 0u, // deUint32 pushConstantRangeCount;
364 DE_NULL, // const VkPushConstantRange* pPushConstantRanges;
367 const Unique<VkPipelineLayout> pipelineLayoutMSPass(createPipelineLayout(deviceInterface, device, &pipelineLayoutMSPassParams));
369 // Create vertex attributes data
370 const VertexDataDesc vertexDataDesc = getVertexDataDescripton();
372 de::SharedPtr<Buffer> vertexBuffer = de::SharedPtr<Buffer>(new Buffer(deviceInterface, device, allocator, makeBufferCreateInfo(vertexDataDesc.dataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible));
373 const Allocation& vertexBufferAllocation = vertexBuffer->getAllocation();
375 uploadVertexData(vertexBufferAllocation, vertexDataDesc);
377 flushMappedMemoryRange(deviceInterface, device, vertexBufferAllocation.getMemory(), vertexBufferAllocation.getOffset(), VK_WHOLE_SIZE);
379 const VkVertexInputBindingDescription vertexBinding =
381 0u, // deUint32 binding;
382 vertexDataDesc.dataStride, // deUint32 stride;
383 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate inputRate;
386 const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
388 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
389 DE_NULL, // const void* pNext;
390 (VkPipelineVertexInputStateCreateFlags)0u, // VkPipelineVertexInputStateCreateFlags flags;
391 1u, // uint32_t vertexBindingDescriptionCount;
392 &vertexBinding, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
393 static_cast<deUint32>(vertexDataDesc.vertexAttribDescVec.size()), // uint32_t vertexAttributeDescriptionCount;
394 dataPointer(vertexDataDesc.vertexAttribDescVec), // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
397 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateInfo =
399 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
400 DE_NULL, // const void* pNext;
401 (VkPipelineInputAssemblyStateCreateFlags)0u, // VkPipelineInputAssemblyStateCreateFlags flags;
402 vertexDataDesc.primitiveTopology, // VkPrimitiveTopology topology;
403 VK_FALSE, // VkBool32 primitiveRestartEnable;
406 const VkViewport viewport =
409 static_cast<float>(imageMSInfo.extent.width), static_cast<float>(imageMSInfo.extent.height),
413 const VkRect2D scissor =
416 makeExtent2D(imageMSInfo.extent.width, imageMSInfo.extent.height),
419 const VkPipelineViewportStateCreateInfo viewportStateInfo =
421 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
422 DE_NULL, // const void* pNext;
423 (VkPipelineViewportStateCreateFlags)0u, // VkPipelineViewportStateCreateFlags flags;
424 1u, // uint32_t viewportCount;
425 &viewport, // const VkViewport* pViewports;
426 1u, // uint32_t scissorCount;
427 &scissor, // const VkRect2D* pScissors;
430 const VkPipelineRasterizationStateCreateInfo rasterizationStateInfo =
432 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
433 DE_NULL, // const void* pNext;
434 (VkPipelineRasterizationStateCreateFlags)0u, // VkPipelineRasterizationStateCreateFlags flags;
435 VK_FALSE, // VkBool32 depthClampEnable;
436 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
437 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
438 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
439 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
440 VK_FALSE, // VkBool32 depthBiasEnable;
441 0.0f, // float depthBiasConstantFactor;
442 0.0f, // float depthBiasClamp;
443 0.0f, // float depthBiasSlopeFactor;
444 1.0f, // float lineWidth;
447 const VkPipelineMultisampleStateCreateInfo multisampleStateInfo = getMSStateCreateInfo(m_imageMSParams);
449 const VkStencilOpState stencilOpState = makeStencilOpState
451 VK_STENCIL_OP_KEEP, // stencil fail
452 VK_STENCIL_OP_KEEP, // depth & stencil pass
453 VK_STENCIL_OP_KEEP, // depth only fail
454 VK_COMPARE_OP_ALWAYS, // compare op
460 const VkPipelineDepthStencilStateCreateInfo depthStencilStateInfo =
462 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
463 DE_NULL, // const void* pNext;
464 (VkPipelineDepthStencilStateCreateFlags)0u, // VkPipelineDepthStencilStateCreateFlags flags;
465 VK_FALSE, // VkBool32 depthTestEnable;
466 VK_FALSE, // VkBool32 depthWriteEnable;
467 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp;
468 VK_FALSE, // VkBool32 depthBoundsTestEnable;
469 VK_FALSE, // VkBool32 stencilTestEnable;
470 stencilOpState, // VkStencilOpState front;
471 stencilOpState, // VkStencilOpState back;
472 0.0f, // float minDepthBounds;
473 1.0f, // float maxDepthBounds;
476 const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
478 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
480 VK_FALSE, // VkBool32 blendEnable;
481 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor;
482 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor;
483 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
484 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor;
485 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor;
486 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
487 colorComponentsAll, // VkColorComponentFlags colorWriteMask;
490 const VkPipelineColorBlendStateCreateInfo colorBlendStateInfo =
492 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
493 DE_NULL, // const void* pNext;
494 (VkPipelineColorBlendStateCreateFlags)0u, // VkPipelineColorBlendStateCreateFlags flags;
495 VK_FALSE, // VkBool32 logicOpEnable;
496 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
497 1u, // deUint32 attachmentCount;
498 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
499 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4];
502 // Create graphics pipeline for multisample pass
503 const Unique<VkShaderModule> vsMSPassModule(createShaderModule(deviceInterface, device, m_context.getBinaryCollection().get("vertex_shader"), (VkShaderModuleCreateFlags)0u));
505 const VkPipelineShaderStageCreateInfo vsMSPassShaderStageInfo =
507 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
508 DE_NULL, // const void* pNext;
509 (VkPipelineShaderStageCreateFlags)0u, // VkPipelineShaderStageCreateFlags flags;
510 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage;
511 *vsMSPassModule, // VkShaderModule module;
512 "main", // const char* pName;
513 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
516 const Unique<VkShaderModule> fsMSPassModule(createShaderModule(deviceInterface, device, m_context.getBinaryCollection().get("fragment_shader"), (VkShaderModuleCreateFlags)0u));
518 const VkPipelineShaderStageCreateInfo fsMSPassShaderStageInfo =
520 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
521 DE_NULL, // const void* pNext;
522 (VkPipelineShaderStageCreateFlags)0u, // VkPipelineShaderStageCreateFlags flags;
523 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage;
524 *fsMSPassModule, // VkShaderModule module;
525 "main", // const char* pName;
526 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
529 const VkPipelineShaderStageCreateInfo shaderStageInfosMSPass[] = { vsMSPassShaderStageInfo, fsMSPassShaderStageInfo };
531 const VkGraphicsPipelineCreateInfo graphicsPipelineInfoMSPass =
533 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
534 DE_NULL, // const void* pNext;
535 (VkPipelineCreateFlags)0u, // VkPipelineCreateFlags flags;
536 2u, // deUint32 stageCount;
537 shaderStageInfosMSPass, // const VkPipelineShaderStageCreateInfo* pStages;
538 &vertexInputStateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
539 &inputAssemblyStateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
540 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
541 &viewportStateInfo, // const VkPipelineViewportStateCreateInfo* pViewportState;
542 &rasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
543 &multisampleStateInfo, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
544 &depthStencilStateInfo, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
545 &colorBlendStateInfo, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
546 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
547 *pipelineLayoutMSPass, // VkPipelineLayout layout;
548 *renderPass, // VkRenderPass renderPass;
549 0u, // deUint32 subpass;
550 DE_NULL, // VkPipeline basePipelineHandle;
551 0u, // deInt32 basePipelineIndex;
554 const Unique<VkPipeline> graphicsPipelineMSPass(createGraphicsPipeline(deviceInterface, device, DE_NULL, &graphicsPipelineInfoMSPass));
556 typedef de::SharedPtr<Unique<VkPipeline> > VkPipelineSp;
557 std::vector<VkPipelineSp> graphicsPipelinesPerSampleFetch(numSamples);
559 // Create descriptor set layout
560 const Unique<VkDescriptorSetLayout> descriptorSetLayout(
561 DescriptorSetLayoutBuilder()
562 .addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT)
563 .addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, VK_SHADER_STAGE_FRAGMENT_BIT)
564 .build(deviceInterface, device));
566 const Unique<VkPipelineLayout> pipelineLayoutPerSampleFetchPass(makePipelineLayout(deviceInterface, device, *descriptorSetLayout));
568 const deUint32 bufferPerSampleFetchPassSize = 4u * (deUint32)sizeof(tcu::Vec4);
570 de::SharedPtr<Buffer> vertexBufferPerSampleFetchPass = de::SharedPtr<Buffer>(new Buffer(deviceInterface, device, allocator, makeBufferCreateInfo(bufferPerSampleFetchPassSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible));
572 // Create graphics pipelines for per sample texel fetch passes
574 const Unique<VkShaderModule> vsPerSampleFetchPassModule(createShaderModule(deviceInterface, device, m_context.getBinaryCollection().get("per_sample_fetch_vs"), (VkShaderModuleCreateFlags)0u));
576 const VkPipelineShaderStageCreateInfo vsPerSampleFetchPassShaderStageInfo =
578 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
579 DE_NULL, // const void* pNext;
580 (VkPipelineShaderStageCreateFlags)0u, // VkPipelineShaderStageCreateFlags flags;
581 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage;
582 *vsPerSampleFetchPassModule, // VkShaderModule module;
583 "main", // const char* pName;
584 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
587 const Unique<VkShaderModule> fsPerSampleFetchPassModule(createShaderModule(deviceInterface, device, m_context.getBinaryCollection().get("per_sample_fetch_fs"), (VkShaderModuleCreateFlags)0u));
589 const VkPipelineShaderStageCreateInfo fsPerSampleFetchPassShaderStageInfo =
591 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
592 DE_NULL, // const void* pNext;
593 (VkPipelineShaderStageCreateFlags)0u, // VkPipelineShaderStageCreateFlags flags;
594 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage;
595 *fsPerSampleFetchPassModule, // VkShaderModule module;
596 "main", // const char* pName;
597 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
600 const VkPipelineShaderStageCreateInfo shaderStageInfosPerSampleFetchPass[] = { vsPerSampleFetchPassShaderStageInfo, fsPerSampleFetchPassShaderStageInfo };
602 std::vector<tcu::Vec4> vertices;
604 vertices.push_back(tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f));
605 vertices.push_back(tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f));
606 vertices.push_back(tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f));
607 vertices.push_back(tcu::Vec4( 1.0f, 1.0f, 0.0f, 1.0f));
609 const Allocation& vertexAllocPerSampleFetchPass = vertexBufferPerSampleFetchPass->getAllocation();
611 deMemcpy(vertexAllocPerSampleFetchPass.getHostPtr(), dataPointer(vertices), static_cast<std::size_t>(bufferPerSampleFetchPassSize));
613 flushMappedMemoryRange(deviceInterface, device, vertexAllocPerSampleFetchPass.getMemory(), vertexAllocPerSampleFetchPass.getOffset(), VK_WHOLE_SIZE);
615 const VkVertexInputBindingDescription vertexBindingPerSampleFetchPass =
617 0u, // deUint32 binding;
618 sizeof(tcu::Vec4), // deUint32 stride;
619 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate inputRate;
622 const VkVertexInputAttributeDescription vertexAttribPositionNdc =
624 0u, // deUint32 location;
625 0u, // deUint32 binding;
626 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
627 0u, // deUint32 offset;
630 const VkPipelineVertexInputStateCreateInfo vertexInputStatePerSampleFetchPass =
632 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
633 DE_NULL, // const void* pNext;
634 (VkPipelineVertexInputStateCreateFlags)0u, // VkPipelineVertexInputStateCreateFlags flags;
635 1u, // uint32_t vertexBindingDescriptionCount;
636 &vertexBindingPerSampleFetchPass, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
637 1u, // uint32_t vertexAttributeDescriptionCount;
638 &vertexAttribPositionNdc, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
641 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStatePerSampleFetchPass =
643 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
644 DE_NULL, // const void* pNext;
645 (VkPipelineInputAssemblyStateCreateFlags)0u, // VkPipelineInputAssemblyStateCreateFlags flags;
646 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // VkPrimitiveTopology topology;
647 VK_FALSE, // VkBool32 primitiveRestartEnable;
650 const VkPipelineMultisampleStateCreateInfo multisampleStatePerSampleFetchPass =
652 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
653 DE_NULL, // const void* pNext;
654 (VkPipelineMultisampleStateCreateFlags)0u, // VkPipelineMultisampleStateCreateFlags flags;
655 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
656 VK_FALSE, // VkBool32 sampleShadingEnable;
657 0.0f, // float minSampleShading;
658 DE_NULL, // const VkSampleMask* pSampleMask;
659 VK_FALSE, // VkBool32 alphaToCoverageEnable;
660 VK_FALSE, // VkBool32 alphaToOneEnable;
663 for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
665 const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
667 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
668 DE_NULL, // const void* pNext;
669 (VkPipelineCreateFlags)0u, // VkPipelineCreateFlags flags;
670 2u, // deUint32 stageCount;
671 shaderStageInfosPerSampleFetchPass, // const VkPipelineShaderStageCreateInfo* pStages;
672 &vertexInputStatePerSampleFetchPass, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
673 &inputAssemblyStatePerSampleFetchPass, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
674 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
675 &viewportStateInfo, // const VkPipelineViewportStateCreateInfo* pViewportState;
676 &rasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
677 &multisampleStatePerSampleFetchPass, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
678 &depthStencilStateInfo, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
679 &colorBlendStateInfo, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
680 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
681 *pipelineLayoutPerSampleFetchPass, // VkPipelineLayout layout;
682 *renderPass, // VkRenderPass renderPass;
683 1u + sampleNdx, // deUint32 subpass;
684 DE_NULL, // VkPipeline basePipelineHandle;
685 0u, // deInt32 basePipelineIndex;
688 graphicsPipelinesPerSampleFetch[sampleNdx] = makeVkSharedPtr(createGraphicsPipeline(deviceInterface, device, DE_NULL, &graphicsPipelineInfo));
692 // Create descriptor pool
693 const Unique<VkDescriptorPool> descriptorPool(
694 DescriptorPoolBuilder()
695 .addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1u)
696 .addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1u)
697 .build(deviceInterface, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
699 // Create descriptor set
700 const Unique<VkDescriptorSet> descriptorSet(makeDescriptorSet(deviceInterface, device, *descriptorPool, *descriptorSetLayout));
702 const VkPhysicalDeviceLimits deviceLimits = getPhysicalDeviceProperties(instance, physicalDevice).limits;
704 VkDeviceSize uboOffsetAlignment = sizeof(deInt32) < deviceLimits.minUniformBufferOffsetAlignment ? deviceLimits.minUniformBufferOffsetAlignment : sizeof(deInt32);
706 uboOffsetAlignment += (deviceLimits.minUniformBufferOffsetAlignment - uboOffsetAlignment % deviceLimits.minUniformBufferOffsetAlignment) % deviceLimits.minUniformBufferOffsetAlignment;
708 const VkBufferCreateInfo bufferSampleIDInfo = makeBufferCreateInfo(uboOffsetAlignment * numSamples, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
709 const de::UniquePtr<Buffer> bufferSampleID(new Buffer(deviceInterface, device, allocator, bufferSampleIDInfo, MemoryRequirement::HostVisible));
711 std::vector<deUint32> sampleIDsOffsets(numSamples);
714 deInt8* sampleIDs = new deInt8[uboOffsetAlignment * numSamples];
716 for (deInt32 sampleNdx = 0u; sampleNdx < static_cast<deInt32>(numSamples); ++sampleNdx)
718 sampleIDsOffsets[sampleNdx] = static_cast<deUint32>(sampleNdx * uboOffsetAlignment);
719 deInt8* samplePtr = sampleIDs + sampleIDsOffsets[sampleNdx];
721 deMemcpy(samplePtr, &sampleNdx, sizeof(deInt32));
724 deMemcpy(bufferSampleID->getAllocation().getHostPtr(), sampleIDs, static_cast<deUint32>(uboOffsetAlignment * numSamples));
726 flushMappedMemoryRange(deviceInterface, device, bufferSampleID->getAllocation().getMemory(), bufferSampleID->getAllocation().getOffset(), VK_WHOLE_SIZE);
732 const VkDescriptorImageInfo descImageInfo = makeDescriptorImageInfo(DE_NULL, imageViews[0], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
733 const VkDescriptorBufferInfo descBufferInfo = makeDescriptorBufferInfo(**bufferSampleID, 0u, sizeof(deInt32));
735 DescriptorSetUpdateBuilder()
736 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &descImageInfo)
737 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, &descBufferInfo)
738 .update(deviceInterface, device);
741 // Create command buffer for compute and transfer oparations
742 const Unique<VkCommandPool> commandPool(createCommandPool(deviceInterface, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
743 const Unique<VkCommandBuffer> commandBuffer(makeCommandBuffer(deviceInterface, device, *commandPool));
745 // Start recording commands
746 beginCommandBuffer(deviceInterface, *commandBuffer);
749 std::vector<VkImageMemoryBarrier> imageOutputAttachmentBarriers(firstSubpassAttachmentsCount + numSamples);
751 imageOutputAttachmentBarriers[0] = makeImageMemoryBarrier
754 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
755 VK_IMAGE_LAYOUT_UNDEFINED,
756 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
761 imageOutputAttachmentBarriers[1] = makeImageMemoryBarrier
764 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
765 VK_IMAGE_LAYOUT_UNDEFINED,
766 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
771 for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
773 imageOutputAttachmentBarriers[firstSubpassAttachmentsCount + sampleNdx] = makeImageMemoryBarrier
776 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
777 VK_IMAGE_LAYOUT_UNDEFINED,
778 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
779 **imagesPerSampleVec[sampleNdx],
784 deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL,
785 static_cast<deUint32>(imageOutputAttachmentBarriers.size()), dataPointer(imageOutputAttachmentBarriers));
789 const VkDeviceSize vertexStartOffset = 0u;
791 std::vector<VkClearValue> clearValues(firstSubpassAttachmentsCount + numSamples);
792 for (deUint32 attachmentNdx = 0u; attachmentNdx < firstSubpassAttachmentsCount + numSamples; ++attachmentNdx)
794 clearValues[attachmentNdx] = makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
797 const vk::VkRect2D renderArea =
799 makeOffset2D(0u, 0u),
800 makeExtent2D(imageMSInfo.extent.width, imageMSInfo.extent.height),
804 const VkRenderPassBeginInfo renderPassBeginInfo =
806 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
807 DE_NULL, // const void* pNext;
808 *renderPass, // VkRenderPass renderPass;
809 *framebuffer, // VkFramebuffer framebuffer;
810 renderArea, // VkRect2D renderArea;
811 static_cast<deUint32>(clearValues.size()), // deUint32 clearValueCount;
812 dataPointer(clearValues), // const VkClearValue* pClearValues;
815 deviceInterface.cmdBeginRenderPass(*commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
817 // Bind graphics pipeline
818 deviceInterface.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipelineMSPass);
820 const VkDescriptorSet* descriptorSetMSPass = createMSPassDescSet(m_imageMSParams, descriptorSetLayoutMSPass);
822 if (descriptorSetMSPass)
824 // Bind descriptor set
825 deviceInterface.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayoutMSPass, 0u, 1u, descriptorSetMSPass, 0u, DE_NULL);
828 // Bind vertex buffer
829 deviceInterface.cmdBindVertexBuffers(*commandBuffer, 0u, 1u, &vertexBuffer->get(), &vertexStartOffset);
832 deviceInterface.cmdDraw(*commandBuffer, vertexDataDesc.verticesCount, 1u, 0u, 0u);
834 for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
836 deviceInterface.cmdNextSubpass(*commandBuffer, VK_SUBPASS_CONTENTS_INLINE);
838 // Bind graphics pipeline
839 deviceInterface.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **graphicsPipelinesPerSampleFetch[sampleNdx]);
841 // Bind descriptor set
842 deviceInterface.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayoutPerSampleFetchPass, 0u, 1u, &descriptorSet.get(), 1u, &sampleIDsOffsets[sampleNdx]);
844 // Bind vertex buffer
845 deviceInterface.cmdBindVertexBuffers(*commandBuffer, 0u, 1u, &vertexBufferPerSampleFetchPass->get(), &vertexStartOffset);
848 deviceInterface.cmdDraw(*commandBuffer, 4u, 1u, 0u, 0u);
852 deviceInterface.cmdEndRenderPass(*commandBuffer);
856 const VkImageMemoryBarrier imageRSTransferBarrier = makeImageMemoryBarrier
858 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
859 VK_ACCESS_TRANSFER_READ_BIT,
860 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
861 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
866 deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageRSTransferBarrier);
869 // Copy data from imageRS to buffer
870 const deUint32 imageRSSizeInBytes = getImageSizeInBytes(imageRSInfo.extent, imageRSInfo.arrayLayers, m_imageFormat, imageRSInfo.mipLevels, 1u);
872 const VkBufferCreateInfo bufferRSInfo = makeBufferCreateInfo(imageRSSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
873 const de::UniquePtr<Buffer> bufferRS(new Buffer(deviceInterface, device, allocator, bufferRSInfo, MemoryRequirement::HostVisible));
876 const VkBufferImageCopy bufferImageCopy =
878 0u, // VkDeviceSize bufferOffset;
879 0u, // deUint32 bufferRowLength;
880 0u, // deUint32 bufferImageHeight;
881 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, imageRSInfo.arrayLayers), // VkImageSubresourceLayers imageSubresource;
882 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
883 imageRSInfo.extent, // VkExtent3D imageExtent;
886 deviceInterface.cmdCopyImageToBuffer(*commandBuffer, **imageRS, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, bufferRS->get(), 1u, &bufferImageCopy);
890 const VkBufferMemoryBarrier bufferRSHostReadBarrier = makeBufferMemoryBarrier
892 VK_ACCESS_TRANSFER_WRITE_BIT,
893 VK_ACCESS_HOST_READ_BIT,
899 deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &bufferRSHostReadBarrier, 0u, DE_NULL);
902 // Copy data from per sample images to buffers
903 std::vector<VkImageMemoryBarrier> imagesPerSampleTransferBarriers(numSamples);
905 for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
907 imagesPerSampleTransferBarriers[sampleNdx] = makeImageMemoryBarrier
909 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
910 VK_ACCESS_TRANSFER_READ_BIT,
911 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
912 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
913 **imagesPerSampleVec[sampleNdx],
918 deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL,
919 static_cast<deUint32>(imagesPerSampleTransferBarriers.size()), dataPointer(imagesPerSampleTransferBarriers));
921 std::vector<de::SharedPtr<Buffer> > buffersPerSample(numSamples);
923 for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
925 buffersPerSample[sampleNdx] = de::SharedPtr<Buffer>(new Buffer(deviceInterface, device, allocator, bufferRSInfo, MemoryRequirement::HostVisible));
927 const VkBufferImageCopy bufferImageCopy =
929 0u, // VkDeviceSize bufferOffset;
930 0u, // deUint32 bufferRowLength;
931 0u, // deUint32 bufferImageHeight;
932 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, imageRSInfo.arrayLayers), // VkImageSubresourceLayers imageSubresource;
933 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
934 imageRSInfo.extent, // VkExtent3D imageExtent;
937 deviceInterface.cmdCopyImageToBuffer(*commandBuffer, **imagesPerSampleVec[sampleNdx], VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **buffersPerSample[sampleNdx], 1u, &bufferImageCopy);
940 std::vector<VkBufferMemoryBarrier> buffersPerSampleHostReadBarriers(numSamples);
942 for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
944 buffersPerSampleHostReadBarriers[sampleNdx] = makeBufferMemoryBarrier
946 VK_ACCESS_TRANSFER_WRITE_BIT,
947 VK_ACCESS_HOST_READ_BIT,
948 **buffersPerSample[sampleNdx],
954 deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL,
955 static_cast<deUint32>(buffersPerSampleHostReadBarriers.size()), dataPointer(buffersPerSampleHostReadBarriers), 0u, DE_NULL);
957 // End recording commands
958 VK_CHECK(deviceInterface.endCommandBuffer(*commandBuffer));
960 // Submit commands for execution and wait for completion
961 submitCommandsAndWait(deviceInterface, device, queue, *commandBuffer);
963 // Retrieve data from bufferRS to host memory
964 const Allocation& bufferRSAlloc = bufferRS->getAllocation();
966 invalidateMappedMemoryRange(deviceInterface, device, bufferRSAlloc.getMemory(), bufferRSAlloc.getOffset(), VK_WHOLE_SIZE);
968 const tcu::ConstPixelBufferAccess bufferRSData (m_imageFormat,
969 imageRSInfo.extent.width,
970 imageRSInfo.extent.height,
971 imageRSInfo.extent.depth * imageRSInfo.arrayLayers,
972 bufferRSAlloc.getHostPtr());
974 std::stringstream resolveName;
975 resolveName << "Resolve image " << getImageTypeName(m_imageType) << "_" << bufferRSData.getWidth() << "_" << bufferRSData.getHeight() << "_" << bufferRSData.getDepth() << std::endl;
977 m_context.getTestContext().getLog()
978 << tcu::TestLog::Section(resolveName.str(), resolveName.str())
979 << tcu::LogImage("resolve", "", bufferRSData)
980 << tcu::TestLog::EndSection;
982 std::vector<tcu::ConstPixelBufferAccess> buffersPerSampleData(numSamples);
984 // Retrieve data from per sample buffers to host memory
985 for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
987 const Allocation& bufferAlloc = buffersPerSample[sampleNdx]->getAllocation();
989 invalidateMappedMemoryRange(deviceInterface, device, bufferAlloc.getMemory(), bufferAlloc.getOffset(), VK_WHOLE_SIZE);
991 buffersPerSampleData[sampleNdx] = tcu::ConstPixelBufferAccess
994 imageRSInfo.extent.width,
995 imageRSInfo.extent.height,
996 imageRSInfo.extent.depth * imageRSInfo.arrayLayers,
997 bufferAlloc.getHostPtr()
1000 std::stringstream sampleName;
1001 sampleName << "Sample " << sampleNdx << " image" << std::endl;
1003 m_context.getTestContext().getLog()
1004 << tcu::TestLog::Section(sampleName.str(), sampleName.str())
1005 << tcu::LogImage("sample", "", buffersPerSampleData[sampleNdx])
1006 << tcu::TestLog::EndSection;
1009 return verifyImageData(imageMSInfo, imageRSInfo, buffersPerSampleData, bufferRSData);