1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Imagination Technologies Ltd.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 *//*!
21 * \file
22 * \brief Stencil Tests
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktPipelineStencilTests.hpp"
26 #include "vktPipelineClearUtil.hpp"
27 #include "vktPipelineImageUtil.hpp"
28 #include "vktPipelineVertexUtil.hpp"
29 #include "vktPipelineReferenceRenderer.hpp"
30 #include "vktPipelineUniqueRandomIterator.hpp"
31 #include "vktTestCase.hpp"
32 #include "vkImageUtil.hpp"
33 #include "vkMemUtil.hpp"
34 #include "vkPrograms.hpp"
35 #include "vkQueryUtil.hpp"
36 #include "vkRef.hpp"
37 #include "vkRefUtil.hpp"
38 #include "vkTypeUtil.hpp"
39 #include "vkCmdUtil.hpp"
40 #include "vkObjUtil.hpp"
41 #include "tcuImageCompare.hpp"
42 #include "deMemory.h"
43 #include "deRandom.hpp"
44 #include "deStringUtil.hpp"
45 #include "deUniquePtr.hpp"
46
47 #include <algorithm>
48 #include <sstream>
49 #include <vector>
50
51 namespace vkt
52 {
53 namespace pipeline
54 {
55
56 using namespace vk;
57
58 namespace
59 {
60
isSupportedDepthStencilFormat(const InstanceInterface & instanceInterface,VkPhysicalDevice device,VkFormat format)61 bool isSupportedDepthStencilFormat (const InstanceInterface& instanceInterface, VkPhysicalDevice device, VkFormat format)
62 {
63 VkFormatProperties formatProps;
64
65 instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps);
66
67 return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0;
68 }
69
70 class StencilOpStateUniqueRandomIterator : public UniqueRandomIterator<VkStencilOpState>
71 {
72 public:
73 StencilOpStateUniqueRandomIterator (int seed);
~StencilOpStateUniqueRandomIterator(void)74 virtual ~StencilOpStateUniqueRandomIterator (void) {}
75 virtual VkStencilOpState getIndexedValue (deUint32 index);
76
77 private:
78
79 // Pre-calculated constants
80 const static deUint32 s_stencilOpsLength;
81 const static deUint32 s_stencilOpsLength2;
82 const static deUint32 s_stencilOpsLength3;
83 const static deUint32 s_compareOpsLength;
84
85 // Total number of cross-combinations of (stencilFailOp x stencilPassOp x stencilDepthFailOp x stencilCompareOp)
86 const static deUint32 s_totalStencilOpStates;
87 };
88
89
90 class StencilTest : public vkt::TestCase
91 {
92 public:
93 enum
94 {
95 QUAD_COUNT = 4
96 };
97
98 struct StencilStateConfig
99 {
100 deUint32 frontReadMask;
101 deUint32 frontWriteMask;
102 deUint32 frontRef;
103
104 deUint32 backReadMask;
105 deUint32 backWriteMask;
106 deUint32 backRef;
107 };
108
109 const static StencilStateConfig s_stencilStateConfigs[QUAD_COUNT];
110 const static float s_quadDepths[QUAD_COUNT];
111
112
113 StencilTest (tcu::TestContext& testContext,
114 const std::string& name,
115 const std::string& description,
116 VkFormat stencilFormat,
117 const VkStencilOpState& stencilOpStateFront,
118 const VkStencilOpState& stencilOpStateBack,
119 const bool colorAttachmentEnable,
120 const bool separateDepthStencilLayouts);
121 virtual ~StencilTest (void);
122 virtual void initPrograms (SourceCollections& sourceCollections) const;
123 virtual void checkSupport (Context& context) const;
124 virtual TestInstance* createInstance (Context& context) const;
125
126 private:
127 VkFormat m_stencilFormat;
128 const VkStencilOpState m_stencilOpStateFront;
129 const VkStencilOpState m_stencilOpStateBack;
130 const bool m_colorAttachmentEnable;
131 const bool m_separateDepthStencilLayouts;
132 };
133
134 class StencilTestInstance : public vkt::TestInstance
135 {
136 public:
137 StencilTestInstance (Context& context,
138 VkFormat stencilFormat,
139 const VkStencilOpState& stencilOpStatesFront,
140 const VkStencilOpState& stencilOpStatesBack,
141 const bool colorAttachmentEnable,
142 const bool separateDepthStencilLayouts);
143 virtual ~StencilTestInstance (void);
144 virtual tcu::TestStatus iterate (void);
145
146 private:
147 tcu::TestStatus verifyImage (void);
148
149 VkStencilOpState m_stencilOpStateFront;
150 VkStencilOpState m_stencilOpStateBack;
151 const bool m_colorAttachmentEnable;
152 const bool m_separateDepthStencilLayouts;
153 const tcu::UVec2 m_renderSize;
154 const VkFormat m_colorFormat;
155 const VkFormat m_stencilFormat;
156 VkImageSubresourceRange m_stencilImageSubresourceRange;
157
158 VkImageCreateInfo m_colorImageCreateInfo;
159 Move<VkImage> m_colorImage;
160 de::MovePtr<Allocation> m_colorImageAlloc;
161 Move<VkImage> m_stencilImage;
162 de::MovePtr<Allocation> m_stencilImageAlloc;
163 Move<VkImageView> m_colorAttachmentView;
164 Move<VkImageView> m_stencilAttachmentView;
165 Move<VkRenderPass> m_renderPass;
166 Move<VkFramebuffer> m_framebuffer;
167
168 Move<VkShaderModule> m_vertexShaderModule;
169 Move<VkShaderModule> m_fragmentShaderModule;
170
171 Move<VkBuffer> m_vertexBuffer;
172 std::vector<Vertex4RGBA> m_vertices;
173 de::MovePtr<Allocation> m_vertexBufferAlloc;
174
175 Move<VkPipelineLayout> m_pipelineLayout;
176 Move<VkPipeline> m_graphicsPipelines[StencilTest::QUAD_COUNT];
177
178 Move<VkCommandPool> m_cmdPool;
179 Move<VkCommandBuffer> m_cmdBuffer;
180 };
181
182 const VkStencilOp stencilOps[] =
183 {
184 VK_STENCIL_OP_KEEP,
185 VK_STENCIL_OP_ZERO,
186 VK_STENCIL_OP_REPLACE,
187 VK_STENCIL_OP_INCREMENT_AND_CLAMP,
188 VK_STENCIL_OP_DECREMENT_AND_CLAMP,
189 VK_STENCIL_OP_INVERT,
190 VK_STENCIL_OP_INCREMENT_AND_WRAP,
191 VK_STENCIL_OP_DECREMENT_AND_WRAP
192 };
193
194 const VkCompareOp compareOps[] =
195 {
196 VK_COMPARE_OP_NEVER,
197 VK_COMPARE_OP_LESS,
198 VK_COMPARE_OP_EQUAL,
199 VK_COMPARE_OP_LESS_OR_EQUAL,
200 VK_COMPARE_OP_GREATER,
201 VK_COMPARE_OP_NOT_EQUAL,
202 VK_COMPARE_OP_GREATER_OR_EQUAL,
203 VK_COMPARE_OP_ALWAYS
204 };
205
206 // StencilOpStateUniqueRandomIterator
207
208 const deUint32 StencilOpStateUniqueRandomIterator::s_stencilOpsLength = DE_LENGTH_OF_ARRAY(stencilOps);
209 const deUint32 StencilOpStateUniqueRandomIterator::s_stencilOpsLength2 = s_stencilOpsLength * s_stencilOpsLength;
210 const deUint32 StencilOpStateUniqueRandomIterator::s_stencilOpsLength3 = s_stencilOpsLength2 * s_stencilOpsLength;
211 const deUint32 StencilOpStateUniqueRandomIterator::s_compareOpsLength = DE_LENGTH_OF_ARRAY(compareOps);
212 const deUint32 StencilOpStateUniqueRandomIterator::s_totalStencilOpStates = s_stencilOpsLength3 * s_compareOpsLength;
213
StencilOpStateUniqueRandomIterator(int seed)214 StencilOpStateUniqueRandomIterator::StencilOpStateUniqueRandomIterator (int seed)
215 : UniqueRandomIterator<VkStencilOpState>(s_totalStencilOpStates, s_totalStencilOpStates, seed)
216 {
217 }
218
getIndexedValue(deUint32 index)219 VkStencilOpState StencilOpStateUniqueRandomIterator::getIndexedValue (deUint32 index)
220 {
221 const deUint32 stencilCompareOpIndex = index / s_stencilOpsLength3;
222 const deUint32 stencilCompareOpSeqIndex = stencilCompareOpIndex * s_stencilOpsLength3;
223
224 const deUint32 stencilDepthFailOpIndex = (index - stencilCompareOpSeqIndex) / s_stencilOpsLength2;
225 const deUint32 stencilDepthFailOpSeqIndex = stencilDepthFailOpIndex * s_stencilOpsLength2;
226
227 const deUint32 stencilPassOpIndex = (index - stencilCompareOpSeqIndex - stencilDepthFailOpSeqIndex) / s_stencilOpsLength;
228 const deUint32 stencilPassOpSeqIndex = stencilPassOpIndex * s_stencilOpsLength;
229
230 const deUint32 stencilFailOpIndex = index - stencilCompareOpSeqIndex - stencilDepthFailOpSeqIndex - stencilPassOpSeqIndex;
231
232 const VkStencilOpState stencilOpState =
233 {
234 stencilOps[stencilFailOpIndex], // VkStencilOp failOp;
235 stencilOps[stencilPassOpIndex], // VkStencilOp passOp;
236 stencilOps[stencilDepthFailOpIndex], // VkStencilOp depthFailOp;
237 compareOps[stencilCompareOpIndex], // VkCompareOp compareOp;
238 0x0, // deUint32 compareMask;
239 0x0, // deUint32 writeMask;
240 0x0 // deUint32 reference;
241 };
242
243 return stencilOpState;
244 }
245
246
247 // StencilTest
248
249 const StencilTest::StencilStateConfig StencilTest::s_stencilStateConfigs[QUAD_COUNT] =
250 {
251 // frontReadMask frontWriteMask frontRef backReadMask backWriteMask backRef
252 { 0xFF, 0xFF, 0xAB, 0xF0, 0xFF, 0xFF },
253 { 0xFF, 0xF0, 0xCD, 0xF0, 0xF0, 0xEF },
254 { 0xF0, 0x0F, 0xEF, 0xFF, 0x0F, 0xCD },
255 { 0xF0, 0x01, 0xFF, 0xFF, 0x01, 0xAB }
256 };
257
258 const float StencilTest::s_quadDepths[QUAD_COUNT] =
259 {
260 0.1f,
261 0.0f,
262 0.3f,
263 0.2f
264 };
265
StencilTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,VkFormat stencilFormat,const VkStencilOpState & stencilOpStateFront,const VkStencilOpState & stencilOpStateBack,const bool colorAttachmentEnable,const bool separateDepthStencilLayouts)266 StencilTest::StencilTest (tcu::TestContext& testContext,
267 const std::string& name,
268 const std::string& description,
269 VkFormat stencilFormat,
270 const VkStencilOpState& stencilOpStateFront,
271 const VkStencilOpState& stencilOpStateBack,
272 const bool colorAttachmentEnable,
273 const bool separateDepthStencilLayouts)
274 : vkt::TestCase (testContext, name, description)
275 , m_stencilFormat (stencilFormat)
276 , m_stencilOpStateFront (stencilOpStateFront)
277 , m_stencilOpStateBack (stencilOpStateBack)
278 , m_colorAttachmentEnable (colorAttachmentEnable)
279 , m_separateDepthStencilLayouts (separateDepthStencilLayouts)
280 {
281 }
282
~StencilTest(void)283 StencilTest::~StencilTest (void)
284 {
285 }
286
checkSupport(Context & context) const287 void StencilTest::checkSupport (Context& context) const
288 {
289 if (!isSupportedDepthStencilFormat(context.getInstanceInterface(), context.getPhysicalDevice(), m_stencilFormat))
290 throw tcu::NotSupportedError(std::string("Unsupported depth/stencil format: ") + getFormatName(m_stencilFormat));
291
292 if (m_separateDepthStencilLayouts && !context.isDeviceFunctionalitySupported("VK_KHR_separate_depth_stencil_layouts"))
293 TCU_THROW(NotSupportedError, "VK_KHR_separate_depth_stencil_layouts is not supported");
294 }
295
createInstance(Context & context) const296 TestInstance* StencilTest::createInstance (Context& context) const
297 {
298 return new StencilTestInstance(context, m_stencilFormat, m_stencilOpStateFront, m_stencilOpStateBack, m_colorAttachmentEnable, m_separateDepthStencilLayouts);
299 }
300
initPrograms(SourceCollections & sourceCollections) const301 void StencilTest::initPrograms (SourceCollections& sourceCollections) const
302 {
303 if (m_colorAttachmentEnable)
304 {
305 sourceCollections.glslSources.add("color_vert") << glu::VertexSource(
306 "#version 310 es\n"
307 "layout(location = 0) in vec4 position;\n"
308 "layout(location = 1) in vec4 color;\n"
309 "layout(location = 0) out highp vec4 vtxColor;\n"
310 "void main (void)\n"
311 "{\n"
312 " gl_Position = position;\n"
313 " vtxColor = color;\n"
314 "}\n");
315
316 sourceCollections.glslSources.add("color_frag") << glu::FragmentSource(
317 "#version 310 es\n"
318 "layout(location = 0) in highp vec4 vtxColor;\n"
319 "layout(location = 0) out highp vec4 fragColor;\n"
320 "void main (void)\n"
321 "{\n"
322 " fragColor = vtxColor;\n"
323 "}\n");
324 }
325 else
326 {
327 sourceCollections.glslSources.add("color_vert") << glu::VertexSource(
328 "#version 310 es\n"
329 "layout(location = 0) in vec4 position;\n"
330 "layout(location = 1) in vec4 color;\n"
331 "void main (void)\n"
332 "{\n"
333 " gl_Position = position;\n"
334 "}\n");
335
336 sourceCollections.glslSources.add("color_frag") << glu::FragmentSource(
337 "#version 310 es\n"
338 "void main (void)\n"
339 "{\n"
340 "}\n");
341 }
342 }
343
344
345 // StencilTestInstance
346
StencilTestInstance(Context & context,VkFormat stencilFormat,const VkStencilOpState & stencilOpStateFront,const VkStencilOpState & stencilOpStateBack,const bool colorAttachmentEnable,const bool separateDepthStencilLayouts)347 StencilTestInstance::StencilTestInstance (Context& context,
348 VkFormat stencilFormat,
349 const VkStencilOpState& stencilOpStateFront,
350 const VkStencilOpState& stencilOpStateBack,
351 const bool colorAttachmentEnable,
352 const bool separateDepthStencilLayouts)
353 : vkt::TestInstance (context)
354 , m_stencilOpStateFront (stencilOpStateFront)
355 , m_stencilOpStateBack (stencilOpStateBack)
356 , m_colorAttachmentEnable (colorAttachmentEnable)
357 , m_separateDepthStencilLayouts (separateDepthStencilLayouts)
358 , m_renderSize (32, 32)
359 , m_colorFormat (colorAttachmentEnable ? VK_FORMAT_R8G8B8A8_UNORM : VK_FORMAT_UNDEFINED)
360 , m_stencilFormat (stencilFormat)
361 {
362 const DeviceInterface& vk = context.getDeviceInterface();
363 const VkDevice vkDevice = context.getDevice();
364 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
365 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
366 const VkComponentMapping componentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
367
368 // Create color image
369 if (m_colorAttachmentEnable)
370 {
371 const VkImageCreateInfo colorImageParams =
372 {
373 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
374 DE_NULL, // const void* pNext;
375 0u, // VkImageCreateFlags flags;
376 VK_IMAGE_TYPE_2D, // VkImageType imageType;
377 m_colorFormat, // VkFormat format;
378 { m_renderSize.x(), m_renderSize.y(), 1u }, // VkExtent3D extent;
379 1u, // deUint32 mipLevels;
380 1u, // deUint32 arrayLayers;
381 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
382 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
383 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
384 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
385 1u, // deUint32 queueFamilyIndexCount;
386 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
387 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
388 };
389
390 m_colorImageCreateInfo = colorImageParams;
391 m_colorImage = createImage(vk, vkDevice, &m_colorImageCreateInfo);
392
393 // Allocate and bind color image memory
394 m_colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
395 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
396 }
397
398 // Create stencil image
399 {
400 const VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
401
402 const VkImageCreateInfo stencilImageParams =
403 {
404 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
405 DE_NULL, // const void* pNext;
406 0u, // VkImageCreateFlags flags;
407 VK_IMAGE_TYPE_2D, // VkImageType imageType;
408 m_stencilFormat, // VkFormat format;
409 { m_renderSize.x(), m_renderSize.y(), 1u }, // VkExtent3D extent;
410 1u, // deUint32 mipLevels;
411 1u, // deUint32 arrayLayers;
412 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
413 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
414 usageFlags, // VkImageUsageFlags usage;
415 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
416 1u, // deUint32 queueFamilyIndexCount;
417 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
418 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
419 };
420
421 m_stencilImage = createImage(vk, vkDevice, &stencilImageParams);
422
423 // Allocate and bind stencil image memory
424 m_stencilImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_stencilImage), MemoryRequirement::Any);
425 VK_CHECK(vk.bindImageMemory(vkDevice, *m_stencilImage, m_stencilImageAlloc->getMemory(), m_stencilImageAlloc->getOffset()));
426
427 const VkImageAspectFlags aspect = (mapVkFormat(m_stencilFormat).order == tcu::TextureFormat::DS ? VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT
428 : VK_IMAGE_ASPECT_STENCIL_BIT);
429 m_stencilImageSubresourceRange = makeImageSubresourceRange(aspect, 0u, stencilImageParams.mipLevels, 0u, stencilImageParams.arrayLayers);
430 }
431
432 // Create color attachment view
433 if (m_colorAttachmentEnable)
434 {
435 const VkImageViewCreateInfo colorAttachmentViewParams =
436 {
437 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
438 DE_NULL, // const void* pNext;
439 0u, // VkImageViewCreateFlags flags;
440 *m_colorImage, // VkImage image;
441 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
442 m_colorFormat, // VkFormat format;
443 componentMappingRGBA, // VkComponentMapping components;
444 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange;
445 };
446
447 m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
448 }
449
450 // Create stencil attachment view
451 {
452 const VkImageViewCreateInfo stencilAttachmentViewParams =
453 {
454 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
455 DE_NULL, // const void* pNext;
456 0u, // VkImageViewCreateFlags flags;
457 *m_stencilImage, // VkImage image;
458 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
459 m_stencilFormat, // VkFormat format;
460 componentMappingRGBA, // VkComponentMapping components;
461 m_stencilImageSubresourceRange, // VkImageSubresourceRange subresourceRange;
462 };
463
464 m_stencilAttachmentView = createImageView(vk, vkDevice, &stencilAttachmentViewParams);
465 }
466
467 // Create render pass
468 m_renderPass = makeRenderPass(vk, vkDevice, m_colorFormat, m_stencilFormat);
469
470 // Create framebuffer
471 {
472 std::vector<VkImageView> attachmentBindInfos;
473
474 if (m_colorAttachmentEnable)
475 attachmentBindInfos.push_back(*m_colorAttachmentView);
476
477 attachmentBindInfos.push_back(*m_stencilAttachmentView);
478
479 const VkFramebufferCreateInfo framebufferParams =
480 {
481 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
482 DE_NULL, // const void* pNext;
483 0u, // VkFramebufferCreateFlags flags;
484 *m_renderPass, // VkRenderPass renderPass;
485 (deUint32)attachmentBindInfos.size(), // deUint32 attachmentCount;
486 attachmentBindInfos.data(), // const VkImageView* pAttachments;
487 (deUint32)m_renderSize.x(), // deUint32 width;
488 (deUint32)m_renderSize.y(), // deUint32 height;
489 1u // deUint32 layers;
490 };
491
492 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
493 }
494
495 // Create pipeline layout
496 {
497 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
498 {
499 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
500 DE_NULL, // const void* pNext;
501 0u, // VkPipelineLayoutCreateFlags flags;
502 0u, // deUint32 setLayoutCount;
503 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
504 0u, // deUint32 pushConstantRangeCount;
505 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
506 };
507
508 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
509 }
510
511 m_vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0);
512 m_fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0);
513
514 // Create pipeline
515 {
516 const VkVertexInputBindingDescription vertexInputBindingDescription =
517 {
518 0u, // deUint32 binding;
519 sizeof(Vertex4RGBA), // deUint32 strideInBytes;
520 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate inputRate;
521 };
522
523 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
524 {
525 {
526 0u, // deUint32 location;
527 0u, // deUint32 binding;
528 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
529 0u // deUint32 offsetInBytes;
530 },
531 {
532 1u, // deUint32 location;
533 0u, // deUint32 binding;
534 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
535 DE_OFFSET_OF(Vertex4RGBA, color), // deUint32 offsetInBytes;
536 }
537 };
538
539 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
540 {
541 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
542 DE_NULL, // const void* pNext;
543 0u, // VkPipelineVertexInputStateCreateFlags flags;
544 1u, // deUint32 vertexBindingDescriptionCount;
545 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
546 2u, // deUint32 vertexAttributeDescriptionCount;
547 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
548 };
549
550 const std::vector<VkViewport> viewports (1, makeViewport(m_renderSize));
551 const std::vector<VkRect2D> scissors (1, makeRect2D(m_renderSize));
552
553 const bool isDepthEnabled = (vk::mapVkFormat(m_stencilFormat).order != tcu::TextureFormat::S);
554
555 VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
556 {
557 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
558 DE_NULL, // const void* pNext;
559 0u, // VkPipelineDepthStencilStateCreateFlags flags;
560 isDepthEnabled, // VkBool32 depthTestEnable;
561 isDepthEnabled, // VkBool32 depthWriteEnable;
562 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp;
563 false, // VkBool32 depthBoundsTestEnable;
564 true, // VkBool32 stencilTestEnable;
565 m_stencilOpStateFront, // VkStencilOpState front;
566 m_stencilOpStateBack, // VkStencilOpState back;
567 0.0f, // float minDepthBounds;
568 1.0f // float maxDepthBounds;
569 };
570
571 // Setup different stencil masks and refs in each quad
572 for (int quadNdx = 0; quadNdx < StencilTest::QUAD_COUNT; quadNdx++)
573 {
574 const StencilTest::StencilStateConfig& config = StencilTest::s_stencilStateConfigs[quadNdx];
575 VkStencilOpState& front = depthStencilStateParams.front;
576 VkStencilOpState& back = depthStencilStateParams.back;
577
578 front.compareMask = config.frontReadMask;
579 front.writeMask = config.frontWriteMask;
580 front.reference = config.frontRef;
581
582 back.compareMask = config.backReadMask;
583 back.writeMask = config.backWriteMask;
584 back.reference = config.backRef;
585
586 m_graphicsPipelines[quadNdx] = makeGraphicsPipeline(vk, // const DeviceInterface& vk
587 vkDevice, // const VkDevice device
588 *m_pipelineLayout, // const VkPipelineLayout pipelineLayout
589 *m_vertexShaderModule, // const VkShaderModule vertexShaderModule
590 DE_NULL, // const VkShaderModule tessellationControlModule
591 DE_NULL, // const VkShaderModule tessellationEvalModule
592 DE_NULL, // const VkShaderModule geometryShaderModule
593 *m_fragmentShaderModule, // const VkShaderModule fragmentShaderModule
594 *m_renderPass, // const VkRenderPass renderPass
595 viewports, // const std::vector<VkViewport>& viewports
596 scissors, // const std::vector<VkRect2D>& scissors
597 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
598 0u, // const deUint32 subpass
599 0u, // const deUint32 patchControlPoints
600 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
601 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
602 DE_NULL, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
603 &depthStencilStateParams); // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
604 }
605 }
606
607
608 // Create vertex buffer
609 {
610 const VkBufferCreateInfo vertexBufferParams =
611 {
612 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
613 DE_NULL, // const void* pNext;
614 0u, // VkBufferCreateFlags flags;
615 1024u, // VkDeviceSize size;
616 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
617 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
618 1u, // deUint32 queueFamilyIndexCount;
619 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
620 };
621
622 m_vertices = createOverlappingQuads();
623 m_vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
624 m_vertexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);
625
626 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
627
628 // Adjust depths
629 for (int quadNdx = 0; quadNdx < 4; quadNdx++)
630 for (int vertexNdx = 0; vertexNdx < 6; vertexNdx++)
631 m_vertices[quadNdx * 6 + vertexNdx].position.z() = StencilTest::s_quadDepths[quadNdx];
632
633 // Load vertices into vertex buffer
634 deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
635 flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
636 }
637
638 // Create command pool
639 m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
640
641 // Create command buffer
642 {
643 const VkImageMemoryBarrier colorImageBarrier =
644 {
645 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
646 DE_NULL, // const void* pNext;
647 (VkAccessFlags)0, // VkAccessFlags srcAccessMask;
648 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
649 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
650 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
651 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
652 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
653 *m_colorImage, // VkImage image;
654 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange;
655 };
656
657 VkImageSubresourceRange stencilImageBarrierSubresourceRange = m_stencilImageSubresourceRange;
658 VkImageLayout newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
659 if (m_separateDepthStencilLayouts)
660 {
661 stencilImageBarrierSubresourceRange.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
662 newLayout = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR;
663 }
664
665 const VkImageMemoryBarrier stencilImageBarrier =
666 {
667 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
668 DE_NULL, // const void* pNext;
669 (VkAccessFlags)0, // VkAccessFlags srcAccessMask;
670 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
671 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
672 newLayout, // VkImageLayout newLayout;
673 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
674 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
675 *m_stencilImage, // VkImage image;
676 stencilImageBarrierSubresourceRange, // VkImageSubresourceRange subresourceRange;
677 };
678
679 std::vector<VkClearValue> attachmentClearValues;
680 std::vector<VkImageMemoryBarrier> imageLayoutBarriers;
681
682 if (m_colorAttachmentEnable)
683 {
684 attachmentClearValues.push_back(defaultClearValue(m_colorFormat));
685 imageLayoutBarriers.push_back(colorImageBarrier);
686 }
687
688 attachmentClearValues.push_back(defaultClearValue(m_stencilFormat));
689 imageLayoutBarriers.push_back(stencilImageBarrier);
690
691 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
692
693 beginCommandBuffer(vk, *m_cmdBuffer, 0u);
694
695 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, (VkDependencyFlags)0,
696 0u, DE_NULL, 0u, DE_NULL, (deUint32)imageLayoutBarriers.size(), imageLayoutBarriers.data());
697
698 beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), (deUint32)attachmentClearValues.size(), attachmentClearValues.data());
699
700 const VkDeviceSize quadOffset = (m_vertices.size() / StencilTest::QUAD_COUNT) * sizeof(Vertex4RGBA);
701
702 for (int quadNdx = 0; quadNdx < StencilTest::QUAD_COUNT; quadNdx++)
703 {
704 VkDeviceSize vertexBufferOffset = quadOffset * quadNdx;
705
706 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines[quadNdx]);
707 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
708 vk.cmdDraw(*m_cmdBuffer, (deUint32)(m_vertices.size() / StencilTest::QUAD_COUNT), 1, 0, 0);
709 }
710
711 endRenderPass(vk, *m_cmdBuffer);
712 endCommandBuffer(vk, *m_cmdBuffer);
713 }
714 }
715
~StencilTestInstance(void)716 StencilTestInstance::~StencilTestInstance (void)
717 {
718 }
719
iterate(void)720 tcu::TestStatus StencilTestInstance::iterate (void)
721 {
722 const DeviceInterface& vk = m_context.getDeviceInterface();
723 const VkDevice vkDevice = m_context.getDevice();
724 const VkQueue queue = m_context.getUniversalQueue();
725
726 submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
727
728 return verifyImage();
729 }
730
verifyImage(void)731 tcu::TestStatus StencilTestInstance::verifyImage (void)
732 {
733 const tcu::TextureFormat tcuColorFormat = mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM);
734 const tcu::TextureFormat tcuStencilFormat = mapVkFormat(m_stencilFormat);
735 const ColorVertexShader vertexShader;
736 const ColorFragmentShader fragmentShader (tcuColorFormat, tcuStencilFormat);
737 const rr::Program program (&vertexShader, &fragmentShader);
738 ReferenceRenderer refRenderer (m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuStencilFormat, &program);
739 bool colorCompareOk = false;
740 bool stencilCompareOk = false;
741
742 // Render reference image
743 {
744 // Set depth state
745 rr::RenderState renderState(refRenderer.getViewportState(), m_context.getDeviceProperties().limits.subPixelPrecisionBits);
746
747 renderState.fragOps.depthTestEnabled = true;
748 renderState.fragOps.depthFunc = mapVkCompareOp(VK_COMPARE_OP_LESS);
749 renderState.fragOps.stencilTestEnabled = true;
750
751 rr::StencilState& refStencilFront = renderState.fragOps.stencilStates[rr::FACETYPE_FRONT];
752 rr::StencilState& refStencilBack = renderState.fragOps.stencilStates[rr::FACETYPE_BACK];
753
754 refStencilFront.sFail = mapVkStencilOp(m_stencilOpStateFront.failOp);
755 refStencilFront.dpFail = mapVkStencilOp(m_stencilOpStateFront.depthFailOp);
756 refStencilFront.dpPass = mapVkStencilOp(m_stencilOpStateFront.passOp);
757 refStencilFront.func = mapVkCompareOp(m_stencilOpStateFront.compareOp);
758
759 refStencilBack.sFail = mapVkStencilOp(m_stencilOpStateBack.failOp);
760 refStencilBack.dpPass = mapVkStencilOp(m_stencilOpStateBack.passOp);
761 refStencilBack.dpFail = mapVkStencilOp(m_stencilOpStateBack.depthFailOp);
762 refStencilBack.func = mapVkCompareOp(m_stencilOpStateBack.compareOp);
763
764 // Reverse winding of vertices, as Vulkan screen coordinates start at upper left
765 std::vector<Vertex4RGBA> cwVertices(m_vertices);
766 for (size_t vertexNdx = 0; vertexNdx < cwVertices.size() - 2; vertexNdx += 3)
767 {
768 const Vertex4RGBA cwVertex1 = cwVertices[vertexNdx + 1];
769
770 cwVertices[vertexNdx + 1] = cwVertices[vertexNdx + 2];
771 cwVertices[vertexNdx + 2] = cwVertex1;
772 }
773
774 for (int quadNdx = 0; quadNdx < StencilTest::QUAD_COUNT; quadNdx++)
775 {
776 refStencilFront.ref = (int)StencilTest::s_stencilStateConfigs[quadNdx].frontRef;
777 refStencilFront.compMask = StencilTest::s_stencilStateConfigs[quadNdx].frontReadMask;
778 refStencilFront.writeMask = StencilTest::s_stencilStateConfigs[quadNdx].frontWriteMask;
779
780 refStencilBack.ref = (int)StencilTest::s_stencilStateConfigs[quadNdx].backRef;
781 refStencilBack.compMask = StencilTest::s_stencilStateConfigs[quadNdx].backReadMask;
782 refStencilBack.writeMask = StencilTest::s_stencilStateConfigs[quadNdx].backWriteMask;
783
784 refRenderer.draw(renderState,
785 rr::PRIMITIVETYPE_TRIANGLES,
786 std::vector<Vertex4RGBA>(cwVertices.begin() + quadNdx * 6,
787 cwVertices.begin() + (quadNdx + 1) * 6));
788 }
789 }
790
791 // Compare result with reference image
792 if (m_colorAttachmentEnable)
793 {
794 const DeviceInterface& vk = m_context.getDeviceInterface();
795 const VkDevice vkDevice = m_context.getDevice();
796 const VkQueue queue = m_context.getUniversalQueue();
797 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
798 SimpleAllocator allocator (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
799 de::UniquePtr<tcu::TextureLevel> result (readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImage, m_colorFormat, m_renderSize).release());
800
801 colorCompareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
802 "IntImageCompare",
803 "Image comparison",
804 refRenderer.getAccess(),
805 result->getAccess(),
806 tcu::UVec4(2, 2, 2, 2),
807 tcu::IVec3(1, 1, 0),
808 true,
809 tcu::COMPARE_LOG_RESULT);
810 }
811 else
812 {
813 colorCompareOk = true;
814 }
815
816 // Compare stencil result with reference image
817 {
818 const DeviceInterface& vk = m_context.getDeviceInterface();
819 const VkDevice vkDevice = m_context.getDevice();
820 const VkQueue queue = m_context.getUniversalQueue();
821 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
822 SimpleAllocator allocator (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
823 de::UniquePtr<tcu::TextureLevel> result (readStencilAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_stencilImage, m_stencilFormat, m_renderSize).release());
824
825 {
826 const tcu::PixelBufferAccess stencilAccess (tcu::getEffectiveDepthStencilAccess(refRenderer.getDepthStencilAccess(), tcu::Sampler::MODE_STENCIL));
827 stencilCompareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
828 "StencilImageCompare",
829 "Stencil image comparison",
830 stencilAccess,
831 result->getAccess(),
832 tcu::UVec4(2, 2, 2, 2),
833 tcu::IVec3(1, 1, 0),
834 true,
835 tcu::COMPARE_LOG_RESULT);
836 }
837 }
838
839 if (colorCompareOk && stencilCompareOk)
840 return tcu::TestStatus::pass("Result image matches reference");
841 else
842 return tcu::TestStatus::fail("Image mismatch");
843 }
844
845
846 // Utilities for test names
847
getShortName(VkStencilOp stencilOp)848 const char* getShortName (VkStencilOp stencilOp)
849 {
850 switch (stencilOp)
851 {
852 case VK_STENCIL_OP_KEEP: return "keep";
853 case VK_STENCIL_OP_ZERO: return "zero";
854 case VK_STENCIL_OP_REPLACE: return "repl";
855 case VK_STENCIL_OP_INCREMENT_AND_CLAMP: return "incc";
856 case VK_STENCIL_OP_DECREMENT_AND_CLAMP: return "decc";
857 case VK_STENCIL_OP_INVERT: return "inv";
858 case VK_STENCIL_OP_INCREMENT_AND_WRAP: return "wrap";
859 case VK_STENCIL_OP_DECREMENT_AND_WRAP: return "decw";
860
861 default:
862 DE_FATAL("Invalid VkStencilOpState value");
863 }
864 return DE_NULL;
865 }
866
getStencilStateSetDescription(const VkStencilOpState & stencilOpStateFront,const VkStencilOpState & stencilOpStateBack)867 std::string getStencilStateSetDescription(const VkStencilOpState& stencilOpStateFront,
868 const VkStencilOpState& stencilOpStateBack)
869 {
870 std::ostringstream desc;
871
872 desc << "\nFront faces:\n" << stencilOpStateFront;
873 desc << "Back faces:\n" << stencilOpStateBack;
874
875 return desc.str();
876 }
877
getFormatCaseName(VkFormat format)878 std::string getFormatCaseName (VkFormat format)
879 {
880 const std::string fullName = getFormatName(format);
881
882 DE_ASSERT(de::beginsWith(fullName, "VK_FORMAT_"));
883
884 return de::toLower(fullName.substr(10));
885 }
886
887 } // anonymous
888
createStencilTests(tcu::TestContext & testCtx)889 tcu::TestCaseGroup* createStencilTests (tcu::TestContext& testCtx)
890 {
891 const VkFormat stencilFormats[] =
892 {
893 VK_FORMAT_S8_UINT,
894 VK_FORMAT_D16_UNORM_S8_UINT,
895 VK_FORMAT_D24_UNORM_S8_UINT,
896 VK_FORMAT_D32_SFLOAT_S8_UINT
897 };
898
899 DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(compareOps) == 8);
900 DE_STATIC_ASSERT(vk::VK_COMPARE_OP_LAST == 8);
901
902 static const char* compareOpNames[8] =
903 {
904 "comp_never",
905 "comp_less",
906 "comp_equal",
907 "comp_less_or_equal",
908 "comp_greater",
909 "comp_not_equal",
910 "comp_greater_or_equal",
911 "comp_always"
912 };
913
914 de::MovePtr<tcu::TestCaseGroup> stencilTests (new tcu::TestCaseGroup(testCtx, "stencil", "Stencil tests"));
915 de::MovePtr<tcu::TestCaseGroup> noColorAttachmentTests (new tcu::TestCaseGroup(testCtx, "nocolor", "Stencil tests with no color attachment"));
916 const bool colorAttachmentEnabled[] = { true, false };
917
918 for (deUint32 colorAttachmentEnabledIdx = 0; colorAttachmentEnabledIdx < DE_LENGTH_OF_ARRAY(colorAttachmentEnabled); colorAttachmentEnabledIdx++)
919 {
920 const bool colorEnabled = colorAttachmentEnabled[colorAttachmentEnabledIdx];
921 de::MovePtr<tcu::TestCaseGroup> formatTests (new tcu::TestCaseGroup(testCtx, "format", "Uses different stencil formats"));
922 StencilOpStateUniqueRandomIterator stencilOpItr (123);
923
924 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(stencilFormats); formatNdx++)
925 {
926 const VkFormat stencilFormat = stencilFormats[formatNdx];
927 const bool hasDepth = tcu::hasDepthComponent(mapVkFormat(stencilFormat).order);
928 const bool hasStencil = tcu::hasStencilComponent(mapVkFormat(stencilFormat).order);
929 const int separateLayoutsLoopCount = (hasDepth && hasStencil) ? 2 : 1;
930
931 for (int separateDepthStencilLayouts = 0; separateDepthStencilLayouts < separateLayoutsLoopCount; ++separateDepthStencilLayouts)
932 {
933 const bool useSeparateDepthStencilLayouts = bool(separateDepthStencilLayouts);
934
935 de::MovePtr<tcu::TestCaseGroup> formatTest (new tcu::TestCaseGroup(testCtx,
936 (getFormatCaseName(stencilFormat) + ((useSeparateDepthStencilLayouts) ? "_separate_layouts" : "")).c_str(),
937 (std::string("Uses format ") + getFormatName(stencilFormat) + ((useSeparateDepthStencilLayouts) ? " with separate depth/stencil layouts" : "")).c_str()));
938
939 de::MovePtr<tcu::TestCaseGroup> stencilStateTests;
940 {
941 std::ostringstream desc;
942 desc << "Draws 4 quads with the following depths and dynamic stencil states: ";
943
944 for (int quadNdx = 0; quadNdx < StencilTest::QUAD_COUNT; quadNdx++)
945 {
946 const StencilTest::StencilStateConfig& stencilConfig = StencilTest::s_stencilStateConfigs[quadNdx];
947
948 desc << "(" << quadNdx << ") "
949 << "z = " << StencilTest::s_quadDepths[quadNdx] << ", "
950 << "frontReadMask = " << stencilConfig.frontReadMask << ", "
951 << "frontWriteMask = " << stencilConfig.frontWriteMask << ", "
952 << "frontRef = " << stencilConfig.frontRef << ", "
953 << "backReadMask = " << stencilConfig.backReadMask << ", "
954 << "backWriteMask = " << stencilConfig.backWriteMask << ", "
955 << "backRef = " << stencilConfig.backRef;
956 }
957
958 stencilStateTests = de::MovePtr<tcu::TestCaseGroup>(new tcu::TestCaseGroup(testCtx, "states", desc.str().c_str()));
959 }
960
961 stencilOpItr.reset();
962
963 for (deUint32 failOpNdx = 0u; failOpNdx < DE_LENGTH_OF_ARRAY(stencilOps); failOpNdx++)
964 {
965 const std::string failOpName = std::string("fail_") + getShortName(stencilOps[failOpNdx]);
966 de::MovePtr<tcu::TestCaseGroup> failOpTest (new tcu::TestCaseGroup(testCtx, failOpName.c_str(), ""));
967
968 for (deUint32 passOpNdx = 0u; passOpNdx < DE_LENGTH_OF_ARRAY(stencilOps); passOpNdx++)
969 {
970 const std::string passOpName = std::string("pass_") + getShortName(stencilOps[passOpNdx]);
971 de::MovePtr<tcu::TestCaseGroup> passOpTest (new tcu::TestCaseGroup(testCtx, passOpName.c_str(), ""));
972
973 for (deUint32 dFailOpNdx = 0u; dFailOpNdx < DE_LENGTH_OF_ARRAY(stencilOps); dFailOpNdx++)
974 {
975 const std::string dFailOpName = std::string("dfail_") + getShortName(stencilOps[dFailOpNdx]);
976 de::MovePtr<tcu::TestCaseGroup> dFailOpTest (new tcu::TestCaseGroup(testCtx, dFailOpName.c_str(), ""));
977
978 for (deUint32 compareOpNdx = 0u; compareOpNdx < DE_LENGTH_OF_ARRAY(compareOps); compareOpNdx++)
979 {
980 // Iterate front set of stencil state in ascending order
981 const VkStencilOpState stencilStateFront =
982 {
983 stencilOps[failOpNdx], // failOp
984 stencilOps[passOpNdx], // passOp
985 stencilOps[dFailOpNdx], // depthFailOp
986 compareOps[compareOpNdx], // compareOp
987 0x0, // compareMask
988 0x0, // writeMask
989 0x0 // reference
990 };
991
992 // Iterate back set of stencil state in random order
993 const VkStencilOpState stencilStateBack = stencilOpItr.next();
994 const std::string caseName = compareOpNames[compareOpNdx];
995 const std::string caseDesc = getStencilStateSetDescription(stencilStateFront, stencilStateBack);
996
997 dFailOpTest->addChild(new StencilTest(testCtx, caseName, caseDesc, stencilFormat, stencilStateFront, stencilStateBack, colorEnabled, useSeparateDepthStencilLayouts));
998 }
999 passOpTest->addChild(dFailOpTest.release());
1000 }
1001 failOpTest->addChild(passOpTest.release());
1002 }
1003 stencilStateTests->addChild(failOpTest.release());
1004 }
1005
1006 formatTest->addChild(stencilStateTests.release());
1007 formatTests->addChild(formatTest.release());
1008 }
1009 }
1010
1011 if (colorEnabled)
1012 stencilTests->addChild(formatTests.release());
1013 else
1014 noColorAttachmentTests->addChild(formatTests.release());
1015 }
1016
1017 stencilTests->addChild(noColorAttachmentTests.release());
1018
1019 return stencilTests.release();
1020 }
1021
1022 } // pipeline
1023 } // vkt
1024