1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2016 The Khronos Group Inc.
6 * Copyright (c) 2014 The Android Open Source Project
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
22 * \brief Geometry shader instanced rendering tests
23 *//*--------------------------------------------------------------------*/
25 #include "vktGeometryInstancedRenderingTests.hpp"
26 #include "vktTestCase.hpp"
27 #include "vktTestCaseUtil.hpp"
28 #include "vktGeometryTestsUtil.hpp"
30 #include "vkPrograms.hpp"
31 #include "vkQueryUtil.hpp"
32 #include "vkMemUtil.hpp"
33 #include "vkRefUtil.hpp"
34 #include "vkTypeUtil.hpp"
35 #include "vkImageUtil.hpp"
37 #include "tcuTextureUtil.hpp"
38 #include "tcuImageCompare.hpp"
39 #include "tcuTestLog.hpp"
41 #include "deRandom.hpp"
62 VkImageCreateInfo makeImageCreateInfo (const VkFormat format, const VkExtent3D size, const VkImageUsageFlags usage)
64 const VkImageCreateInfo imageParams =
66 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
67 DE_NULL, // const void* pNext;
68 (VkImageCreateFlags)0, // VkImageCreateFlags flags;
69 VK_IMAGE_TYPE_2D, // VkImageType imageType;
70 format, // VkFormat format;
71 size, // VkExtent3D extent;
72 1u, // deUint32 mipLevels;
73 1u, // deUint32 arrayLayers;
74 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
75 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
76 usage, // VkImageUsageFlags usage;
77 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
78 0u, // deUint32 queueFamilyIndexCount;
79 DE_NULL, // const deUint32* pQueueFamilyIndices;
80 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
85 Move<VkRenderPass> makeRenderPass (const DeviceInterface& vk,
86 const VkDevice device,
87 const VkFormat colorFormat)
89 const VkAttachmentDescription colorAttachmentDescription =
91 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
92 colorFormat, // VkFormat format;
93 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
94 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
95 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
96 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
97 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
98 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
99 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
102 const VkAttachmentReference colorAttachmentRef =
104 0u, // deUint32 attachment;
105 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
108 const VkSubpassDescription subpassDescription =
110 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags;
111 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
112 0u, // deUint32 inputAttachmentCount;
113 DE_NULL, // const VkAttachmentReference* pInputAttachments;
114 1u, // deUint32 colorAttachmentCount;
115 &colorAttachmentRef, // const VkAttachmentReference* pColorAttachments;
116 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
117 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
118 0u, // deUint32 preserveAttachmentCount;
119 DE_NULL // const deUint32* pPreserveAttachments;
122 const VkRenderPassCreateInfo renderPassInfo =
124 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
125 DE_NULL, // const void* pNext;
126 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags;
127 1u, // deUint32 attachmentCount;
128 &colorAttachmentDescription, // const VkAttachmentDescription* pAttachments;
129 1u, // deUint32 subpassCount;
130 &subpassDescription, // const VkSubpassDescription* pSubpasses;
131 0u, // deUint32 dependencyCount;
132 DE_NULL // const VkSubpassDependency* pDependencies;
135 return createRenderPass(vk, device, &renderPassInfo);
138 Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface& vk,
139 const VkDevice device,
140 const VkPipelineLayout pipelineLayout,
141 const VkRenderPass renderPass,
142 const VkShaderModule vertexModule,
143 const VkShaderModule geometryModule,
144 const VkShaderModule fragmentModule,
145 const VkExtent2D renderSize)
147 const VkVertexInputBindingDescription vertexInputBindingDescription =
149 0u, // uint32_t binding;
150 sizeof(Vec4), // uint32_t stride;
151 VK_VERTEX_INPUT_RATE_INSTANCE, // VkVertexInputRate inputRate;
154 const VkVertexInputAttributeDescription vertexInputAttributeDescription =
156 0u, // uint32_t location;
157 0u, // uint32_t binding;
158 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
159 0u, // uint32_t offset;
162 const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
164 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
165 DE_NULL, // const void* pNext;
166 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
167 1u, // uint32_t vertexBindingDescriptionCount;
168 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
169 1u, // uint32_t vertexAttributeDescriptionCount;
170 &vertexInputAttributeDescription, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
173 const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
175 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
176 DE_NULL, // const void* pNext;
177 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags;
178 VK_PRIMITIVE_TOPOLOGY_POINT_LIST, // VkPrimitiveTopology topology;
179 VK_FALSE, // VkBool32 primitiveRestartEnable;
182 const VkViewport viewport = makeViewport(
184 static_cast<float>(renderSize.width), static_cast<float>(renderSize.height),
186 const VkRect2D scissor =
189 makeExtent2D(renderSize.width, renderSize.height),
192 const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
194 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
195 DE_NULL, // const void* pNext;
196 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags;
197 1u, // uint32_t viewportCount;
198 &viewport, // const VkViewport* pViewports;
199 1u, // uint32_t scissorCount;
200 &scissor, // const VkRect2D* pScissors;
203 const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
205 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
206 DE_NULL, // const void* pNext;
207 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags;
208 VK_FALSE, // VkBool32 depthClampEnable;
209 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
210 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
211 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
212 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
213 VK_FALSE, // VkBool32 depthBiasEnable;
214 0.0f, // float depthBiasConstantFactor;
215 0.0f, // float depthBiasClamp;
216 0.0f, // float depthBiasSlopeFactor;
217 1.0f, // float lineWidth;
220 const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
222 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
223 DE_NULL, // const void* pNext;
224 (VkPipelineMultisampleStateCreateFlags)0, // VkPipelineMultisampleStateCreateFlags flags;
225 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
226 VK_FALSE, // VkBool32 sampleShadingEnable;
227 0.0f, // float minSampleShading;
228 DE_NULL, // const VkSampleMask* pSampleMask;
229 VK_FALSE, // VkBool32 alphaToCoverageEnable;
230 VK_FALSE // VkBool32 alphaToOneEnable;
233 const VkStencilOpState stencilOpState = makeStencilOpState(
234 VK_STENCIL_OP_KEEP, // stencil fail
235 VK_STENCIL_OP_KEEP, // depth & stencil pass
236 VK_STENCIL_OP_KEEP, // depth only fail
237 VK_COMPARE_OP_ALWAYS, // compare op
242 VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
244 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
245 DE_NULL, // const void* pNext;
246 (VkPipelineDepthStencilStateCreateFlags)0, // VkPipelineDepthStencilStateCreateFlags flags;
247 VK_FALSE, // VkBool32 depthTestEnable;
248 VK_FALSE, // VkBool32 depthWriteEnable;
249 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp;
250 VK_FALSE, // VkBool32 depthBoundsTestEnable;
251 VK_FALSE, // VkBool32 stencilTestEnable;
252 stencilOpState, // VkStencilOpState front;
253 stencilOpState, // VkStencilOpState back;
254 0.0f, // float minDepthBounds;
255 1.0f, // float maxDepthBounds;
258 const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
259 const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
261 VK_FALSE, // VkBool32 blendEnable;
262 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor;
263 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor;
264 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
265 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor;
266 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor;
267 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
268 colorComponentsAll, // VkColorComponentFlags colorWriteMask;
271 const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
273 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
274 DE_NULL, // const void* pNext;
275 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags;
276 VK_FALSE, // VkBool32 logicOpEnable;
277 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
278 1u, // deUint32 attachmentCount;
279 &pipelineColorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
280 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4];
283 const VkPipelineShaderStageCreateInfo pShaderStages[] =
286 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
287 DE_NULL, // const void* pNext;
288 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
289 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage;
290 vertexModule, // VkShaderModule module;
291 "main", // const char* pName;
292 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
295 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
296 DE_NULL, // const void* pNext;
297 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
298 VK_SHADER_STAGE_GEOMETRY_BIT, // VkShaderStageFlagBits stage;
299 geometryModule, // VkShaderModule module;
300 "main", // const char* pName;
301 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
304 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
305 DE_NULL, // const void* pNext;
306 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
307 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage;
308 fragmentModule, // VkShaderModule module;
309 "main", // const char* pName;
310 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
314 const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
316 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
317 DE_NULL, // const void* pNext;
318 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
319 DE_LENGTH_OF_ARRAY(pShaderStages), // deUint32 stageCount;
320 pShaderStages, // const VkPipelineShaderStageCreateInfo* pStages;
321 &vertexInputStateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
322 &pipelineInputAssemblyStateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
323 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
324 &pipelineViewportStateInfo, // const VkPipelineViewportStateCreateInfo* pViewportState;
325 &pipelineRasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
326 &pipelineMultisampleStateInfo, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
327 &pipelineDepthStencilStateInfo, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
328 &pipelineColorBlendStateInfo, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
329 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
330 pipelineLayout, // VkPipelineLayout layout;
331 renderPass, // VkRenderPass renderPass;
332 0u, // deUint32 subpass;
333 DE_NULL, // VkPipeline basePipelineHandle;
334 0, // deInt32 basePipelineIndex;
337 return createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
340 void draw (Context& context,
341 const UVec2& renderSize,
342 const VkFormat colorFormat,
343 const Vec4& clearColor,
344 const VkBuffer colorBuffer,
345 const int numDrawInstances,
346 const std::vector<Vec4>& perInstanceAttribute)
348 const DeviceInterface& vk = context.getDeviceInterface();
349 const VkDevice device = context.getDevice();
350 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
351 const VkQueue queue = context.getUniversalQueue();
352 Allocator& allocator = context.getDefaultAllocator();
354 const VkImageSubresourceRange colorSubresourceRange (makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u));
355 const VkExtent3D colorImageExtent (makeExtent3D(renderSize.x(), renderSize.y(), 1u));
356 const VkExtent2D renderExtent (makeExtent2D(renderSize.x(), renderSize.y()));
358 const Unique<VkImage> colorImage (makeImage (vk, device, makeImageCreateInfo(colorFormat, colorImageExtent, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT)));
359 const UniquePtr<Allocation> colorImageAlloc (bindImage (vk, device, allocator, *colorImage, MemoryRequirement::Any));
360 const Unique<VkImageView> colorAttachment (makeImageView (vk, device, *colorImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresourceRange));
362 const VkDeviceSize vertexBufferSize = sizeInBytes(perInstanceAttribute);
363 const Unique<VkBuffer> vertexBuffer (makeBuffer(vk, device, makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)));
364 const UniquePtr<Allocation> vertexBufferAlloc (bindBuffer(vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible));
366 const Unique<VkShaderModule> vertexModule (createShaderModule (vk, device, context.getBinaryCollection().get("vert"), 0u));
367 const Unique<VkShaderModule> geometryModule (createShaderModule (vk, device, context.getBinaryCollection().get("geom"), 0u));
368 const Unique<VkShaderModule> fragmentModule (createShaderModule (vk, device, context.getBinaryCollection().get("frag"), 0u));
370 const Unique<VkRenderPass> renderPass (makeRenderPass (vk, device, colorFormat));
371 const Unique<VkFramebuffer> framebuffer (makeFramebuffer (vk, device, *renderPass, *colorAttachment, renderSize.x(), renderSize.y(), 1u));
372 const Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout (vk, device));
373 const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertexModule, *geometryModule, *fragmentModule, renderExtent));
375 const Unique<VkCommandPool> cmdPool (createCommandPool (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
376 const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
378 // Initialize vertex data
380 deMemcpy(vertexBufferAlloc->getHostPtr(), &perInstanceAttribute[0], (size_t)vertexBufferSize);
381 flushMappedMemoryRange(vk, device, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset(), vertexBufferSize);
384 beginCommandBuffer(vk, *cmdBuffer);
386 const VkClearValue clearValue = makeClearValueColor(clearColor);
387 const VkRect2D renderArea =
392 const VkRenderPassBeginInfo renderPassBeginInfo =
394 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
395 DE_NULL, // const void* pNext;
396 *renderPass, // VkRenderPass renderPass;
397 *framebuffer, // VkFramebuffer framebuffer;
398 renderArea, // VkRect2D renderArea;
399 1u, // uint32_t clearValueCount;
400 &clearValue, // const VkClearValue* pClearValues;
402 vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
404 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
406 const VkDeviceSize offset = 0ull;
407 vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &vertexBuffer.get(), &offset);
409 vk.cmdDraw(*cmdBuffer, 1u, static_cast<deUint32>(numDrawInstances), 0u, 0u);
410 vk.cmdEndRenderPass(*cmdBuffer);
412 // Prepare color image for copy
414 const VkImageMemoryBarrier barriers[] =
417 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
418 DE_NULL, // const void* pNext;
419 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags outputMask;
420 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags inputMask;
421 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout;
422 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout;
423 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
424 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
425 *colorImage, // VkImage image;
426 colorSubresourceRange, // VkImageSubresourceRange subresourceRange;
430 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
431 0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(barriers), barriers);
433 // Color image -> host buffer
435 const VkBufferImageCopy region =
437 0ull, // VkDeviceSize bufferOffset;
438 0u, // uint32_t bufferRowLength;
439 0u, // uint32_t bufferImageHeight;
440 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u), // VkImageSubresourceLayers imageSubresource;
441 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
442 colorImageExtent, // VkExtent3D imageExtent;
445 vk.cmdCopyImageToBuffer(*cmdBuffer, *colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, colorBuffer, 1u, ®ion);
447 // Buffer write barrier
449 const VkBufferMemoryBarrier barriers[] =
452 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
453 DE_NULL, // const void* pNext;
454 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
455 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
456 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
457 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
458 colorBuffer, // VkBuffer buffer;
459 0ull, // VkDeviceSize offset;
460 VK_WHOLE_SIZE, // VkDeviceSize size;
464 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u,
465 0u, DE_NULL, DE_LENGTH_OF_ARRAY(barriers), barriers, DE_NULL, 0u);
468 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
469 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
472 std::vector<Vec4> generatePerInstancePosition (const int numInstances)
474 de::Random rng(1234);
475 std::vector<Vec4> positions;
477 for (int i = 0; i < numInstances; ++i)
479 const float flipX = rng.getBool() ? 1.0f : -1.0f;
480 const float flipY = rng.getBool() ? 1.0f : -1.0f;
481 const float x = flipX * rng.getFloat(0.1f, 0.9f); // x mustn't be 0.0, because we are using sign() in the shader
482 const float y = flipY * rng.getFloat(0.0f, 0.7f);
484 positions.push_back(Vec4(x, y, 0.0f, 1.0f));
490 //! Get a rectangle region of an image, using NDC coordinates (i.e. [-1, 1] range).
491 //! Result rect is cropped in either dimension to be inside the bounds of the image.
492 tcu::PixelBufferAccess getSubregion (tcu::PixelBufferAccess image, const float x, const float y, const float size)
494 const float w = static_cast<float>(image.getWidth());
495 const float h = static_cast<float>(image.getHeight());
496 const float x1 = w * (x + 1.0f) * 0.5f;
497 const float y1 = h * (y + 1.0f) * 0.5f;
498 const float sx = w * size * 0.5f;
499 const float sy = h * size * 0.5f;
500 const float x2 = x1 + sx;
501 const float y2 = y1 + sy;
503 // Round and clamp only after all of the above.
504 const int ix1 = std::max(deRoundFloatToInt32(x1), 0);
505 const int ix2 = std::min(deRoundFloatToInt32(x2), image.getWidth());
506 const int iy1 = std::max(deRoundFloatToInt32(y1), 0);
507 const int iy2 = std::min(deRoundFloatToInt32(y2), image.getHeight());
509 return tcu::getSubregion(image, ix1, iy1, ix2 - ix1, iy2 - iy1);
512 //! Must be in sync with the geometry shader code.
513 void generateReferenceImage(tcu::PixelBufferAccess image, const Vec4& clearColor, const std::vector<Vec4>& perInstancePosition, const int numInvocations)
515 tcu::clear(image, clearColor);
517 for (std::vector<Vec4>::const_iterator iterPosition = perInstancePosition.begin(); iterPosition != perInstancePosition.end(); ++iterPosition)
518 for (int invocationNdx = 0; invocationNdx < numInvocations; ++invocationNdx)
520 const float x = iterPosition->x();
521 const float y = iterPosition->y();
522 const float modifier = (numInvocations > 1 ? static_cast<float>(invocationNdx) / static_cast<float>(numInvocations - 1) : 0.0f);
523 const Vec4 color (deFloatAbs(x), deFloatAbs(y), 0.2f + 0.8f * modifier, 1.0f);
524 const float size = 0.05f + 0.03f * modifier;
525 const float dx = (deFloatSign(-x) - x) / static_cast<float>(numInvocations);
526 const float xOffset = static_cast<float>(invocationNdx) * dx;
527 const float yOffset = 0.3f * deFloatSin(12.0f * modifier);
529 tcu::PixelBufferAccess rect = getSubregion(image, x + xOffset - size, y + yOffset - size, size + size);
530 tcu::clear(rect, color);
534 void initPrograms (SourceCollections& programCollection, const TestParams params)
538 std::ostringstream src;
539 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
541 << "layout(location = 0) in vec4 in_position;\n"
543 << "out gl_PerVertex {\n"
544 << " vec4 gl_Position;\n"
547 << "void main(void)\n"
549 << " gl_Position = in_position;\n"
552 programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
557 // The shader must be in sync with reference image rendering routine.
559 std::ostringstream src;
560 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
562 << "layout(points, invocations = " << params.numInvocations << ") in;\n"
563 << "layout(triangle_strip, max_vertices = 4) out;\n"
565 << "layout(location = 0) out vec4 out_color;\n"
567 << "in gl_PerVertex {\n"
568 << " vec4 gl_Position;\n"
571 << "out gl_PerVertex {\n"
572 << " vec4 gl_Position;\n"
575 << "void main(void)\n"
577 << " const vec4 pos = gl_in[0].gl_Position;\n"
578 << " const float modifier = " << (params.numInvocations > 1 ? "float(gl_InvocationID) / float(" + de::toString(params.numInvocations - 1) + ")" : "0.0") << ";\n"
579 << " const vec4 color = vec4(abs(pos.x), abs(pos.y), 0.2 + 0.8 * modifier, 1.0);\n"
580 << " const float size = 0.05 + 0.03 * modifier;\n"
581 << " const float dx = (sign(-pos.x) - pos.x) / float(" << params.numInvocations << ");\n"
582 << " const vec4 offsetPos = pos + vec4(float(gl_InvocationID) * dx,\n"
583 << " 0.3 * sin(12.0 * modifier),\n"
587 << " gl_Position = offsetPos + vec4(-size, -size, 0.0, 0.0);\n"
588 << " out_color = color;\n"
589 << " EmitVertex();\n"
591 << " gl_Position = offsetPos + vec4(-size, size, 0.0, 0.0);\n"
592 << " out_color = color;\n"
593 << " EmitVertex();\n"
595 << " gl_Position = offsetPos + vec4( size, -size, 0.0, 0.0);\n"
596 << " out_color = color;\n"
597 << " EmitVertex();\n"
599 << " gl_Position = offsetPos + vec4( size, size, 0.0, 0.0);\n"
600 << " out_color = color;\n"
601 << " EmitVertex();\n"
604 programCollection.glslSources.add("geom") << glu::GeometrySource(src.str());
609 std::ostringstream src;
610 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
612 << "layout(location = 0) in vec4 in_color;\n"
613 << "layout(location = 0) out vec4 o_color;\n"
615 << "void main(void)\n"
617 << " o_color = in_color;\n"
620 programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
624 tcu::TestStatus test (Context& context, const TestParams params)
626 const DeviceInterface& vk = context.getDeviceInterface();
627 const InstanceInterface& vki = context.getInstanceInterface();
628 const VkDevice device = context.getDevice();
629 const VkPhysicalDevice physDevice = context.getPhysicalDevice();
630 Allocator& allocator = context.getDefaultAllocator();
632 checkGeometryShaderSupport(vki, physDevice, params.numInvocations);
634 const UVec2 renderSize (128u, 128u);
635 const VkFormat colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
636 const Vec4 clearColor = Vec4(0.0f, 0.0f, 0.0f, 1.0f);
638 const VkDeviceSize colorBufferSize = renderSize.x() * renderSize.y() * tcu::getPixelSize(mapVkFormat(colorFormat));
639 const Unique<VkBuffer> colorBuffer (makeBuffer(vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
640 const UniquePtr<Allocation> colorBufferAlloc (bindBuffer(vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
642 const std::vector<Vec4> perInstancePosition = generatePerInstancePosition(params.numDrawInstances);
645 context.getTestContext().getLog()
646 << tcu::TestLog::Message << "Rendering " << params.numDrawInstances << " instance(s) of colorful quads." << tcu::TestLog::EndMessage
647 << tcu::TestLog::Message << "Drawing " << params.numInvocations << " quad(s), each drawn by a geometry shader invocation." << tcu::TestLog::EndMessage;
650 zeroBuffer(vk, device, *colorBufferAlloc, colorBufferSize);
651 draw(context, renderSize, colorFormat, clearColor, *colorBuffer, params.numDrawInstances, perInstancePosition);
655 invalidateMappedMemoryRange(vk, device, colorBufferAlloc->getMemory(), colorBufferAlloc->getOffset(), colorBufferSize);
656 const tcu::ConstPixelBufferAccess result(mapVkFormat(colorFormat), renderSize.x(), renderSize.y(), 1u, colorBufferAlloc->getHostPtr());
658 tcu::TextureLevel reference(mapVkFormat(colorFormat), renderSize.x(), renderSize.y());
659 generateReferenceImage(reference.getAccess(), clearColor, perInstancePosition, params.numInvocations);
661 if (!tcu::fuzzyCompare(context.getTestContext().getLog(), "Image Compare", "Image Compare", reference.getAccess(), result, 0.01f, tcu::COMPARE_LOG_RESULT))
662 return tcu::TestStatus::fail("Rendered image is incorrect");
664 return tcu::TestStatus::pass("OK");
670 //! \note CTS requires shaders to be known ahead of time (some platforms use precompiled shaders), so we can't query a limit at runtime and generate
671 //! a shader based on that. This applies to number of GS invocations which can't be injected into the shader.
672 tcu::TestCaseGroup* createInstancedRenderingTests (tcu::TestContext& testCtx)
674 MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "instanced", "Instanced rendering tests."));
676 const int drawInstanceCases[] =
680 const int invocationCases[] =
682 1, 2, 8, 32, // required by the Vulkan spec
683 64, 127, // larger than the minimum, but perhaps some implementations support it, so we'll try
686 for (const int* pNumDrawInstances = drawInstanceCases; pNumDrawInstances != drawInstanceCases + DE_LENGTH_OF_ARRAY(drawInstanceCases); ++pNumDrawInstances)
687 for (const int* pNumInvocations = invocationCases; pNumInvocations != invocationCases + DE_LENGTH_OF_ARRAY(invocationCases); ++pNumInvocations)
689 std::ostringstream caseName;
690 caseName << "draw_" << *pNumDrawInstances << "_instances_" << *pNumInvocations << "_geometry_invocations";
692 const TestParams params =
698 addFunctionCaseWithPrograms(group.get(), caseName.str(), "", initPrograms, test, params);
701 return group.release();