1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2018 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 Vulkan Transform Feedback Simple Tests
22 *//*--------------------------------------------------------------------*/
24 #include "vktTransformFeedbackSimpleTests.hpp"
25 #include "vktTestGroupUtil.hpp"
26 #include "vktTestCase.hpp"
28 #include "vkBuilderUtil.hpp"
29 #include "vkCmdUtil.hpp"
30 #include "vkImageUtil.hpp"
31 #include "vkObjUtil.hpp"
32 #include "vkQueryUtil.hpp"
33 #include "vkRefUtil.hpp"
34 #include "vkTypeUtil.hpp"
36 #include "deUniquePtr.hpp"
37 #include "deRandom.hpp"
39 #include "tcuTextureUtil.hpp"
40 #include "tcuVectorUtil.hpp"
41 #include "tcuImageCompare.hpp"
42 #include "tcuRGBA.hpp"
48 namespace TransformFeedback
57 #define VALIDATE_MINIMUM(A,B) if ((A) < (B)) TCU_FAIL(#A "==" + de::toString(A) + " which is less than required by specification (" + de::toString(B) + ")")
58 #define VALIDATE_BOOL(A) if (! ( (A) == VK_TRUE || (A) == VK_FALSE) ) TCU_FAIL(#A " expected to be VK_TRUE or VK_FALSE. Received " + de::toString((deUint64)(A)))
65 TEST_TYPE_XFB_POINTSIZE,
66 TEST_TYPE_XFB_CLIPDISTANCE,
67 TEST_TYPE_XFB_CULLDISTANCE,
68 TEST_TYPE_XFB_CLIP_AND_CULL,
69 TEST_TYPE_TRIANGLE_STRIP_ADJACENCY,
70 TEST_TYPE_STREAMS_POINTSIZE,
71 TEST_TYPE_STREAMS_CLIPDISTANCE,
72 TEST_TYPE_STREAMS_CULLDISTANCE,
73 TEST_TYPE_MULTISTREAMS,
74 TEST_TYPE_DRAW_INDIRECT,
75 TEST_TYPE_BACKWARD_DEPENDENCY,
77 TEST_TYPE_QUERY_RESET,
88 deUint32 vertexStride;
91 const deUint32 MINIMUM_TF_BUFFER_SIZE = (1<<27);
92 const deUint32 IMAGE_SIZE = 64u;
95 inline SharedPtr<Unique<T> > makeSharedPtr(Move<T> move)
97 return SharedPtr<Unique<T> >(new Unique<T>(move));
100 Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface& vk,
101 const VkDevice device)
103 const VkPushConstantRange pushConstantRanges =
105 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlags stageFlags;
106 0u, // deUint32 offset;
107 sizeof(deUint32) // deUint32 size;
109 const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
111 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
112 DE_NULL, // const void* pNext;
113 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
114 0u, // deUint32 setLayoutCount;
115 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
116 1u, // deUint32 pushConstantRangeCount;
117 &pushConstantRanges, // const VkPushConstantRange* pPushConstantRanges;
119 return createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
122 Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface& vk,
123 const VkDevice device,
124 const VkPipelineLayout pipelineLayout,
125 const VkRenderPass renderPass,
126 const VkShaderModule vertexModule,
127 const VkShaderModule geometryModule,
128 const VkShaderModule fragmendModule,
129 const VkExtent2D renderSize,
130 const deUint32 subpass,
131 const deUint32* rasterizationStreamPtr = DE_NULL,
132 const VkPrimitiveTopology topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST,
133 const bool inputVertices = false)
135 const std::vector<VkViewport> viewports (1, makeViewport(renderSize));
136 const std::vector<VkRect2D> scissors (1, makeRect2D(renderSize));
137 const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo =
139 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType
140 DE_NULL, // const void* pNext
141 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags
142 0u, // deUint32 vertexBindingDescriptionCount
143 DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions
144 0u, // deUint32 vertexAttributeDescriptionCount
145 DE_NULL, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions
147 const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfoPtr = (inputVertices) ? DE_NULL : &vertexInputStateCreateInfo;
148 const VkBool32 disableRasterization = (fragmendModule == DE_NULL);
149 const deUint32 rasterizationStream = (rasterizationStreamPtr == DE_NULL) ? 0 : *rasterizationStreamPtr;
150 const VkPipelineRasterizationStateStreamCreateInfoEXT rasterizationStateStreamCreateInfo =
152 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_STREAM_CREATE_INFO_EXT, // VkStructureType sType;
153 DE_NULL, // const void* pNext;
154 0, // VkPipelineRasterizationStateStreamCreateFlagsEXT flags;
155 rasterizationStream // deUint32 rasterizationStream;
157 const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo =
159 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
160 &rasterizationStateStreamCreateInfo, // const void* pNext;
161 0u, // VkPipelineRasterizationStateCreateFlags flags;
162 VK_FALSE, // VkBool32 depthClampEnable;
163 disableRasterization, // VkBool32 rasterizerDiscardEnable;
164 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
165 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
166 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
167 VK_FALSE, // VkBool32 depthBiasEnable;
168 0.0f, // float depthBiasConstantFactor;
169 0.0f, // float depthBiasClamp;
170 0.0f, // float depthBiasSlopeFactor;
171 1.0f // float lineWidth;
173 const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfoPtr = (rasterizationStreamPtr == DE_NULL) ? DE_NULL : &rasterizationStateCreateInfo;
175 return makeGraphicsPipeline(vk, // const DeviceInterface& vk
176 device, // const VkDevice device
177 pipelineLayout, // const VkPipelineLayout pipelineLayout
178 vertexModule, // const VkShaderModule vertexShaderModule
179 DE_NULL, // const VkShaderModule tessellationControlModule
180 DE_NULL, // const VkShaderModule tessellationEvalModule
181 geometryModule, // const VkShaderModule geometryShaderModule
182 fragmendModule, // const VkShaderModule fragmentShaderModule
183 renderPass, // const VkRenderPass renderPass
184 viewports, // const std::vector<VkViewport>& viewports
185 scissors, // const std::vector<VkRect2D>& scissors
186 topology, // const VkPrimitiveTopology topology
187 subpass, // const deUint32 subpass
188 0u, // const deUint32 patchControlPoints
189 vertexInputStateCreateInfoPtr, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
190 rasterizationStateCreateInfoPtr); // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
193 VkImageCreateInfo makeImageCreateInfo (const VkImageCreateFlags flags, const VkImageType type, const VkFormat format, const VkExtent2D size, const deUint32 numLayers, const VkImageUsageFlags usage)
195 const VkExtent3D extent = { size.width, size.height, 1u };
196 const VkImageCreateInfo imageParams =
198 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
199 DE_NULL, // const void* pNext;
200 flags, // VkImageCreateFlags flags;
201 type, // VkImageType imageType;
202 format, // VkFormat format;
203 extent, // VkExtent3D extent;
204 1u, // deUint32 mipLevels;
205 numLayers, // deUint32 arrayLayers;
206 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
207 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
208 usage, // VkImageUsageFlags usage;
209 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
210 0u, // deUint32 queueFamilyIndexCount;
211 DE_NULL, // const deUint32* pQueueFamilyIndices;
212 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
217 Move<VkRenderPass> makeRenderPass (const DeviceInterface& vk,
218 const VkDevice device)
220 std::vector<VkSubpassDescription> subpassDescriptions;
221 std::vector<VkSubpassDependency> subpassDependencies;
223 const VkSubpassDescription description =
225 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags;
226 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
227 0u, // deUint32 inputAttachmentCount;
228 DE_NULL, // const VkAttachmentReference* pInputAttachments;
229 0u, // deUint32 colorAttachmentCount;
230 DE_NULL, // const VkAttachmentReference* pColorAttachments;
231 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
232 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
233 0, // deUint32 preserveAttachmentCount;
234 DE_NULL // const deUint32* pPreserveAttachments;
236 subpassDescriptions.push_back(description);
238 const VkSubpassDependency dependency =
240 0u, // deUint32 srcSubpass;
241 0u, // deUint32 dstSubpass;
242 VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT, // VkPipelineStageFlags srcStageMask;
243 VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, // VkPipelineStageFlags dstStageMask;
244 VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT, // VkAccessFlags srcAccessMask;
245 VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT, // VkAccessFlags dstAccessMask;
246 0u // VkDependencyFlags dependencyFlags;
248 subpassDependencies.push_back(dependency);
250 const VkRenderPassCreateInfo renderPassInfo =
252 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
253 DE_NULL, // const void* pNext;
254 static_cast<VkRenderPassCreateFlags>(0u), // VkRenderPassCreateFlags flags;
255 0u, // deUint32 attachmentCount;
256 DE_NULL, // const VkAttachmentDescription* pAttachments;
257 static_cast<deUint32>(subpassDescriptions.size()), // deUint32 subpassCount;
258 &subpassDescriptions[0], // const VkSubpassDescription* pSubpasses;
259 static_cast<deUint32>(subpassDependencies.size()), // deUint32 dependencyCount;
260 subpassDependencies.size() > 0 ? &subpassDependencies[0] : DE_NULL // const VkSubpassDependency* pDependencies;
263 return createRenderPass(vk, device, &renderPassInfo);
266 VkImageMemoryBarrier makeImageMemoryBarrier (const VkAccessFlags srcAccessMask,
267 const VkAccessFlags dstAccessMask,
268 const VkImageLayout oldLayout,
269 const VkImageLayout newLayout,
271 const VkImageSubresourceRange subresourceRange)
273 const VkImageMemoryBarrier barrier =
275 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
276 DE_NULL, // const void* pNext;
277 srcAccessMask, // VkAccessFlags outputMask;
278 dstAccessMask, // VkAccessFlags inputMask;
279 oldLayout, // VkImageLayout oldLayout;
280 newLayout, // VkImageLayout newLayout;
281 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
282 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
283 image, // VkImage image;
284 subresourceRange, // VkImageSubresourceRange subresourceRange;
289 VkBufferMemoryBarrier makeBufferMemoryBarrier (const VkAccessFlags srcAccessMask,
290 const VkAccessFlags dstAccessMask,
291 const VkBuffer buffer,
292 const VkDeviceSize offset,
293 const VkDeviceSize bufferSizeBytes)
295 const VkBufferMemoryBarrier barrier =
297 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
298 DE_NULL, // const void* pNext;
299 srcAccessMask, // VkAccessFlags srcAccessMask;
300 dstAccessMask, // VkAccessFlags dstAccessMask;
301 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
302 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
303 buffer, // VkBuffer buffer;
304 offset, // VkDeviceSize offset;
305 bufferSizeBytes, // VkDeviceSize size;
310 VkMemoryBarrier makeMemoryBarrier (const VkAccessFlags srcAccessMask,
311 const VkAccessFlags dstAccessMask)
313 const VkMemoryBarrier barrier =
315 VK_STRUCTURE_TYPE_MEMORY_BARRIER, // VkStructureType sType;
316 DE_NULL, // const void* pNext;
317 srcAccessMask, // VkAccessFlags outputMask;
318 dstAccessMask, // VkAccessFlags inputMask;
323 VkBufferImageCopy makeBufferImageCopy (const VkExtent3D extent,
324 const VkImageSubresourceLayers subresourceLayers)
326 const VkBufferImageCopy copyParams =
328 0ull, // VkDeviceSize bufferOffset;
329 0u, // deUint32 bufferRowLength;
330 0u, // deUint32 bufferImageHeight;
331 subresourceLayers, // VkImageSubresourceLayers imageSubresource;
332 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
333 extent, // VkExtent3D imageExtent;
338 inline Move<VkBuffer> makeBuffer (const DeviceInterface& vk, const VkDevice device, const VkBufferCreateInfo& createInfo)
340 return createBuffer(vk, device, &createInfo);
343 inline Move<VkImage> makeImage (const DeviceInterface& vk, const VkDevice device, const VkImageCreateInfo& createInfo)
345 return createImage(vk, device, &createInfo);
348 de::MovePtr<Allocation> bindImage (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkImage image, const MemoryRequirement requirement)
350 de::MovePtr<Allocation> alloc = allocator.allocate(getImageMemoryRequirements(vk, device, image), requirement);
351 VK_CHECK(vk.bindImageMemory(device, image, alloc->getMemory(), alloc->getOffset()));
355 de::MovePtr<Allocation> bindBuffer (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkBuffer buffer, const MemoryRequirement requirement)
357 de::MovePtr<Allocation> alloc(allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), requirement));
358 VK_CHECK(vk.bindBufferMemory(device, buffer, alloc->getMemory(), alloc->getOffset()));
362 VkQueryPoolCreateInfo makeQueryPoolCreateInfo (const deUint32 queryCountersNumber)
364 const VkQueryPoolCreateInfo queryPoolCreateInfo =
366 VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO, // VkStructureType sType;
367 DE_NULL, // const void* pNext;
368 (VkQueryPoolCreateFlags)0, // VkQueryPoolCreateFlags flags;
369 VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT, // VkQueryType queryType;
370 queryCountersNumber, // deUint32 queryCount;
371 0u, // VkQueryPipelineStatisticFlags pipelineStatistics;
374 return queryPoolCreateInfo;
377 void fillBuffer (const DeviceInterface& vk, const VkDevice device, Allocation& bufferAlloc, VkDeviceSize bufferSize, const void* data, const VkDeviceSize dataSize)
379 const VkMappedMemoryRange memRange =
381 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
382 DE_NULL, // const void* pNext;
383 bufferAlloc.getMemory(), // VkDeviceMemory memory;
384 bufferAlloc.getOffset(), // VkDeviceSize offset;
385 VK_WHOLE_SIZE // VkDeviceSize size;
387 std::vector<deUint8> dataVec (static_cast<deUint32>(bufferSize), 0u);
389 DE_ASSERT(bufferSize >= dataSize);
391 deMemcpy(&dataVec[0], data, static_cast<deUint32>(dataSize));
393 deMemcpy(bufferAlloc.getHostPtr(), &dataVec[0], dataVec.size());
394 VK_CHECK(vk.flushMappedMemoryRanges(device, 1u, &memRange));
397 class TransformFeedbackTestInstance : public TestInstance
400 TransformFeedbackTestInstance (Context& context, const TestParameters& parameters);
402 void validateLimits ();
403 deUint32 getNextChunkSize (const deUint32 usedBytes, const deUint32 bufBytes);
404 std::vector<VkDeviceSize> generateSizesList (const size_t bufBytes, const size_t chunkCount);
405 std::vector<VkDeviceSize> generateOffsetsList (const std::vector<VkDeviceSize>& sizesList);
406 void verifyTransformFeedbackBuffer (const MovePtr<Allocation>& bufAlloc, const deUint32 bufBytes);
408 const bool m_extensions;
409 const VkExtent2D m_imageExtent2D;
410 const TestParameters m_parameters;
411 VkPhysicalDeviceTransformFeedbackPropertiesEXT m_transformFeedbackProperties;
415 TransformFeedbackTestInstance::TransformFeedbackTestInstance (Context& context, const TestParameters& parameters)
416 : TestInstance (context)
417 , m_extensions (context.requireDeviceExtension("VK_EXT_transform_feedback"))
418 , m_imageExtent2D (makeExtent2D(IMAGE_SIZE, IMAGE_SIZE))
419 , m_parameters (parameters)
422 const VkPhysicalDeviceTransformFeedbackFeaturesEXT& transformFeedbackFeatures = m_context.getTransformFeedbackFeatures();
423 VkPhysicalDeviceProperties2 deviceProperties2;
425 if (transformFeedbackFeatures.transformFeedback == DE_FALSE)
426 TCU_THROW(NotSupportedError, "transformFeedback feature is not supported");
428 deMemset(&deviceProperties2, 0, sizeof(deviceProperties2));
429 deMemset(&m_transformFeedbackProperties, 0, sizeof(m_transformFeedbackProperties));
431 deviceProperties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
432 deviceProperties2.pNext = &m_transformFeedbackProperties;
434 m_transformFeedbackProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT;
435 m_transformFeedbackProperties.pNext = DE_NULL;
437 context.getInstanceInterface().getPhysicalDeviceProperties2(context.getPhysicalDevice(), &deviceProperties2);
442 void TransformFeedbackTestInstance::validateLimits ()
444 VALIDATE_MINIMUM(m_transformFeedbackProperties.maxTransformFeedbackBuffers, 1);
445 VALIDATE_MINIMUM(m_transformFeedbackProperties.maxTransformFeedbackBufferSize, MINIMUM_TF_BUFFER_SIZE);
446 VALIDATE_MINIMUM(m_transformFeedbackProperties.maxTransformFeedbackStreamDataSize, 512);
447 VALIDATE_MINIMUM(m_transformFeedbackProperties.maxTransformFeedbackBufferDataSize, 512);
448 VALIDATE_MINIMUM(m_transformFeedbackProperties.maxTransformFeedbackBufferDataStride, 512);
450 VALIDATE_BOOL(m_transformFeedbackProperties.transformFeedbackQueries);
451 VALIDATE_BOOL(m_transformFeedbackProperties.transformFeedbackStreamsLinesTriangles);
452 VALIDATE_BOOL(m_transformFeedbackProperties.transformFeedbackRasterizationStreamSelect);
453 VALIDATE_BOOL(m_transformFeedbackProperties.transformFeedbackDraw);
456 std::vector<VkDeviceSize> TransformFeedbackTestInstance::generateSizesList (const size_t bufBytes, const size_t chunkCount)
458 const int minChunkSlot = static_cast<int>(1);
459 const int maxChunkSlot = static_cast<int>(bufBytes / sizeof(deUint32));
460 int prevOffsetSlot = 0;
461 std::map<int, bool> offsetsSet;
462 std::vector<VkDeviceSize> result;
464 DE_ASSERT(bufBytes <= MINIMUM_TF_BUFFER_SIZE);
465 DE_ASSERT(bufBytes % sizeof(deUint32) == 0);
466 DE_ASSERT(minChunkSlot <= maxChunkSlot);
467 DE_ASSERT(chunkCount > 0);
468 // To be effective this algorithm requires that chunkCount is much less than amount of chunks possible
469 DE_ASSERT(8 * chunkCount <= static_cast<size_t>(maxChunkSlot));
471 offsetsSet[0] = true;
473 // Create a list of unique offsets first
474 for (size_t chunkNdx = 1; chunkNdx < chunkCount; ++chunkNdx)
480 chunkSlot = m_rnd.getInt(minChunkSlot, maxChunkSlot - 1);
481 } while (offsetsSet.find(chunkSlot) != offsetsSet.end());
483 offsetsSet[chunkSlot] = true;
485 offsetsSet[maxChunkSlot] = true;
487 // Calculate sizes of offsets list
488 result.reserve(chunkCount);
489 for (std::map<int, bool>::iterator mapIt = offsetsSet.begin(); mapIt != offsetsSet.end(); ++mapIt)
491 const int offsetSlot = mapIt->first;
496 DE_ASSERT(prevOffsetSlot < offsetSlot && offsetSlot > 0);
498 result.push_back(static_cast<VkDeviceSize>(static_cast<size_t>(offsetSlot - prevOffsetSlot) * sizeof(deUint32)));
500 prevOffsetSlot = offsetSlot;
503 DE_ASSERT(result.size() == chunkCount);
508 std::vector<VkDeviceSize> TransformFeedbackTestInstance::generateOffsetsList (const std::vector<VkDeviceSize>& sizesList)
510 VkDeviceSize offset = 0ull;
511 std::vector<VkDeviceSize> result;
513 result.reserve(sizesList.size());
515 for (size_t chunkNdx = 0; chunkNdx < sizesList.size(); ++chunkNdx)
517 result.push_back(offset);
519 offset += sizesList[chunkNdx];
522 DE_ASSERT(sizesList.size() == result.size());
527 void TransformFeedbackTestInstance::verifyTransformFeedbackBuffer (const MovePtr<Allocation>& bufAlloc, const deUint32 bufBytes)
529 const DeviceInterface& vk = m_context.getDeviceInterface();
530 const VkDevice device = m_context.getDevice();
532 invalidateMappedMemoryRange(vk, device, bufAlloc->getMemory(), bufAlloc->getOffset(), bufBytes);
534 const deUint32 numPoints = static_cast<deUint32>(bufBytes / sizeof(deUint32));
535 const deUint32* tfData = (deUint32*)bufAlloc->getHostPtr();
537 for (deUint32 i = 0; i < numPoints; ++i)
539 TCU_FAIL(std::string("Failed at item ") + de::toString(i) + " received:" + de::toString(tfData[i]) + " expected:" + de::toString(i));
542 class TransformFeedbackBasicTestInstance : public TransformFeedbackTestInstance
545 TransformFeedbackBasicTestInstance (Context& context, const TestParameters& parameters);
548 tcu::TestStatus iterate (void);
551 TransformFeedbackBasicTestInstance::TransformFeedbackBasicTestInstance (Context& context, const TestParameters& parameters)
552 : TransformFeedbackTestInstance (context, parameters)
556 tcu::TestStatus TransformFeedbackBasicTestInstance::iterate (void)
558 const DeviceInterface& vk = m_context.getDeviceInterface();
559 const VkDevice device = m_context.getDevice();
560 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
561 const VkQueue queue = m_context.getUniversalQueue();
562 Allocator& allocator = m_context.getDefaultAllocator();
564 const Unique<VkShaderModule> vertexModule (createShaderModule (vk, device, m_context.getBinaryCollection().get("vert"), 0u));
565 const Unique<VkRenderPass> renderPass (makeRenderPass (vk, device, VK_FORMAT_UNDEFINED));
566 const Unique<VkFramebuffer> framebuffer (makeFramebuffer (vk, device, *renderPass, 0u, DE_NULL, m_imageExtent2D.width, m_imageExtent2D.height));
567 const Unique<VkPipelineLayout> pipelineLayout (TransformFeedback::makePipelineLayout (vk, device));
568 const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertexModule, DE_NULL, DE_NULL, m_imageExtent2D, 0u));
569 const Unique<VkCommandPool> cmdPool (createCommandPool (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
570 const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
572 const VkBufferCreateInfo tfBufCreateInfo = makeBufferCreateInfo(m_parameters.bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT);
573 const Move<VkBuffer> tfBuf = createBuffer(vk, device, &tfBufCreateInfo);
574 const MovePtr<Allocation> tfBufAllocation = allocator.allocate(getBufferMemoryRequirements(vk, device, *tfBuf), MemoryRequirement::HostVisible);
575 const std::vector<VkDeviceSize> tfBufBindingSizes = generateSizesList(m_parameters.bufferSize, m_parameters.partCount);
576 const std::vector<VkDeviceSize> tfBufBindingOffsets = generateOffsetsList(tfBufBindingSizes);
578 VK_CHECK(vk.bindBufferMemory(device, *tfBuf, tfBufAllocation->getMemory(), tfBufAllocation->getOffset()));
580 beginCommandBuffer(vk, *cmdBuffer);
582 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D));
584 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
586 for (deUint32 drawNdx = 0; drawNdx < m_parameters.partCount; ++drawNdx)
588 const deUint32 startValue = static_cast<deUint32>(tfBufBindingOffsets[drawNdx] / sizeof(deUint32));
589 const deUint32 numPoints = static_cast<deUint32>(tfBufBindingSizes[drawNdx] / sizeof(deUint32));
591 vk.cmdBindTransformFeedbackBuffersEXT(*cmdBuffer, 0, 1, &*tfBuf, &tfBufBindingOffsets[drawNdx], &tfBufBindingSizes[drawNdx]);
593 vk.cmdPushConstants(*cmdBuffer, *pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0u, sizeof(startValue), &startValue);
595 vk.cmdBeginTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
597 vk.cmdDraw(*cmdBuffer, numPoints, 1u, 0u, 0u);
599 vk.cmdEndTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
602 endRenderPass(vk, *cmdBuffer);
604 endCommandBuffer(vk, *cmdBuffer);
605 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
607 verifyTransformFeedbackBuffer(tfBufAllocation, m_parameters.bufferSize);
609 return tcu::TestStatus::pass("Pass");
612 class TransformFeedbackResumeTestInstance : public TransformFeedbackTestInstance
615 TransformFeedbackResumeTestInstance (Context& context, const TestParameters& parameters);
618 tcu::TestStatus iterate (void);
621 TransformFeedbackResumeTestInstance::TransformFeedbackResumeTestInstance (Context& context, const TestParameters& parameters)
622 : TransformFeedbackTestInstance (context, parameters)
626 tcu::TestStatus TransformFeedbackResumeTestInstance::iterate (void)
628 const DeviceInterface& vk = m_context.getDeviceInterface();
629 const VkDevice device = m_context.getDevice();
630 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
631 const VkQueue queue = m_context.getUniversalQueue();
632 Allocator& allocator = m_context.getDefaultAllocator();
634 const Unique<VkShaderModule> vertexModule (createShaderModule (vk, device, m_context.getBinaryCollection().get("vert"), 0u));
635 const Unique<VkRenderPass> renderPass (makeRenderPass (vk, device, VK_FORMAT_UNDEFINED));
636 const Unique<VkFramebuffer> framebuffer (makeFramebuffer (vk, device, *renderPass, 0u, DE_NULL, m_imageExtent2D.width, m_imageExtent2D.height));
637 const Unique<VkPipelineLayout> pipelineLayout (TransformFeedback::makePipelineLayout (vk, device));
638 const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertexModule, DE_NULL, DE_NULL, m_imageExtent2D, 0u));
640 const Unique<VkCommandPool> cmdPool (createCommandPool (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
641 const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
643 const VkBufferCreateInfo tfBufCreateInfo = makeBufferCreateInfo(m_parameters.bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT);
644 const Move<VkBuffer> tfBuf = createBuffer(vk, device, &tfBufCreateInfo);
645 const MovePtr<Allocation> tfBufAllocation = allocator.allocate(getBufferMemoryRequirements(vk, device, *tfBuf), MemoryRequirement::HostVisible);
646 const std::vector<VkDeviceSize> tfBufBindingSizes = std::vector<VkDeviceSize>(1, m_parameters.bufferSize);
647 const std::vector<VkDeviceSize> tfBufBindingOffsets = std::vector<VkDeviceSize>(1, 0ull);
649 const size_t tfcBufSize = 16 * sizeof(deUint32) * m_parameters.partCount;
650 const VkBufferCreateInfo tfcBufCreateInfo = makeBufferCreateInfo(tfcBufSize, VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT);
651 const Move<VkBuffer> tfcBuf = createBuffer(vk, device, &tfcBufCreateInfo);
652 const MovePtr<Allocation> tfcBufAllocation = allocator.allocate(getBufferMemoryRequirements(vk, device, *tfcBuf), MemoryRequirement::Any);
653 const std::vector<VkDeviceSize> tfcBufBindingOffsets = generateOffsetsList(generateSizesList(tfcBufSize, m_parameters.partCount));
654 const VkBufferMemoryBarrier tfcBufBarrier = makeBufferMemoryBarrier(VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT, VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT, *tfcBuf, 0ull, VK_WHOLE_SIZE);
656 const std::vector<VkDeviceSize> chunkSizesList = generateSizesList(m_parameters.bufferSize, m_parameters.partCount);
657 const std::vector<VkDeviceSize> chunkOffsetsList = generateOffsetsList(chunkSizesList);
659 DE_ASSERT(tfBufBindingSizes.size() == 1);
660 DE_ASSERT(tfBufBindingOffsets.size() == 1);
662 VK_CHECK(vk.bindBufferMemory(device, *tfBuf, tfBufAllocation->getMemory(), tfBufAllocation->getOffset()));
663 VK_CHECK(vk.bindBufferMemory(device, *tfcBuf, tfcBufAllocation->getMemory(), tfcBufAllocation->getOffset()));
665 beginCommandBuffer(vk, *cmdBuffer);
667 for (size_t drawNdx = 0; drawNdx < m_parameters.partCount; ++drawNdx)
669 const deUint32 startValue = static_cast<deUint32>(chunkOffsetsList[drawNdx] / sizeof(deUint32));
670 const deUint32 numPoints = static_cast<deUint32>(chunkSizesList[drawNdx] / sizeof(deUint32));
671 const deUint32 countBuffersCount = (drawNdx == 0) ? 0 : 1;
673 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D));
676 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
678 vk.cmdBindTransformFeedbackBuffersEXT(*cmdBuffer, 0, 1, &*tfBuf, &tfBufBindingOffsets[0], &tfBufBindingSizes[0]);
680 vk.cmdPushConstants(*cmdBuffer, *pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0u, sizeof(startValue), &startValue);
682 vk.cmdBeginTransformFeedbackEXT(*cmdBuffer, 0, countBuffersCount, (drawNdx == 0) ? DE_NULL : &*tfcBuf, (drawNdx == 0) ? DE_NULL : &tfcBufBindingOffsets[drawNdx - 1]);
684 vk.cmdDraw(*cmdBuffer, numPoints, 1u, 0u, 0u);
686 vk.cmdEndTransformFeedbackEXT(*cmdBuffer, 0, 1, &*tfcBuf, &tfcBufBindingOffsets[drawNdx]);
688 endRenderPass(vk, *cmdBuffer);
690 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, 0u, 0u, DE_NULL, 1u, &tfcBufBarrier, 0u, DE_NULL);
693 endCommandBuffer(vk, *cmdBuffer);
694 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
696 verifyTransformFeedbackBuffer(tfBufAllocation, m_parameters.bufferSize);
698 return tcu::TestStatus::pass("Pass");
701 class TransformFeedbackTriangleStripWithAdjacencyTestInstance : public TransformFeedbackTestInstance
704 TransformFeedbackTriangleStripWithAdjacencyTestInstance (Context& context, const TestParameters& parameters);
707 tcu::TestStatus iterate (void);
708 void verifyTransformFeedbackBuffer (const MovePtr<Allocation>& bufAlloc, const VkDeviceSize bufBytes);
711 TransformFeedbackTriangleStripWithAdjacencyTestInstance::TransformFeedbackTriangleStripWithAdjacencyTestInstance (Context& context, const TestParameters& parameters)
712 : TransformFeedbackTestInstance (context, parameters)
716 tcu::TestStatus TransformFeedbackTriangleStripWithAdjacencyTestInstance::iterate (void)
718 const DeviceInterface& vk = m_context.getDeviceInterface();
719 const VkDevice device = m_context.getDevice();
720 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
721 const VkQueue queue = m_context.getUniversalQueue();
722 Allocator& allocator = m_context.getDefaultAllocator();
724 DE_ASSERT(m_parameters.partCount >= 6);
726 const VkPrimitiveTopology topology (VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY);
727 const Unique<VkShaderModule> vertexModule (createShaderModule (vk, device, m_context.getBinaryCollection().get("vert"), 0u));
728 const Unique<VkRenderPass> renderPass (makeRenderPass (vk, device, VK_FORMAT_UNDEFINED));
729 const Unique<VkFramebuffer> framebuffer (makeFramebuffer (vk, device, *renderPass, 0u, DE_NULL, m_imageExtent2D.width, m_imageExtent2D.height));
730 const Unique<VkPipelineLayout> pipelineLayout (TransformFeedback::makePipelineLayout (vk, device));
731 const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertexModule, DE_NULL, DE_NULL, m_imageExtent2D, 0u, DE_NULL, topology));
732 const Unique<VkCommandPool> cmdPool (createCommandPool (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
733 const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
735 const deUint32 numPrimitives = m_parameters.partCount / 2u - 2u;
736 const deUint32 numPoints = 3u * numPrimitives;
737 const VkDeviceSize bufferSize = numPoints * sizeof(deUint32);
738 const VkBufferCreateInfo tfBufCreateInfo = makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT);
739 const Move<VkBuffer> tfBuf = createBuffer(vk, device, &tfBufCreateInfo);
740 const MovePtr<Allocation> tfBufAllocation = allocator.allocate(getBufferMemoryRequirements(vk, device, *tfBuf), MemoryRequirement::HostVisible);
741 const VkDeviceSize tfBufBindingSize = bufferSize;
742 const VkDeviceSize tfBufBindingOffset = 0u;
743 const deUint32 startValue = 0u;
745 VK_CHECK(vk.bindBufferMemory(device, *tfBuf, tfBufAllocation->getMemory(), tfBufAllocation->getOffset()));
747 beginCommandBuffer(vk, *cmdBuffer);
749 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D));
751 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
753 vk.cmdBindTransformFeedbackBuffersEXT(*cmdBuffer, 0, 1, &*tfBuf, &tfBufBindingOffset, &tfBufBindingSize);
755 vk.cmdPushConstants(*cmdBuffer, *pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0u, sizeof(startValue), &startValue);
757 vk.cmdBeginTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
759 vk.cmdDraw(*cmdBuffer, m_parameters.partCount, 1u, 0u, 0u);
761 vk.cmdEndTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
763 endRenderPass(vk, *cmdBuffer);
765 endCommandBuffer(vk, *cmdBuffer);
766 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
768 verifyTransformFeedbackBuffer(tfBufAllocation, bufferSize);
770 return tcu::TestStatus::pass("Pass");
773 void TransformFeedbackTriangleStripWithAdjacencyTestInstance::verifyTransformFeedbackBuffer (const MovePtr<Allocation>& bufAlloc, const VkDeviceSize bufBytes)
775 const DeviceInterface& vk = m_context.getDeviceInterface();
776 const VkDevice device = m_context.getDevice();
778 invalidateMappedMemoryRange(vk, device, bufAlloc->getMemory(), bufAlloc->getOffset(), VK_WHOLE_SIZE);
780 const deUint32 numPoints = static_cast<deUint32>(bufBytes / sizeof(deUint32));
781 const deUint32* tfData = (deUint32*)bufAlloc->getHostPtr();
783 for (deUint32 dataNdx = 0; dataNdx < numPoints; ++dataNdx)
785 const deUint32 i = dataNdx / 3;
786 const deUint32 vertexNdx = dataNdx % 3;
787 const bool even = (0 == i % 2);
792 const deUint32 vertexNumbers[3] = { 2 * i + 0, 2 * i + 2, 2 * i + 4 };
794 expected = vertexNumbers[vertexNdx];
798 const deUint32 vertexNumbers[3] = { 2 * i + 0, 2 * i + 4, 2 * i + 2 };
800 expected = vertexNumbers[vertexNdx];
803 if (tfData[dataNdx] != expected)
804 TCU_FAIL(std::string("Failed at item ") + de::toString(dataNdx) + " received:" + de::toString(tfData[dataNdx]) + " expected:" + de::toString(expected));
808 class TransformFeedbackBuiltinTestInstance : public TransformFeedbackTestInstance
811 TransformFeedbackBuiltinTestInstance (Context& context, const TestParameters& parameters);
814 tcu::TestStatus iterate (void);
815 void verifyTransformFeedbackBuffer (const MovePtr<Allocation>& bufAlloc, const VkDeviceSize offset, const deUint32 bufBytes);
818 TransformFeedbackBuiltinTestInstance::TransformFeedbackBuiltinTestInstance (Context& context, const TestParameters& parameters)
819 : TransformFeedbackTestInstance (context, parameters)
821 const InstanceInterface& vki = m_context.getInstanceInterface();
822 const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
823 const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
825 const deUint32 tfBuffersSupported = m_transformFeedbackProperties.maxTransformFeedbackBuffers;
826 const deUint32 tfBuffersRequired = m_parameters.partCount;
828 if ((m_parameters.testType == TEST_TYPE_XFB_CLIPDISTANCE || m_parameters.testType == TEST_TYPE_XFB_CLIP_AND_CULL) && !features.shaderClipDistance)
829 TCU_THROW(NotSupportedError, std::string("shaderClipDistance feature is not supported"));
830 if ((m_parameters.testType == TEST_TYPE_XFB_CULLDISTANCE || m_parameters.testType == TEST_TYPE_XFB_CLIP_AND_CULL) && !features.shaderCullDistance)
831 TCU_THROW(NotSupportedError, std::string("shaderCullDistance feature is not supported"));
832 if (tfBuffersSupported < tfBuffersRequired)
833 TCU_THROW(NotSupportedError, std::string("maxTransformFeedbackBuffers=" + de::toString(tfBuffersSupported) + ", while test requires " + de::toString(tfBuffersRequired)).c_str());
836 void TransformFeedbackBuiltinTestInstance::verifyTransformFeedbackBuffer (const MovePtr<Allocation>& bufAlloc, const VkDeviceSize offset, const deUint32 bufBytes)
838 const DeviceInterface& vk = m_context.getDeviceInterface();
839 const VkDevice device = m_context.getDevice();
841 invalidateMappedMemoryRange(vk, device, bufAlloc->getMemory(), bufAlloc->getOffset(), VK_WHOLE_SIZE);
843 const deUint32 numPoints = static_cast<deUint32>(bufBytes / sizeof(float));
844 const deUint8* tfDataBytes = (deUint8*)bufAlloc->getHostPtr();
845 const float* tfData = (float*)&tfDataBytes[offset];
847 for (deUint32 i = 0; i < numPoints; ++i)
849 const deUint32 divisor = 32768u;
850 const float epsilon = 1.0f / float(divisor);
851 const float expected = float(i) / float(divisor);
853 if (deAbs(tfData[i] - expected) > epsilon)
854 TCU_FAIL(std::string("Failed at item ") + de::toString(i) + " received:" + de::toString(tfData[i]) + " expected:" + de::toString(expected));
858 tcu::TestStatus TransformFeedbackBuiltinTestInstance::iterate (void)
860 const DeviceInterface& vk = m_context.getDeviceInterface();
861 const VkDevice device = m_context.getDevice();
862 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
863 const VkQueue queue = m_context.getUniversalQueue();
864 Allocator& allocator = m_context.getDefaultAllocator();
866 const Unique<VkShaderModule> vertexModule (createShaderModule (vk, device, m_context.getBinaryCollection().get("vert"), 0u));
867 const Unique<VkRenderPass> renderPass (makeRenderPass (vk, device, VK_FORMAT_UNDEFINED));
868 const Unique<VkFramebuffer> framebuffer (makeFramebuffer (vk, device, *renderPass, 0u, DE_NULL, m_imageExtent2D.width, m_imageExtent2D.height));
869 const Unique<VkPipelineLayout> pipelineLayout (TransformFeedback::makePipelineLayout (vk, device));
870 const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertexModule, DE_NULL, DE_NULL, m_imageExtent2D, 0u));
871 const Unique<VkCommandPool> cmdPool (createCommandPool (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
872 const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
874 const VkDeviceSize tfBufSize = m_parameters.bufferSize * m_parameters.partCount;
875 const VkBufferCreateInfo tfBufCreateInfo = makeBufferCreateInfo(tfBufSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT);
876 const Move<VkBuffer> tfBuf = createBuffer(vk, device, &tfBufCreateInfo);
877 const std::vector<VkBuffer> tfBufArray = std::vector<VkBuffer>(m_parameters.partCount, *tfBuf);
878 const MovePtr<Allocation> tfBufAllocation = allocator.allocate(getBufferMemoryRequirements(vk, device, *tfBuf), MemoryRequirement::HostVisible);
879 const std::vector<VkDeviceSize> tfBufBindingSizes = std::vector<VkDeviceSize>(m_parameters.partCount, m_parameters.bufferSize);
880 const std::vector<VkDeviceSize> tfBufBindingOffsets = generateOffsetsList(tfBufBindingSizes);
881 const deUint32 perVertexDataSize = (m_parameters.testType == TEST_TYPE_XFB_POINTSIZE) ? static_cast<deUint32>(sizeof(float))
882 : (m_parameters.testType == TEST_TYPE_XFB_CLIPDISTANCE) ? static_cast<deUint32>(8u * sizeof(float))
883 : (m_parameters.testType == TEST_TYPE_XFB_CULLDISTANCE) ? static_cast<deUint32>(8u * sizeof(float))
884 : (m_parameters.testType == TEST_TYPE_XFB_CLIP_AND_CULL) ? static_cast<deUint32>(6u * sizeof(float))
886 const deUint32 numPoints = m_parameters.bufferSize / perVertexDataSize;
888 VK_CHECK(vk.bindBufferMemory(device, *tfBuf, tfBufAllocation->getMemory(), tfBufAllocation->getOffset()));
890 beginCommandBuffer(vk, *cmdBuffer);
892 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D));
894 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
896 vk.cmdBindTransformFeedbackBuffersEXT(*cmdBuffer, 0, m_parameters.partCount, &tfBufArray[0], &tfBufBindingOffsets[0], &tfBufBindingSizes[0]);
898 vk.cmdBeginTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
900 vk.cmdDraw(*cmdBuffer, numPoints, 1u, 0u, 0u);
902 vk.cmdEndTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
904 endRenderPass(vk, *cmdBuffer);
906 endCommandBuffer(vk, *cmdBuffer);
907 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
909 verifyTransformFeedbackBuffer(tfBufAllocation, tfBufBindingOffsets[m_parameters.partCount - 1], numPoints * perVertexDataSize);
911 return tcu::TestStatus::pass("Pass");
914 class TransformFeedbackMultistreamTestInstance : public TransformFeedbackTestInstance
917 TransformFeedbackMultistreamTestInstance (Context& context, const TestParameters& parameters);
920 std::vector<VkDeviceSize> generateSizesList (const size_t bufBytes, const size_t chunkCount);
921 void verifyTransformFeedbackBuffer (const MovePtr<Allocation>& bufAlloc, const deUint32 bufBytes);
922 tcu::TestStatus iterate (void);
925 TransformFeedbackMultistreamTestInstance::TransformFeedbackMultistreamTestInstance (Context& context, const TestParameters& parameters)
926 : TransformFeedbackTestInstance (context, parameters)
928 const InstanceInterface& vki = m_context.getInstanceInterface();
929 const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
930 const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
931 const VkPhysicalDeviceTransformFeedbackFeaturesEXT& transformFeedbackFeatures = m_context.getTransformFeedbackFeatures();
932 const deUint32 streamsSupported = m_transformFeedbackProperties.maxTransformFeedbackStreams;
933 const deUint32 streamsRequired = m_parameters.streamId + 1;
934 const deUint32 tfBuffersSupported = m_transformFeedbackProperties.maxTransformFeedbackBuffers;
935 const deUint32 tfBuffersRequired = m_parameters.partCount;
936 const deUint32 bytesPerVertex = m_parameters.bufferSize / m_parameters.partCount;
937 const deUint32 tfStreamDataSizeSupported = m_transformFeedbackProperties.maxTransformFeedbackStreamDataSize;
938 const deUint32 tfBufferDataSizeSupported = m_transformFeedbackProperties.maxTransformFeedbackBufferDataSize;
939 const deUint32 tfBufferDataStrideSupported = m_transformFeedbackProperties.maxTransformFeedbackBufferDataStride;
941 DE_ASSERT(m_parameters.partCount == 2u);
943 if (!features.geometryShader)
944 TCU_THROW(NotSupportedError, "Missing feature: geometryShader");
946 if (transformFeedbackFeatures.geometryStreams == DE_FALSE)
947 TCU_THROW(NotSupportedError, "geometryStreams feature is not supported");
949 if (streamsSupported < streamsRequired)
950 TCU_THROW(NotSupportedError, std::string("maxTransformFeedbackStreams=" + de::toString(streamsSupported) + ", while test requires " + de::toString(streamsRequired)).c_str());
952 if (tfBuffersSupported < tfBuffersRequired)
953 TCU_THROW(NotSupportedError, std::string("maxTransformFeedbackBuffers=" + de::toString(tfBuffersSupported) + ", while test requires " + de::toString(tfBuffersRequired)).c_str());
955 if (tfStreamDataSizeSupported < bytesPerVertex)
956 TCU_THROW(NotSupportedError, std::string("maxTransformFeedbackStreamDataSize=" + de::toString(tfStreamDataSizeSupported) + ", while test requires " + de::toString(bytesPerVertex)).c_str());
958 if (tfBufferDataSizeSupported < bytesPerVertex)
959 TCU_THROW(NotSupportedError, std::string("maxTransformFeedbackBufferDataSize=" + de::toString(tfBufferDataSizeSupported) + ", while test requires " + de::toString(bytesPerVertex)).c_str());
961 if (tfBufferDataStrideSupported < bytesPerVertex)
962 TCU_THROW(NotSupportedError, std::string("maxTransformFeedbackBufferDataStride=" + de::toString(tfBufferDataStrideSupported) + ", while test requires " + de::toString(bytesPerVertex)).c_str());
965 std::vector<VkDeviceSize> TransformFeedbackMultistreamTestInstance::generateSizesList (const size_t bufBytes, const size_t chunkCount)
967 const VkDeviceSize chunkSize = bufBytes / chunkCount;
968 std::vector<VkDeviceSize> result (chunkCount, chunkSize);
970 DE_ASSERT(chunkSize * chunkCount == bufBytes);
971 DE_ASSERT(bufBytes <= MINIMUM_TF_BUFFER_SIZE);
972 DE_ASSERT(bufBytes % sizeof(deUint32) == 0);
973 DE_ASSERT(chunkCount > 0);
974 DE_ASSERT(result.size() == chunkCount);
979 void TransformFeedbackMultistreamTestInstance::verifyTransformFeedbackBuffer (const MovePtr<Allocation>& bufAlloc, const deUint32 bufBytes)
981 const DeviceInterface& vk = m_context.getDeviceInterface();
982 const VkDevice device = m_context.getDevice();
984 invalidateMappedMemoryRange(vk, device, bufAlloc->getMemory(), bufAlloc->getOffset(), bufBytes);
986 const deUint32 numPoints = static_cast<deUint32>(bufBytes / sizeof(deUint32));
987 const float* tfData = (float*)bufAlloc->getHostPtr();
989 for (deUint32 i = 0; i < numPoints; ++i)
990 if (tfData[i] != float(i))
991 TCU_FAIL(std::string("Failed at item ") + de::toString(float(i)) + " received:" + de::toString(tfData[i]) + " expected:" + de::toString(i));
994 tcu::TestStatus TransformFeedbackMultistreamTestInstance::iterate (void)
996 const DeviceInterface& vk = m_context.getDeviceInterface();
997 const VkDevice device = m_context.getDevice();
998 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
999 const VkQueue queue = m_context.getUniversalQueue();
1000 Allocator& allocator = m_context.getDefaultAllocator();
1002 const Unique<VkRenderPass> renderPass (makeRenderPass (vk, device, VK_FORMAT_UNDEFINED));
1004 const Unique<VkShaderModule> vertexModule (createShaderModule (vk, device, m_context.getBinaryCollection().get("vert"), 0u));
1005 const Unique<VkShaderModule> geomModule (createShaderModule (vk, device, m_context.getBinaryCollection().get("geom"), 0u));
1007 const Unique<VkFramebuffer> framebuffer (makeFramebuffer (vk, device, *renderPass, 0u, DE_NULL, m_imageExtent2D.width, m_imageExtent2D.height));
1008 const Unique<VkPipelineLayout> pipelineLayout (TransformFeedback::makePipelineLayout (vk, device));
1009 const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertexModule, *geomModule, DE_NULL, m_imageExtent2D, 0u));
1010 const Unique<VkCommandPool> cmdPool (createCommandPool (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
1011 const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1013 const VkBufferCreateInfo tfBufCreateInfo = makeBufferCreateInfo(m_parameters.bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT);
1014 const Move<VkBuffer> tfBuf = createBuffer(vk, device, &tfBufCreateInfo);
1015 const std::vector<VkBuffer> tfBufArray = std::vector<VkBuffer>(m_parameters.partCount, *tfBuf);
1016 const MovePtr<Allocation> tfBufAllocation = allocator.allocate(getBufferMemoryRequirements(vk, device, *tfBuf), MemoryRequirement::HostVisible);
1017 const std::vector<VkDeviceSize> tfBufBindingSizes = generateSizesList(m_parameters.bufferSize, m_parameters.partCount);
1018 const std::vector<VkDeviceSize> tfBufBindingOffsets = generateOffsetsList(tfBufBindingSizes);
1020 VK_CHECK(vk.bindBufferMemory(device, *tfBuf, tfBufAllocation->getMemory(), tfBufAllocation->getOffset()));
1022 beginCommandBuffer(vk, *cmdBuffer);
1024 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D));
1026 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1028 vk.cmdBindTransformFeedbackBuffersEXT(*cmdBuffer, 0u, m_parameters.partCount, &tfBufArray[0], &tfBufBindingOffsets[0], &tfBufBindingSizes[0]);
1030 vk.cmdBeginTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
1032 vk.cmdDraw(*cmdBuffer, 1u, 1u, 0u, 0u);
1034 vk.cmdEndTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
1036 endRenderPass(vk, *cmdBuffer);
1038 endCommandBuffer(vk, *cmdBuffer);
1039 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
1041 verifyTransformFeedbackBuffer(tfBufAllocation, m_parameters.bufferSize);
1043 return tcu::TestStatus::pass("Pass");
1046 class TransformFeedbackStreamsTestInstance : public TransformFeedbackTestInstance
1049 TransformFeedbackStreamsTestInstance (Context& context, const TestParameters& parameters);
1052 tcu::TestStatus iterate (void);
1053 bool verifyImage (const VkFormat imageFormat, const VkExtent2D& size, const void* resultData);
1056 TransformFeedbackStreamsTestInstance::TransformFeedbackStreamsTestInstance (Context& context, const TestParameters& parameters)
1057 : TransformFeedbackTestInstance (context, parameters)
1059 const InstanceInterface& vki = m_context.getInstanceInterface();
1060 const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
1061 const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
1062 const VkPhysicalDeviceTransformFeedbackFeaturesEXT& transformFeedbackFeatures = m_context.getTransformFeedbackFeatures();
1063 const deUint32 streamsSupported = m_transformFeedbackProperties.maxTransformFeedbackStreams;
1064 const deUint32 streamsRequired = m_parameters.streamId + 1;
1065 const bool geomPointSizeRequired = m_parameters.testType == TEST_TYPE_STREAMS_POINTSIZE;
1067 if (!features.geometryShader)
1068 TCU_THROW(NotSupportedError, "Missing feature: geometryShader");
1070 if (transformFeedbackFeatures.geometryStreams == DE_FALSE)
1071 TCU_THROW(NotSupportedError, "geometryStreams feature is not supported");
1073 if (m_transformFeedbackProperties.transformFeedbackRasterizationStreamSelect == DE_FALSE)
1074 TCU_THROW(NotSupportedError, "transformFeedbackRasterizationStreamSelect feature is not supported");
1076 if (streamsSupported < streamsRequired)
1077 TCU_THROW(NotSupportedError, std::string("maxTransformFeedbackStreams=" + de::toString(streamsSupported) + ", while test requires " + de::toString(streamsRequired)).c_str());
1079 if (geomPointSizeRequired && !features.shaderTessellationAndGeometryPointSize)
1080 TCU_THROW(NotSupportedError, "shaderTessellationAndGeometryPointSize feature is not supported");
1083 bool TransformFeedbackStreamsTestInstance::verifyImage (const VkFormat imageFormat, const VkExtent2D& size, const void* resultData)
1085 const tcu::RGBA magentaRGBA (tcu::RGBA(0xFF, 0x00, 0xFF, 0xFF));
1086 const tcu::Vec4 magenta (magentaRGBA.toVec());
1087 const tcu::Vec4 black (tcu::RGBA::black().toVec());
1088 const tcu::TextureFormat textureFormat (mapVkFormat(imageFormat));
1089 const int dataSize (size.width * size.height * textureFormat.getPixelSize());
1090 tcu::TextureLevel referenceImage (textureFormat, size.width, size.height);
1091 tcu::PixelBufferAccess referenceAccess (referenceImage.getAccess());
1093 // Generate reference image
1094 if (m_parameters.testType == TEST_TYPE_STREAMS)
1096 for (int y = 0; y < referenceImage.getHeight(); ++y)
1098 const tcu::Vec4& validColor = y < referenceImage.getHeight() / 2 ? black : magenta;
1100 for (int x = 0; x < referenceImage.getWidth(); ++x)
1101 referenceAccess.setPixel(validColor, x, y);
1105 if (m_parameters.testType == TEST_TYPE_STREAMS_CLIPDISTANCE || m_parameters.testType == TEST_TYPE_STREAMS_CULLDISTANCE)
1107 for (int y = 0; y < referenceImage.getHeight(); ++y)
1108 for (int x = 0; x < referenceImage.getWidth(); ++x)
1110 const tcu::Vec4& validColor = (y >= referenceImage.getHeight() / 2) && (x >= referenceImage.getWidth() / 2) ? magenta : black;
1112 referenceAccess.setPixel(validColor, x, y);
1116 if (m_parameters.testType == TEST_TYPE_STREAMS_POINTSIZE)
1118 const int pointSize = static_cast<int>(m_parameters.pointSize);
1119 const tcu::Vec4& validColor = black;
1121 for (int y = 0; y < referenceImage.getHeight(); ++y)
1122 for (int x = 0; x < referenceImage.getWidth(); ++x)
1123 referenceAccess.setPixel(validColor, x, y);
1125 referenceAccess.setPixel(magenta, (1 + referenceImage.getWidth()) / 4 - 1, (referenceImage.getHeight() * 3) / 4 - 1);
1127 for (int y = 0; y < pointSize; ++y)
1128 for (int x = 0; x < pointSize; ++x)
1129 referenceAccess.setPixel(magenta, x + (referenceImage.getWidth() * 3) / 4 - 1, y + (referenceImage.getHeight() * 3) / 4 - 1);
1132 if (deMemCmp(resultData, referenceAccess.getDataPtr(), dataSize) != 0)
1134 const tcu::ConstPixelBufferAccess resultImage (textureFormat, size.width, size.height, 1, resultData);
1137 ok = tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Image comparison", "", referenceAccess, resultImage, tcu::UVec4(1), tcu::COMPARE_LOG_RESULT);
1145 tcu::TestStatus TransformFeedbackStreamsTestInstance::iterate (void)
1147 const DeviceInterface& vk = m_context.getDeviceInterface();
1148 const VkDevice device = m_context.getDevice();
1149 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1150 const VkQueue queue = m_context.getUniversalQueue();
1151 Allocator& allocator = m_context.getDefaultAllocator();
1153 const Unique<VkRenderPass> renderPass (makeRenderPass (vk, device, VK_FORMAT_R8G8B8A8_UNORM));
1155 const Unique<VkShaderModule> vertModule (createShaderModule (vk, device, m_context.getBinaryCollection().get("vert"), 0u));
1156 const Unique<VkShaderModule> geomModule (createShaderModule (vk, device, m_context.getBinaryCollection().get("geom"), 0u));
1157 const Unique<VkShaderModule> fragModule (createShaderModule (vk, device, m_context.getBinaryCollection().get("frag"), 0u));
1159 const VkFormat colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
1160 const VkImageUsageFlags imageUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1161 const tcu::RGBA clearColor (tcu::RGBA::black());
1162 const VkImageSubresourceRange colorSubresRange (makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u));
1163 const VkDeviceSize colorBufferSize (m_imageExtent2D.width * m_imageExtent2D.height * tcu::getPixelSize(mapVkFormat(colorFormat)));
1164 const Unique<VkImage> colorImage (makeImage (vk, device, makeImageCreateInfo(0u, VK_IMAGE_TYPE_2D, colorFormat, m_imageExtent2D, 1u, imageUsageFlags)));
1165 const UniquePtr<Allocation> colorImageAlloc (bindImage (vk, device, allocator, *colorImage, MemoryRequirement::Any));
1166 const Unique<VkImageView> colorAttachment (makeImageView (vk, device, *colorImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));
1167 const Unique<VkBuffer> colorBuffer (makeBuffer (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
1168 const UniquePtr<Allocation> colorBufferAlloc (bindBuffer (vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
1170 const Unique<VkFramebuffer> framebuffer (makeFramebuffer (vk, device, *renderPass, *colorAttachment, m_imageExtent2D.width, m_imageExtent2D.height));
1171 const Unique<VkPipelineLayout> pipelineLayout (TransformFeedback::makePipelineLayout (vk, device));
1172 const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertModule, *geomModule, *fragModule, m_imageExtent2D, 0u, &m_parameters.streamId));
1173 const Unique<VkCommandPool> cmdPool (createCommandPool (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
1174 const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1176 const VkImageMemoryBarrier preCopyBarrier = makeImageMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
1177 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1178 *colorImage, colorSubresRange);
1179 const VkBufferImageCopy region = makeBufferImageCopy(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
1180 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
1181 const VkBufferMemoryBarrier postCopyBarrier = makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *colorBuffer, 0ull, VK_WHOLE_SIZE);
1183 beginCommandBuffer(vk, *cmdBuffer);
1185 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D), clearColor.toVec());
1187 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1189 vk.cmdDraw(*cmdBuffer, 2u, 1u, 0u, 0u);
1191 endRenderPass(vk, *cmdBuffer);
1193 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
1194 vk.cmdCopyImageToBuffer(*cmdBuffer, *colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorBuffer, 1u, ®ion);
1195 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u);
1197 endCommandBuffer(vk, *cmdBuffer);
1198 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
1200 if (!verifyImage(colorFormat, m_imageExtent2D, colorBufferAlloc->getHostPtr()))
1201 return tcu::TestStatus::fail("Fail");
1203 return tcu::TestStatus::pass("Pass");
1206 class TransformFeedbackIndirectDrawTestInstance : public TransformFeedbackTestInstance
1209 TransformFeedbackIndirectDrawTestInstance (Context& context, const TestParameters& parameters);
1212 tcu::TestStatus iterate (void);
1213 bool verifyImage (const VkFormat imageFormat, const VkExtent2D& size, const void* resultData);
1216 TransformFeedbackIndirectDrawTestInstance::TransformFeedbackIndirectDrawTestInstance (Context& context, const TestParameters& parameters)
1217 : TransformFeedbackTestInstance (context, parameters)
1219 const InstanceInterface& vki = m_context.getInstanceInterface();
1220 const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
1221 const VkPhysicalDeviceLimits limits = getPhysicalDeviceProperties(vki, physDevice).limits;
1222 const deUint32 tfBufferDataSizeSupported = m_transformFeedbackProperties.maxTransformFeedbackBufferDataSize;
1223 const deUint32 tfBufferDataStrideSupported = m_transformFeedbackProperties.maxTransformFeedbackBufferDataStride;
1225 if (m_transformFeedbackProperties.transformFeedbackDraw == DE_FALSE)
1226 TCU_THROW(NotSupportedError, "transformFeedbackDraw feature is not supported");
1228 if (limits.maxVertexInputBindingStride < m_parameters.vertexStride)
1229 TCU_THROW(NotSupportedError, std::string("maxVertexInputBindingStride=" + de::toString(limits.maxVertexInputBindingStride) + ", while test requires " + de::toString(m_parameters.vertexStride)).c_str());
1231 if (tfBufferDataSizeSupported < m_parameters.vertexStride)
1232 TCU_THROW(NotSupportedError, std::string("maxTransformFeedbackBufferDataSize=" + de::toString(tfBufferDataSizeSupported) + ", while test requires " + de::toString(m_parameters.vertexStride)).c_str());
1234 if (tfBufferDataStrideSupported < m_parameters.vertexStride)
1235 TCU_THROW(NotSupportedError, std::string("maxTransformFeedbackBufferDataStride=" + de::toString(tfBufferDataStrideSupported) + ", while test requires " + de::toString(m_parameters.vertexStride)).c_str());
1238 bool TransformFeedbackIndirectDrawTestInstance::verifyImage (const VkFormat imageFormat, const VkExtent2D& size, const void* resultData)
1240 const tcu::Vec4 white (tcu::RGBA::white().toVec());
1241 const tcu::TextureFormat textureFormat (mapVkFormat(imageFormat));
1242 const int dataSize (size.width * size.height * textureFormat.getPixelSize());
1243 tcu::TextureLevel referenceImage (textureFormat, size.width, size.height);
1244 tcu::PixelBufferAccess referenceAccess (referenceImage.getAccess());
1246 // Generate reference image
1247 for (int y = 0; y < referenceImage.getHeight(); ++y)
1248 for (int x = 0; x < referenceImage.getWidth(); ++x)
1249 referenceAccess.setPixel(white, x, y);
1251 if (deMemCmp(resultData, referenceAccess.getDataPtr(), dataSize) != 0)
1253 const tcu::ConstPixelBufferAccess resultImage (textureFormat, size.width, size.height, 1, resultData);
1256 ok = tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Image comparison", "", referenceAccess, resultImage, tcu::UVec4(1), tcu::COMPARE_LOG_RESULT);
1264 tcu::TestStatus TransformFeedbackIndirectDrawTestInstance::iterate (void)
1266 const DeviceInterface& vk = m_context.getDeviceInterface();
1267 const VkDevice device = m_context.getDevice();
1268 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1269 const VkQueue queue = m_context.getUniversalQueue();
1270 Allocator& allocator = m_context.getDefaultAllocator();
1272 const Unique<VkRenderPass> renderPass (makeRenderPass (vk, device, VK_FORMAT_R8G8B8A8_UNORM));
1274 const Unique<VkShaderModule> vertModule (createShaderModule (vk, device, m_context.getBinaryCollection().get("vert"), 0u));
1275 const Unique<VkShaderModule> fragModule (createShaderModule (vk, device, m_context.getBinaryCollection().get("frag"), 0u));
1277 const VkFormat colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
1278 const VkImageUsageFlags imageUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1279 const tcu::RGBA clearColor (tcu::RGBA::black());
1280 const VkImageSubresourceRange colorSubresRange (makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u));
1281 const VkDeviceSize colorBufferSize (m_imageExtent2D.width * m_imageExtent2D.height * tcu::getPixelSize(mapVkFormat(colorFormat)));
1282 const Unique<VkImage> colorImage (makeImage (vk, device, makeImageCreateInfo(0u, VK_IMAGE_TYPE_2D, colorFormat, m_imageExtent2D, 1u, imageUsageFlags)));
1283 const UniquePtr<Allocation> colorImageAlloc (bindImage (vk, device, allocator, *colorImage, MemoryRequirement::Any));
1284 const Unique<VkImageView> colorAttachment (makeImageView (vk, device, *colorImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));
1285 const Unique<VkBuffer> colorBuffer (makeBuffer (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
1286 const UniquePtr<Allocation> colorBufferAlloc (bindBuffer (vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
1288 const deUint32 vertexCount = 6u;
1289 const VkDeviceSize vertexBufferSize = vertexCount * m_parameters.vertexStride;
1290 const VkBufferUsageFlags vertexBufferUsage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1291 const Unique<VkBuffer> vertexBuffer (makeBuffer (vk, device, makeBufferCreateInfo(vertexBufferSize, vertexBufferUsage)));
1292 const UniquePtr<Allocation> vertexBufferAlloc (bindBuffer (vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible));
1293 const VkDeviceSize vertexBufferOffset (0u);
1294 const float vertexBufferVals[] =
1296 -1.0f, -1.0f, 0.0f, 1.0f,
1297 -1.0f, +1.0f, 0.0f, 1.0f,
1298 +1.0f, -1.0f, 0.0f, 1.0f,
1299 -1.0f, +1.0f, 0.0f, 1.0f,
1300 +1.0f, -1.0f, 0.0f, 1.0f,
1301 +1.0f, +1.0f, 0.0f, 1.0f,
1304 const deUint32 counterBufferValue = m_parameters.vertexStride * vertexCount;
1305 const VkDeviceSize counterBufferSize = sizeof(counterBufferValue);
1306 const VkBufferUsageFlags counterBufferUsage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1307 const Unique<VkBuffer> counterBuffer (makeBuffer (vk, device, makeBufferCreateInfo(counterBufferSize, counterBufferUsage)));
1308 const UniquePtr<Allocation> counterBufferAlloc (bindBuffer (vk, device, allocator, *counterBuffer, MemoryRequirement::HostVisible));
1310 const Unique<VkFramebuffer> framebuffer (makeFramebuffer (vk, device, *renderPass, *colorAttachment, m_imageExtent2D.width, m_imageExtent2D.height));
1311 const Unique<VkPipelineLayout> pipelineLayout (TransformFeedback::makePipelineLayout (vk, device));
1312 const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertModule, DE_NULL, *fragModule, m_imageExtent2D, 0u, DE_NULL, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, true));
1313 const Unique<VkCommandPool> cmdPool (createCommandPool (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
1314 const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1316 const VkImageMemoryBarrier preCopyBarrier = makeImageMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
1317 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1318 *colorImage, colorSubresRange);
1319 const VkBufferImageCopy region = makeBufferImageCopy(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
1320 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
1321 const VkBufferMemoryBarrier postCopyBarrier = makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *colorBuffer, 0ull, VK_WHOLE_SIZE);
1323 fillBuffer(vk, device, *counterBufferAlloc, counterBufferSize, &counterBufferValue, counterBufferSize);
1324 fillBuffer(vk, device, *vertexBufferAlloc, vertexBufferSize, vertexBufferVals, sizeof(vertexBufferVals));
1326 beginCommandBuffer(vk, *cmdBuffer);
1328 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D), clearColor.toVec());
1330 vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertexBuffer, &vertexBufferOffset);
1332 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1334 vk.cmdDrawIndirectByteCountEXT(*cmdBuffer, 1u, 0u, *counterBuffer, 0u, 0u, m_parameters.vertexStride);
1336 endRenderPass(vk, *cmdBuffer);
1338 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
1339 vk.cmdCopyImageToBuffer(*cmdBuffer, *colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorBuffer, 1u, ®ion);
1340 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u);
1342 endCommandBuffer(vk, *cmdBuffer);
1343 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
1345 if (!verifyImage(colorFormat, m_imageExtent2D, colorBufferAlloc->getHostPtr()))
1346 return tcu::TestStatus::fail("Fail");
1348 return tcu::TestStatus::pass("Pass");
1351 class TransformFeedbackBackwardDependencyTestInstance : public TransformFeedbackTestInstance
1354 TransformFeedbackBackwardDependencyTestInstance (Context& context, const TestParameters& parameters);
1357 tcu::TestStatus iterate (void);
1358 std::vector<VkDeviceSize> generateSizesList (const size_t bufBytes, const size_t chunkCount);
1361 TransformFeedbackBackwardDependencyTestInstance::TransformFeedbackBackwardDependencyTestInstance (Context& context, const TestParameters& parameters)
1362 : TransformFeedbackTestInstance (context, parameters)
1364 if (m_transformFeedbackProperties.transformFeedbackDraw == DE_FALSE)
1365 TCU_THROW(NotSupportedError, "transformFeedbackDraw feature is not supported");
1368 std::vector<VkDeviceSize> TransformFeedbackBackwardDependencyTestInstance::generateSizesList (const size_t bufBytes, const size_t chunkCount)
1370 const VkDeviceSize chunkSize = bufBytes / chunkCount;
1371 std::vector<VkDeviceSize> result (chunkCount, chunkSize);
1373 DE_ASSERT(chunkSize * chunkCount == bufBytes);
1374 DE_ASSERT(bufBytes <= MINIMUM_TF_BUFFER_SIZE);
1375 DE_ASSERT(bufBytes % sizeof(deUint32) == 0);
1376 DE_ASSERT(chunkCount > 0);
1377 DE_ASSERT(result.size() == chunkCount);
1382 tcu::TestStatus TransformFeedbackBackwardDependencyTestInstance::iterate (void)
1384 const DeviceInterface& vk = m_context.getDeviceInterface();
1385 const VkDevice device = m_context.getDevice();
1386 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1387 const VkQueue queue = m_context.getUniversalQueue();
1388 Allocator& allocator = m_context.getDefaultAllocator();
1390 const Unique<VkShaderModule> vertexModule (createShaderModule (vk, device, m_context.getBinaryCollection().get("vert"), 0u));
1391 const Unique<VkRenderPass> renderPass (TransformFeedback::makeRenderPass (vk, device));
1392 const Unique<VkFramebuffer> framebuffer (makeFramebuffer (vk, device, *renderPass, 0u, DE_NULL, m_imageExtent2D.width, m_imageExtent2D.height));
1393 const Unique<VkPipelineLayout> pipelineLayout (TransformFeedback::makePipelineLayout (vk, device));
1394 const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertexModule, DE_NULL, DE_NULL, m_imageExtent2D, 0u));
1395 const Unique<VkCommandPool> cmdPool (createCommandPool (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
1396 const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1398 const VkBufferCreateInfo tfBufCreateInfo = makeBufferCreateInfo(m_parameters.bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT);
1399 const Move<VkBuffer> tfBuf = createBuffer(vk, device, &tfBufCreateInfo);
1400 const MovePtr<Allocation> tfBufAllocation = allocator.allocate(getBufferMemoryRequirements(vk, device, *tfBuf), MemoryRequirement::HostVisible);
1401 const VkDeviceSize tfBufBindingSize = m_parameters.bufferSize;
1402 const VkDeviceSize tfBufBindingOffset = 0ull;
1404 const size_t tfcBufSize = sizeof(deUint32);
1405 const VkBufferCreateInfo tfcBufCreateInfo = makeBufferCreateInfo(tfcBufSize, VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT | VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT);
1406 const Move<VkBuffer> tfcBuf = createBuffer(vk, device, &tfcBufCreateInfo);
1407 const MovePtr<Allocation> tfcBufAllocation = allocator.allocate(getBufferMemoryRequirements(vk, device, *tfcBuf), MemoryRequirement::Any);
1408 const VkDeviceSize tfcBufBindingOffset = 0ull;
1409 const VkMemoryBarrier tfcMemoryBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT, VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT);
1411 const std::vector<VkDeviceSize> chunkSizesList = generateSizesList(m_parameters.bufferSize, m_parameters.partCount);
1412 const std::vector<VkDeviceSize> chunkOffsetsList = generateOffsetsList(chunkSizesList);
1414 VK_CHECK(vk.bindBufferMemory(device, *tfBuf, tfBufAllocation->getMemory(), tfBufAllocation->getOffset()));
1415 VK_CHECK(vk.bindBufferMemory(device, *tfcBuf, tfcBufAllocation->getMemory(), tfcBufAllocation->getOffset()));
1417 DE_ASSERT(m_parameters.partCount == 2u);
1419 beginCommandBuffer(vk, *cmdBuffer);
1421 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D));
1423 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1425 vk.cmdBindTransformFeedbackBuffersEXT(*cmdBuffer, 0, 1, &*tfBuf, &tfBufBindingOffset, &tfBufBindingSize);
1428 const deUint32 startValue = static_cast<deUint32>(chunkOffsetsList[0] / sizeof(deUint32));
1429 const deUint32 numPoints = static_cast<deUint32>(chunkSizesList[0] / sizeof(deUint32));
1431 vk.cmdPushConstants(*cmdBuffer, *pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0u, sizeof(startValue), &startValue);
1433 vk.cmdBeginTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
1435 vk.cmdDraw(*cmdBuffer, numPoints, 1u, 0u, 0u);
1437 vk.cmdEndTransformFeedbackEXT(*cmdBuffer, 0, 1, &*tfcBuf, &tfcBufBindingOffset);
1440 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, 0u, 1u, &tfcMemoryBarrier, 0u, DE_NULL, DE_NULL, 0u);
1443 const deUint32 startValue = static_cast<deUint32>(chunkOffsetsList[1] / sizeof(deUint32));
1445 vk.cmdPushConstants(*cmdBuffer, *pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0u, sizeof(startValue), &startValue);
1447 vk.cmdBeginTransformFeedbackEXT(*cmdBuffer, 0, 1, &*tfcBuf, &tfcBufBindingOffset);
1449 vk.cmdDrawIndirectByteCountEXT(*cmdBuffer, 1u, 0u, *tfcBuf, 0u, 0u, 4u);
1451 vk.cmdEndTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
1455 endRenderPass(vk, *cmdBuffer);
1457 endCommandBuffer(vk, *cmdBuffer);
1458 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
1460 verifyTransformFeedbackBuffer(tfBufAllocation, m_parameters.bufferSize);
1462 return tcu::TestStatus::pass("Pass");
1466 class TransformFeedbackQueryTestInstance : public TransformFeedbackTestInstance
1469 TransformFeedbackQueryTestInstance (Context& context, const TestParameters& parameters);
1472 tcu::TestStatus iterate (void);
1475 TransformFeedbackQueryTestInstance::TransformFeedbackQueryTestInstance (Context& context, const TestParameters& parameters)
1476 : TransformFeedbackTestInstance (context, parameters)
1478 const InstanceInterface& vki = m_context.getInstanceInterface();
1479 const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
1480 const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
1481 const VkPhysicalDeviceTransformFeedbackFeaturesEXT& transformFeedbackFeatures = m_context.getTransformFeedbackFeatures();
1482 const deUint32 streamsSupported = m_transformFeedbackProperties.maxTransformFeedbackStreams;
1483 const deUint32 streamsRequired = m_parameters.streamId + 1;
1485 if (!features.geometryShader)
1486 TCU_THROW(NotSupportedError, "Missing feature: geometryShader");
1488 if (transformFeedbackFeatures.geometryStreams == DE_FALSE)
1489 TCU_THROW(NotSupportedError, "geometryStreams feature is not supported");
1491 if (streamsSupported < streamsRequired)
1492 TCU_THROW(NotSupportedError, std::string("maxTransformFeedbackStreams=" + de::toString(streamsSupported) + ", while test requires " + de::toString(streamsRequired)).c_str());
1494 if (m_transformFeedbackProperties.transformFeedbackQueries == DE_FALSE)
1495 TCU_THROW(NotSupportedError, "transformFeedbackQueries feature is not supported");
1497 if (m_parameters.testType == TEST_TYPE_QUERY_RESET)
1499 // Check VK_EXT_host_query_reset is supported
1500 m_context.requireDeviceExtension("VK_EXT_host_query_reset");
1501 if(m_context.getHostQueryResetFeatures().hostQueryReset == VK_FALSE)
1502 throw tcu::NotSupportedError(std::string("Implementation doesn't support resetting queries from the host").c_str());
1506 tcu::TestStatus TransformFeedbackQueryTestInstance::iterate (void)
1508 const DeviceInterface& vk = m_context.getDeviceInterface();
1509 const VkDevice device = m_context.getDevice();
1510 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1511 const VkQueue queue = m_context.getUniversalQueue();
1512 Allocator& allocator = m_context.getDefaultAllocator();
1514 const deUint32 overflowVertices = 3u;
1515 const deUint32 bytesPerVertex = static_cast<deUint32>(4 * sizeof(float));
1516 const deUint32 numVerticesInBuffer = m_parameters.bufferSize / bytesPerVertex;
1517 const deUint32 numVerticesToWrite = numVerticesInBuffer + overflowVertices;
1518 const Unique<VkRenderPass> renderPass (makeRenderPass (vk, device, VK_FORMAT_UNDEFINED));
1520 const Unique<VkShaderModule> vertModule (createShaderModule (vk, device, m_context.getBinaryCollection().get("vert"), 0u));
1521 const Unique<VkShaderModule> geomModule (createShaderModule (vk, device, m_context.getBinaryCollection().get("geom"), 0u));
1523 const Unique<VkFramebuffer> framebuffer (makeFramebuffer (vk, device, *renderPass, 0u, DE_NULL, m_imageExtent2D.width, m_imageExtent2D.height));
1524 const Unique<VkPipelineLayout> pipelineLayout (TransformFeedback::makePipelineLayout (vk, device));
1525 const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertModule, *geomModule, DE_NULL, m_imageExtent2D, 0u));
1526 const Unique<VkCommandPool> cmdPool (createCommandPool (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
1527 const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1529 const VkBufferCreateInfo tfBufCreateInfo = makeBufferCreateInfo(m_parameters.bufferSize, VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT);
1530 const Move<VkBuffer> tfBuf = createBuffer(vk, device, &tfBufCreateInfo);
1531 const MovePtr<Allocation> tfBufAllocation = bindBuffer(vk, device, allocator, *tfBuf, MemoryRequirement::HostVisible);
1532 const VkDeviceSize tfBufBindingSize = m_parameters.bufferSize;
1533 const VkDeviceSize tfBufBindingOffset = 0ull;
1535 const deUint32 queryCountersNumber = 1u;
1536 const deUint32 queryIndex = 0u;
1537 const VkQueryPoolCreateInfo queryPoolCreateInfo = makeQueryPoolCreateInfo(queryCountersNumber);
1538 const Unique<VkQueryPool> queryPool (createQueryPool(vk, device, &queryPoolCreateInfo));
1540 DE_ASSERT(numVerticesInBuffer * bytesPerVertex == m_parameters.bufferSize);
1542 beginCommandBuffer(vk, *cmdBuffer);
1544 vk.cmdResetQueryPool(*cmdBuffer, *queryPool, queryIndex, queryCountersNumber);
1546 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D));
1548 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1550 vk.cmdBindTransformFeedbackBuffersEXT(*cmdBuffer, 0u, 1u, &*tfBuf, &tfBufBindingOffset, &tfBufBindingSize);
1552 if (m_parameters.streamId == 0)
1553 vk.cmdBeginQuery(*cmdBuffer, *queryPool, queryIndex, 0u);
1555 vk.cmdBeginQueryIndexedEXT(*cmdBuffer, *queryPool, queryIndex, 0u, m_parameters.streamId);
1557 vk.cmdBeginTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
1559 vk.cmdDraw(*cmdBuffer, numVerticesToWrite, 1u, 0u, 0u);
1561 vk.cmdEndTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
1563 if (m_parameters.streamId == 0)
1564 vk.cmdEndQuery(*cmdBuffer, *queryPool, queryIndex);
1566 vk.cmdEndQueryIndexedEXT(*cmdBuffer, *queryPool, queryIndex, m_parameters.streamId);
1568 endRenderPass(vk, *cmdBuffer);
1570 endCommandBuffer(vk, *cmdBuffer);
1572 if (m_parameters.testType == TEST_TYPE_QUERY_RESET)
1573 vk.resetQueryPoolEXT(device, *queryPool, queryIndex, queryCountersNumber);
1574 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
1577 const deUint32 queryDataSize (static_cast<deUint32>(2u * sizeof(deUint32)));
1578 std::vector<deUint8> queryData (queryDataSize, 0u);
1579 const deUint32* numPrimitivesWritten = reinterpret_cast<deUint32*>(&queryData[0]);
1580 const deUint32* numPrimitivesNeeded = numPrimitivesWritten + 1;
1582 vk.getQueryPoolResults(device, *queryPool, queryIndex, queryCountersNumber, queryDataSize, &queryData[0], queryDataSize, 0u);
1584 if (*numPrimitivesWritten != numVerticesInBuffer)
1585 return tcu::TestStatus::fail("numPrimitivesWritten=" + de::toString(*numPrimitivesWritten) + " while expected " + de::toString(numVerticesInBuffer));
1587 if (*numPrimitivesNeeded != numVerticesToWrite)
1588 return tcu::TestStatus::fail("numPrimitivesNeeded=" + de::toString(*numPrimitivesNeeded) + " while expected " + de::toString(numVerticesToWrite));
1591 if (m_parameters.testType == TEST_TYPE_QUERY_RESET)
1594 const deUint32 queryDataSize (static_cast<deUint32>(3u * sizeof(deUint32)));
1595 std::vector<deUint8> queryData (queryDataSize, 0u);
1596 deUint32* numPrimitivesWritten = reinterpret_cast<deUint32*>(&queryData[0]);
1597 deUint32* numPrimitivesNeeded = numPrimitivesWritten + 1;
1598 deUint32* availabilityState = numPrimitivesNeeded + 1;
1600 // Initialize values
1601 *numPrimitivesNeeded = 1u;
1602 *numPrimitivesWritten = 1u;
1603 *availabilityState = 1u;
1605 vk.resetQueryPoolEXT(device, *queryPool, queryIndex, queryCountersNumber);
1607 vk::VkResult res = vk.getQueryPoolResults(device, *queryPool, queryIndex, queryCountersNumber, queryDataSize, &queryData[0], queryDataSize, VK_QUERY_RESULT_WITH_AVAILABILITY_BIT);
1608 /* From Vulkan spec:
1610 * If VK_QUERY_RESULT_WAIT_BIT and VK_QUERY_RESULT_PARTIAL_BIT are both not set then no result values are written to pData
1611 * for queries that are in the unavailable state at the time of the call, and vkGetQueryPoolResults returns VK_NOT_READY.
1612 * However, availability state is still written to pData for those queries if VK_QUERY_RESULT_WITH_AVAILABILITY_BIT is set.
1614 if (res != vk::VK_NOT_READY || *availabilityState != 0u)
1615 return tcu::TestStatus::fail("QueryPoolResults incorrect reset");
1616 if (*numPrimitivesWritten != 1u || *numPrimitivesNeeded != 1u )
1617 return tcu::TestStatus::fail("QueryPoolResults data was modified");
1621 return tcu::TestStatus::pass("Pass");
1624 class TransformFeedbackTestCase : public vkt::TestCase
1627 TransformFeedbackTestCase (tcu::TestContext &context, const char *name, const char *description, const TestParameters& parameters);
1630 vkt::TestInstance* createInstance (vkt::Context& context) const;
1631 void initPrograms (SourceCollections& programCollection) const;
1633 TestParameters m_parameters;
1636 TransformFeedbackTestCase::TransformFeedbackTestCase (tcu::TestContext &context, const char *name, const char *description, const TestParameters& parameters)
1637 : TestCase (context, name, description)
1638 , m_parameters (parameters)
1642 vkt::TestInstance* TransformFeedbackTestCase::createInstance (vkt::Context& context) const
1644 if (m_parameters.testType == TEST_TYPE_BASIC)
1645 return new TransformFeedbackBasicTestInstance(context, m_parameters);
1647 if (m_parameters.testType == TEST_TYPE_RESUME)
1648 return new TransformFeedbackResumeTestInstance(context, m_parameters);
1650 if (m_parameters.testType == TEST_TYPE_XFB_POINTSIZE)
1651 return new TransformFeedbackBuiltinTestInstance(context, m_parameters);
1653 if (m_parameters.testType == TEST_TYPE_XFB_CLIPDISTANCE)
1654 return new TransformFeedbackBuiltinTestInstance(context, m_parameters);
1656 if (m_parameters.testType == TEST_TYPE_XFB_CULLDISTANCE)
1657 return new TransformFeedbackBuiltinTestInstance(context, m_parameters);
1659 if (m_parameters.testType == TEST_TYPE_XFB_CLIP_AND_CULL)
1660 return new TransformFeedbackBuiltinTestInstance(context, m_parameters);
1662 if (m_parameters.testType == TEST_TYPE_TRIANGLE_STRIP_ADJACENCY)
1663 return new TransformFeedbackTriangleStripWithAdjacencyTestInstance(context, m_parameters);
1665 if (m_parameters.testType == TEST_TYPE_STREAMS)
1666 return new TransformFeedbackStreamsTestInstance(context, m_parameters);
1668 if (m_parameters.testType == TEST_TYPE_STREAMS_POINTSIZE)
1669 return new TransformFeedbackStreamsTestInstance(context, m_parameters);
1671 if (m_parameters.testType == TEST_TYPE_STREAMS_CLIPDISTANCE)
1672 return new TransformFeedbackStreamsTestInstance(context, m_parameters);
1674 if (m_parameters.testType == TEST_TYPE_STREAMS_CULLDISTANCE)
1675 return new TransformFeedbackStreamsTestInstance(context, m_parameters);
1677 if (m_parameters.testType == TEST_TYPE_MULTISTREAMS)
1678 return new TransformFeedbackMultistreamTestInstance(context, m_parameters);
1680 if (m_parameters.testType == TEST_TYPE_DRAW_INDIRECT)
1681 return new TransformFeedbackIndirectDrawTestInstance(context, m_parameters);
1683 if (m_parameters.testType == TEST_TYPE_BACKWARD_DEPENDENCY)
1684 return new TransformFeedbackBackwardDependencyTestInstance(context, m_parameters);
1686 if (m_parameters.testType == TEST_TYPE_QUERY || m_parameters.testType == TEST_TYPE_QUERY_RESET)
1687 return new TransformFeedbackQueryTestInstance(context, m_parameters);
1689 TCU_THROW(InternalError, "Specified test type not found");
1692 void TransformFeedbackTestCase::initPrograms (SourceCollections& programCollection) const
1694 const bool vertexShaderOnly = m_parameters.testType == TEST_TYPE_BASIC
1695 || m_parameters.testType == TEST_TYPE_RESUME
1696 || m_parameters.testType == TEST_TYPE_BACKWARD_DEPENDENCY
1697 || m_parameters.testType == TEST_TYPE_TRIANGLE_STRIP_ADJACENCY;
1698 const bool requiresFullPipeline = m_parameters.testType == TEST_TYPE_STREAMS
1699 || m_parameters.testType == TEST_TYPE_STREAMS_POINTSIZE
1700 || m_parameters.testType == TEST_TYPE_STREAMS_CULLDISTANCE
1701 || m_parameters.testType == TEST_TYPE_STREAMS_CLIPDISTANCE;
1702 const bool xfbBuiltinPipeline = m_parameters.testType == TEST_TYPE_XFB_POINTSIZE
1703 || m_parameters.testType == TEST_TYPE_XFB_CLIPDISTANCE
1704 || m_parameters.testType == TEST_TYPE_XFB_CULLDISTANCE
1705 || m_parameters.testType == TEST_TYPE_XFB_CLIP_AND_CULL;
1707 if (vertexShaderOnly)
1711 std::ostringstream src;
1712 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1714 << "layout(push_constant) uniform pushConstants\n"
1719 << "layout(xfb_buffer = 0, xfb_offset = 0, xfb_stride = 4, location = 0) out uint idx_out;\n"
1721 << "void main(void)\n"
1723 << " idx_out = uInput.start + gl_VertexIndex;\n"
1726 programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
1732 if (xfbBuiltinPipeline)
1734 const std::string outputBuiltIn = (m_parameters.testType == TEST_TYPE_XFB_POINTSIZE) ? "float gl_PointSize;\n"
1735 : (m_parameters.testType == TEST_TYPE_XFB_CLIPDISTANCE) ? "float gl_ClipDistance[8];\n"
1736 : (m_parameters.testType == TEST_TYPE_XFB_CULLDISTANCE) ? "float gl_CullDistance[8];\n"
1737 : (m_parameters.testType == TEST_TYPE_XFB_CLIP_AND_CULL) ? "float gl_CullDistance[5];\nfloat gl_ClipDistance[1];\n"
1739 const std::string operationBuiltIn = (m_parameters.testType == TEST_TYPE_XFB_POINTSIZE) ? "gl_PointSize = float(gl_VertexIndex) / 32768.0f;"
1740 : (m_parameters.testType == TEST_TYPE_XFB_CLIPDISTANCE) ? "for (int i=0; i<8; i++) gl_ClipDistance[i] = float(8 * gl_VertexIndex + i) / 32768.0f;"
1741 : (m_parameters.testType == TEST_TYPE_XFB_CULLDISTANCE) ? "for (int i=0; i<8; i++) gl_CullDistance[i] = float(8 * gl_VertexIndex + i) / 32768.0f;"
1742 : (m_parameters.testType == TEST_TYPE_XFB_CLIP_AND_CULL) ? "for (int i=0; i<5; i++) gl_CullDistance[i] = float(6 * gl_VertexIndex + i) / 32768.0f;\n"
1743 "gl_ClipDistance[0] = float(6 * gl_VertexIndex + 5) / 32768.0f;\n"
1748 std::ostringstream src;
1749 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1751 << "layout(xfb_buffer = " << m_parameters.partCount - 1 << ", xfb_offset = 0) out gl_PerVertex\n"
1756 << "void main(void)\n"
1761 programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
1767 if (m_parameters.testType == TEST_TYPE_MULTISTREAMS)
1771 std::ostringstream src;
1772 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1774 << "void main(void)\n"
1778 programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
1783 const deUint32 s = m_parameters.streamId;
1784 std::ostringstream src;
1788 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1790 << "layout(points) in;\n"
1792 << "layout(points, max_vertices = 32) out;\n"
1793 << "layout(stream = " << 0 << ", xfb_buffer = 0, xfb_offset = 0, xfb_stride = 16, location = 0) out vec4 out0;\n"
1794 << "layout(stream = " << s << ", xfb_buffer = 1, xfb_offset = 0, xfb_stride = 16, location = 1) out vec4 out1;\n"
1796 << "const int counts[] = int[](1, 1, 2, 4, 8);\n"
1798 << "void main(void)\n"
1803 << " // Start 1st buffer from point where 0th buffer ended\n"
1804 << " for (int i = 0; i < counts.length(); i++)\n"
1805 << " c1 = c1 + 4 * counts[i];\n"
1807 << " for (int i = 0; i < counts.length(); i++)\n"
1809 << " const int n0 = counts[i];\n"
1810 << " const int n1 = counts[counts.length() - 1 - i];\n"
1812 << " for (int j = 0; j < n0; j++)\n"
1814 << " out0 = vec4(ivec4(c0, c0 + 1, c0 + 2, c0 + 3));\n"
1815 << " c0 = c0 + 4;\n"
1816 << " EmitStreamVertex(0);\n"
1817 << " EndStreamPrimitive(0);\n"
1820 << " for (int j = 0; j < n1; j++)\n"
1822 << " out1 = vec4(ivec4(c1, c1 + 1, c1 + 2, c1 + 3));\n"
1823 << " c1 = c1 + 4;\n"
1824 << " EmitStreamVertex(" << s << ");\n"
1825 << " EndStreamPrimitive(" << s << ");\n"
1830 programCollection.glslSources.add("geom") << glu::GeometrySource(src.str());
1836 if (requiresFullPipeline)
1840 std::ostringstream src;
1841 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1843 << "void main(void)\n"
1847 programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
1852 const deUint32 s = m_parameters.streamId;
1853 const bool requirePoints = (m_parameters.testType == TEST_TYPE_STREAMS_POINTSIZE || m_parameters.testType == TEST_TYPE_MULTISTREAMS);
1854 const std::string outputPrimitiveType = requirePoints ? "points" : "triangle_strip";
1855 const std::string outputBuiltIn = (m_parameters.testType == TEST_TYPE_STREAMS_POINTSIZE) ? " float gl_PointSize;\n"
1856 : (m_parameters.testType == TEST_TYPE_STREAMS_CLIPDISTANCE) ? " float gl_ClipDistance[];\n"
1857 : (m_parameters.testType == TEST_TYPE_STREAMS_CULLDISTANCE) ? " float gl_CullDistance[];\n"
1859 std::ostringstream src;
1863 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1865 << "layout(points) in;\n"
1866 << "layout(" << outputPrimitiveType << ", max_vertices = 16) out;\n"
1867 << "layout(stream = " << s << ") out;\n"
1868 << "layout(location = 0) out vec4 color;\n"
1870 << "layout(stream = " << s << ") out gl_PerVertex\n"
1872 << " vec4 gl_Position;\n"
1876 << "void main(void)\n"
1878 << " // Color constants\n"
1879 << " vec4 g = vec4(0.0, 1.0, 0.0, 1.0);\n"
1880 << " vec4 m = vec4(1.0, 0.0, 1.0, 1.0);\n"
1881 << " // Coordinate constants: leftmost column\n"
1882 << " vec4 a = vec4(-1.0,-1.0, 0.0, 1.0);\n"
1883 << " vec4 b = vec4(-1.0, 0.0, 0.0, 1.0);\n"
1884 << " vec4 c = vec4(-1.0, 1.0, 0.0, 1.0);\n"
1885 << " // Coordinate constants: middle column\n"
1886 << " vec4 i = vec4( 0.0,-1.0, 0.0, 1.0);\n"
1887 << " vec4 j = vec4( 0.0, 0.0, 0.0, 1.0);\n"
1888 << " vec4 k = vec4( 0.0, 1.0, 0.0, 1.0);\n"
1889 << " // Coordinate constants: rightmost column\n"
1890 << " vec4 x = vec4( 1.0,-1.0, 0.0, 1.0);\n"
1891 << " vec4 y = vec4( 1.0, 0.0, 0.0, 1.0);\n"
1892 << " vec4 z = vec4( 1.0, 1.0, 0.0, 1.0);\n"
1895 if (m_parameters.testType == TEST_TYPE_STREAMS)
1897 src << " if (gl_PrimitiveIDIn == 0)\n"
1899 << " color = m; gl_Position = b; EmitStreamVertex(" << s << ");\n"
1900 << " color = m; gl_Position = y; EmitStreamVertex(" << s << ");\n"
1901 << " color = m; gl_Position = c; EmitStreamVertex(" << s << ");\n"
1902 << " EndStreamPrimitive(" << s << ");\n"
1906 << " color = m; gl_Position = y; EmitStreamVertex(" << s << ");\n"
1907 << " color = m; gl_Position = c; EmitStreamVertex(" << s << ");\n"
1908 << " color = m; gl_Position = z; EmitStreamVertex(" << s << ");\n"
1909 << " EndStreamPrimitive(" << s << ");\n"
1913 if (m_parameters.testType == TEST_TYPE_STREAMS_POINTSIZE)
1915 const std::string pointSize = "gl_PointSize = " + de::toString(m_parameters.pointSize) + ".0f";
1917 src << " if (gl_PrimitiveIDIn == 0)\n"
1919 << " color = g; gl_Position = (a + j) / 2.0f; gl_PointSize = 1.0f; EmitStreamVertex(0);\n"
1920 << " EndStreamPrimitive(0);\n"
1921 << " color = m; gl_Position = (b + k) / 2.0f; gl_PointSize = 1.0f; EmitStreamVertex(" << s << ");\n"
1922 << " EndStreamPrimitive(" << s << ");\n"
1926 << " color = g; gl_Position = (j + x) / 2.0f; " << pointSize << "; EmitStreamVertex(0);\n"
1927 << " EndStreamPrimitive(0);\n"
1928 << " color = m; gl_Position = (k + y) / 2.0f; " << pointSize << "; EmitStreamVertex(" << s << ");\n"
1929 << " EndStreamPrimitive(" << s << ");\n"
1933 if (m_parameters.testType == TEST_TYPE_STREAMS_CLIPDISTANCE)
1935 src << " if (gl_PrimitiveIDIn == 0)\n"
1937 << " color = m; gl_Position = b; gl_ClipDistance[0] = -1.0; EmitStreamVertex(" << s << ");\n"
1938 << " color = m; gl_Position = c; gl_ClipDistance[0] = -1.0; EmitStreamVertex(" << s << ");\n"
1939 << " color = m; gl_Position = y; gl_ClipDistance[0] = 1.0; EmitStreamVertex(" << s << ");\n"
1940 << " EndStreamPrimitive(" << s << ");\n"
1944 << " color = m; gl_Position = y; gl_ClipDistance[0] = 1.0; EmitStreamVertex(" << s << ");\n"
1945 << " color = m; gl_Position = c; gl_ClipDistance[0] = -1.0; EmitStreamVertex(" << s << ");\n"
1946 << " color = m; gl_Position = z; gl_ClipDistance[0] = 1.0; EmitStreamVertex(" << s << ");\n"
1947 << " EndStreamPrimitive(" << s << ");\n"
1951 if (m_parameters.testType == TEST_TYPE_STREAMS_CULLDISTANCE)
1953 src << " if (gl_PrimitiveIDIn == 0)\n"
1955 << " color = m; gl_Position = b; gl_CullDistance[0] = -1.0; EmitStreamVertex(" << s << ");\n"
1956 << " color = m; gl_Position = c; gl_CullDistance[0] = -1.0; EmitStreamVertex(" << s << ");\n"
1957 << " color = m; gl_Position = j; gl_CullDistance[0] = -1.0; EmitStreamVertex(" << s << ");\n"
1958 << " EndStreamPrimitive(" << s << ");\n"
1959 << " color = m; gl_Position = j; gl_CullDistance[0] = -1.0; EmitStreamVertex(" << s << ");\n"
1960 << " color = m; gl_Position = c; gl_CullDistance[0] = -1.0; EmitStreamVertex(" << s << ");\n"
1961 << " color = m; gl_Position = k; gl_CullDistance[0] = -1.0; EmitStreamVertex(" << s << ");\n"
1962 << " EndStreamPrimitive(" << s << ");\n"
1966 << " color = m; gl_Position = j; gl_CullDistance[0] = 1.0; EmitStreamVertex(" << s << ");\n"
1967 << " color = m; gl_Position = k; gl_CullDistance[0] = 1.0; EmitStreamVertex(" << s << ");\n"
1968 << " color = m; gl_Position = y; gl_CullDistance[0] = 1.0; EmitStreamVertex(" << s << ");\n"
1969 << " EndStreamPrimitive(" << s << ");\n"
1970 << " color = m; gl_Position = y; gl_CullDistance[0] = 1.0; EmitStreamVertex(" << s << ");\n"
1971 << " color = m; gl_Position = k; gl_CullDistance[0] = 1.0; EmitStreamVertex(" << s << ");\n"
1972 << " color = m; gl_Position = z; gl_CullDistance[0] = 1.0; EmitStreamVertex(" << s << ");\n"
1973 << " EndStreamPrimitive(" << s << ");\n"
1979 programCollection.glslSources.add("geom") << glu::GeometrySource(src.str());
1984 std::ostringstream src;
1985 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1987 << "layout(location = 0) in vec4 i_color;\n"
1988 << "layout(location = 0) out vec4 o_color;\n"
1990 << "void main(void)\n"
1992 << " o_color = i_color;\n"
1995 programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
2001 if (m_parameters.testType == TEST_TYPE_DRAW_INDIRECT)
2005 std::ostringstream src;
2006 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
2008 << "layout(location = 0) in vec4 in_position;\n"
2010 << "void main(void)\n"
2012 << " gl_Position = in_position;\n"
2015 programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
2020 std::ostringstream src;
2021 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
2023 << "layout(location = 0) out vec4 o_color;\n"
2025 << "void main(void)\n"
2027 << " o_color = vec4(1.0, 1.0, 1.0, 1.0);\n"
2030 programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
2036 if (m_parameters.testType == TEST_TYPE_QUERY || m_parameters.testType == TEST_TYPE_QUERY_RESET)
2040 std::ostringstream src;
2041 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
2043 << "layout(location = 0) out vec4 out0;\n"
2045 << "void main(void)\n"
2047 << " float n = 4.0 * float(gl_VertexIndex);\n"
2048 << " out0 = vec4(n + 0.0, n + 1.0, n + 2.0, n + 3.0);\n"
2051 programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
2056 const deUint32 s = m_parameters.streamId;
2057 std::ostringstream src;
2059 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
2061 << "layout(points) in;\n"
2062 << "layout(location = 0) in vec4 in0[];\n"
2064 << "layout(points, max_vertices = 1) out;\n"
2065 << "layout(stream = " << s << ", xfb_buffer = 0, xfb_offset = 0, xfb_stride = 16, location = 0) out vec4 out0;\n"
2067 << "void main(void)\n"
2069 << " out0 = in0[0];\n"
2070 << " EmitStreamVertex(" << s << ");\n"
2071 << " EndStreamPrimitive(" << s << ");\n"
2074 programCollection.glslSources.add("geom") << glu::GeometrySource(src.str());
2080 DE_ASSERT(0 && "Unknown test");
2083 void createTransformFeedbackSimpleTests (tcu::TestCaseGroup* group)
2086 const deUint32 bufferCounts[] = { 1, 2, 4, 8 };
2087 const deUint32 bufferSizes[] = { 256, 512, 128*1024 };
2088 const TestType testTypes[] = { TEST_TYPE_BASIC, TEST_TYPE_RESUME, TEST_TYPE_XFB_POINTSIZE, TEST_TYPE_XFB_CLIPDISTANCE, TEST_TYPE_XFB_CULLDISTANCE, TEST_TYPE_XFB_CLIP_AND_CULL };
2089 const std::string testTypeNames[] = { "basic", "resume", "xfb_pointsize", "xfb_clipdistance", "xfb_culldistance", "xfb_clip_and_cull" };
2091 for (deUint32 testTypesNdx = 0; testTypesNdx < DE_LENGTH_OF_ARRAY(testTypes); ++testTypesNdx)
2093 const TestType testType = testTypes[testTypesNdx];
2094 const std::string testName = testTypeNames[testTypesNdx];
2096 for (deUint32 bufferCountsNdx = 0; bufferCountsNdx < DE_LENGTH_OF_ARRAY(bufferCounts); ++bufferCountsNdx)
2098 const deUint32 partCount = bufferCounts[bufferCountsNdx];
2100 for (deUint32 bufferSizesNdx = 0; bufferSizesNdx < DE_LENGTH_OF_ARRAY(bufferSizes); ++bufferSizesNdx)
2102 const deUint32 bufferSize = bufferSizes[bufferSizesNdx];
2103 const TestParameters parameters = { testType, bufferSize, partCount, 0u, 0u, 0u };
2105 group->addChild(new TransformFeedbackTestCase(group->getTestContext(), (testName + "_" + de::toString(partCount) + "_" + de::toString(bufferSize)).c_str(), "Simple Transform Feedback test", parameters));
2112 const deUint32 bufferCounts[] = { 6, 8, 10, 12 };
2113 const TestType testTypes[] = { TEST_TYPE_TRIANGLE_STRIP_ADJACENCY };
2114 const std::string testTypeNames[] = { "triangle_strip_with_adjacency"};
2116 for (deUint32 testTypesNdx = 0; testTypesNdx < DE_LENGTH_OF_ARRAY(testTypes); ++testTypesNdx)
2118 const TestType testType = testTypes[testTypesNdx];
2119 const std::string testName = testTypeNames[testTypesNdx];
2121 for (deUint32 bufferCountsNdx = 0; bufferCountsNdx < DE_LENGTH_OF_ARRAY(bufferCounts); ++bufferCountsNdx)
2123 const deUint32 vertexCount = bufferCounts[bufferCountsNdx];
2124 const TestParameters parameters = { testType, 0u, vertexCount, 0u, 0u, 0u };
2126 group->addChild(new TransformFeedbackTestCase(group->getTestContext(), (testName + "_" + de::toString(vertexCount)).c_str(), "Triangle Strip With Adjacency Transform Feedback test", parameters));
2132 const deUint32 vertexStrides[] = { 4, 61, 127, 251, 509 };
2133 const TestType testType = TEST_TYPE_DRAW_INDIRECT;
2134 const std::string testName = "draw_indirect";
2136 for (deUint32 vertexStridesNdx = 0; vertexStridesNdx < DE_LENGTH_OF_ARRAY(vertexStrides); ++vertexStridesNdx)
2138 const deUint32 vertexStride = static_cast<deUint32>(sizeof(deUint32) * vertexStrides[vertexStridesNdx]);
2139 const TestParameters parameters = { testType, 0u, 0u, 0u, 0u, vertexStride };
2141 group->addChild(new TransformFeedbackTestCase(group->getTestContext(), (testName + "_" + de::toString(vertexStride)).c_str(), "Rendering tests with various strides", parameters));
2146 const TestType testType = TEST_TYPE_BACKWARD_DEPENDENCY;
2147 const std::string testName = "backward_dependency";
2148 const TestParameters parameters = { testType, 512u, 2u, 0u, 0u, 0u };
2150 group->addChild(new TransformFeedbackTestCase(group->getTestContext(), testName.c_str(), "Rendering test checks backward pipeline dependency", parameters));
2154 const deUint32 usedStreamId[] = { 0, 1, 3, 6, 14 };
2155 const deUint32 vertexCount[] = { 4, 61, 127, 251, 509 };
2156 const TestType testType = TEST_TYPE_QUERY;
2157 const std::string testName = "query";
2158 const TestType testTypeHostQueryReset = TEST_TYPE_QUERY_RESET;
2159 const std::string testNameHostQueryReset = "host_query_reset";
2161 for (deUint32 streamCountsNdx = 0; streamCountsNdx < DE_LENGTH_OF_ARRAY(usedStreamId); ++streamCountsNdx)
2163 const deUint32 streamId = usedStreamId[streamCountsNdx];
2165 for (deUint32 vertexCountNdx = 0; vertexCountNdx < DE_LENGTH_OF_ARRAY(vertexCount); ++vertexCountNdx)
2167 const deUint32 bytesPerVertex = static_cast<deUint32>(4 * sizeof(float));
2168 const deUint32 bufferSize = bytesPerVertex * vertexCount[vertexCountNdx];
2169 const TestParameters parameters = { testType, bufferSize, 0u, streamId, 0u, 0u };
2170 const std::string fullTestName = testName + "_" + de::toString(streamId) + "_" + de::toString(vertexCount[vertexCountNdx]);
2172 group->addChild(new TransformFeedbackTestCase(group->getTestContext(), fullTestName.c_str(), "Written primitives query test", parameters));
2174 const std::string fullTestNameHostQueryReset = testNameHostQueryReset + "_" + de::toString(streamId) + "_" + de::toString(vertexCount[vertexCountNdx]);
2175 const TestParameters parametersHostQueryReset = { testTypeHostQueryReset, bufferSize, 0u, streamId, 0u, 0u };
2176 group->addChild(new TransformFeedbackTestCase(group->getTestContext(), fullTestNameHostQueryReset.c_str(), "Written primitives query test", parametersHostQueryReset));
2182 void createTransformFeedbackStreamsSimpleTests (tcu::TestCaseGroup* group)
2184 const deUint32 usedStreamId[] = { 1, 3, 6, 14 };
2185 const TestType testTypes[] = { TEST_TYPE_STREAMS, TEST_TYPE_STREAMS_POINTSIZE, TEST_TYPE_STREAMS_CLIPDISTANCE, TEST_TYPE_STREAMS_CULLDISTANCE };
2186 const std::string testTypeNames[] = { "streams", "streams_pointsize", "streams_clipdistance", "streams_culldistance" };
2188 for (deUint32 testTypesNdx = 0; testTypesNdx < DE_LENGTH_OF_ARRAY(testTypes); ++testTypesNdx)
2190 const TestType testType = testTypes[testTypesNdx];
2191 const std::string testName = testTypeNames[testTypesNdx];
2192 const deUint32 pointSize = (testType == TEST_TYPE_STREAMS_POINTSIZE) ? 2u : 0u;
2194 for (deUint32 streamCountsNdx = 0; streamCountsNdx < DE_LENGTH_OF_ARRAY(usedStreamId); ++streamCountsNdx)
2196 const deUint32 streamId = usedStreamId[streamCountsNdx];
2197 const TestParameters parameters = { testType, 0u, 0u, streamId, pointSize, 0u };
2199 group->addChild(new TransformFeedbackTestCase(group->getTestContext(), (testName + "_" + de::toString(streamId)).c_str(), "Streams usage test", parameters));
2204 const TestType testType = TEST_TYPE_MULTISTREAMS;
2205 const std::string testName = "multistreams";
2207 for (deUint32 bufferCountsNdx = 0; bufferCountsNdx < DE_LENGTH_OF_ARRAY(usedStreamId); ++bufferCountsNdx)
2209 const deUint32 streamId = usedStreamId[bufferCountsNdx];
2210 const deUint32 streamsUsed = 2u;
2211 const deUint32 maxBytesPerVertex = 256u;
2212 const TestParameters parameters = { testType, maxBytesPerVertex * streamsUsed, streamsUsed, streamId, 0u, 0u };
2214 group->addChild(new TransformFeedbackTestCase(group->getTestContext(), (testName + "_" + de::toString(streamId)).c_str(), "Simultaneous multiple streams usage test", parameters));
2219 void createTransformFeedbackAndStreamsSimpleTests (tcu::TestCaseGroup* group)
2221 createTransformFeedbackSimpleTests(group);
2222 createTransformFeedbackStreamsSimpleTests(group);
2226 tcu::TestCaseGroup* createTransformFeedbackSimpleTests (tcu::TestContext& testCtx)
2228 return createTestGroup(testCtx, "simple", "Transform Feedback Simple tests", createTransformFeedbackAndStreamsSimpleTests);
2231 } // TransformFeedback