4f479f8e461d3f4bf8c7a94769d2292ce4820643
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / dynamic_state / vktDynamicStateDSTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 The Khronos Group Inc.
6  * Copyright (c) 2015 Intel Corporation
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 Dynamic State Depth Stencil Tests
23  *//*--------------------------------------------------------------------*/
24
25 #include "vktDynamicStateDSTests.hpp"
26
27 #include "vktTestCaseUtil.hpp"
28 #include "vktDynamicStateTestCaseUtil.hpp"
29
30 #include "tcuTestLog.hpp"
31 #include "tcuResource.hpp"
32 #include "tcuImageCompare.hpp"
33 #include "tcuCommandLine.hpp"
34 #include "tcuTextureUtil.hpp"
35 #include "tcuRGBA.hpp"
36
37 #include "vkRefUtil.hpp"
38 #include "vkImageUtil.hpp"
39
40 #include "vktDynamicStateCreateInfoUtil.hpp"
41 #include "vktDynamicStateImageObjectUtil.hpp"
42 #include "vktDynamicStateBufferObjectUtil.hpp"
43 #include "vkPrograms.hpp"
44
45 namespace vkt
46 {
47 namespace DynamicState
48 {
49
50 namespace
51 {
52
53 class DepthStencilBaseCase : public TestInstance
54 {
55 public:
56         DepthStencilBaseCase (Context& context, const char* vertexShaderName, const char* fragmentShaderName)
57                 : TestInstance                                          (context)
58                 , m_colorAttachmentFormat                       (vk::VK_FORMAT_R8G8B8A8_UNORM)
59                 , m_topology                                            (vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
60                 , m_vk                                                          (context.getDeviceInterface())
61                 , m_vertexShaderName                            (vertexShaderName)
62                 , m_fragmentShaderName                          (fragmentShaderName)
63         {
64         }
65
66 protected:
67
68         enum
69         {
70                 WIDTH   = 128,
71                 HEIGHT  = 128
72         };
73
74         vk::VkFormat                                                                    m_colorAttachmentFormat;
75         vk::VkFormat                                                                    m_depthStencilAttachmentFormat;
76
77         vk::VkPrimitiveTopology                                                 m_topology;
78
79         const vk::DeviceInterface&                                              m_vk;
80
81         vk::Move<vk::VkPipeline>                                                m_pipeline_1;
82         vk::Move<vk::VkPipeline>                                                m_pipeline_2;
83         vk::Move<vk::VkPipelineLayout>                                  m_pipelineLayout;
84
85         de::SharedPtr<Image>                                                    m_colorTargetImage;
86         vk::Move<vk::VkImageView>                                               m_colorTargetView;
87
88         de::SharedPtr<Image>                                                    m_depthStencilImage;
89         vk::Move<vk::VkImageView>                                               m_attachmentView;
90
91         PipelineCreateInfo::VertexInputState                    m_vertexInputState;
92         de::SharedPtr<Buffer>                                                   m_vertexBuffer;
93
94         vk::Move<vk::VkCommandPool>                                             m_cmdPool;
95         vk::Move<vk::VkCommandBuffer>                                   m_cmdBuffer;
96
97         vk::Move<vk::VkFramebuffer>                                             m_framebuffer;
98         vk::Move<vk::VkRenderPass>                                              m_renderPass;
99
100         const std::string                                                               m_vertexShaderName;
101         const std::string                                                               m_fragmentShaderName;
102
103         std::vector<PositionColorVertex>                                m_data;
104
105         PipelineCreateInfo::DepthStencilState                   m_depthStencilState_1;
106         PipelineCreateInfo::DepthStencilState                   m_depthStencilState_2;
107
108         void initialize (void)
109         {
110                 const vk::VkDevice device = m_context.getDevice();
111
112                 vk::VkFormatProperties formatProperties;
113                 // check for VK_FORMAT_D24_UNORM_S8_UINT support
114                 m_context.getInstanceInterface().getPhysicalDeviceFormatProperties(m_context.getPhysicalDevice(), vk::VK_FORMAT_D24_UNORM_S8_UINT, &formatProperties);
115                 if (formatProperties.optimalTilingFeatures & vk::VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
116                 {
117                         m_depthStencilAttachmentFormat = vk::VK_FORMAT_D24_UNORM_S8_UINT;
118                 }
119                 else
120                 {
121                         // check for VK_FORMAT_D32_SFLOAT_S8_UINT support
122                         m_context.getInstanceInterface().getPhysicalDeviceFormatProperties(m_context.getPhysicalDevice(), vk::VK_FORMAT_D32_SFLOAT_S8_UINT, &formatProperties);
123                         if (formatProperties.optimalTilingFeatures & vk::VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
124                         {
125                                 m_depthStencilAttachmentFormat = vk::VK_FORMAT_D32_SFLOAT_S8_UINT;
126                         }
127                         else
128                                 throw tcu::NotSupportedError("No valid depth stencil attachment available");
129                 }
130
131                 const PipelineLayoutCreateInfo pipelineLayoutCreateInfo;
132                 m_pipelineLayout = vk::createPipelineLayout(m_vk, device, &pipelineLayoutCreateInfo);
133
134                 const vk::Unique<vk::VkShaderModule> vs(createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_vertexShaderName), 0));
135                 const vk::Unique<vk::VkShaderModule> fs(createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_fragmentShaderName), 0));
136
137                 const vk::VkExtent3D imageExtent = { WIDTH, HEIGHT, 1 };
138                 const ImageCreateInfo targetImageCreateInfo(vk::VK_IMAGE_TYPE_2D, m_colorAttachmentFormat, imageExtent, 1, 1, vk::VK_SAMPLE_COUNT_1_BIT,
139                                                                                                         vk::VK_IMAGE_TILING_OPTIMAL,
140                                                                                                         vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
141                                                                                                         vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
142                                                                                                         vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
143
144                 m_colorTargetImage = Image::createAndAlloc(m_vk, device, targetImageCreateInfo, m_context.getDefaultAllocator());
145
146                 const ImageCreateInfo depthStencilImageCreateInfo(vk::VK_IMAGE_TYPE_2D, m_depthStencilAttachmentFormat, imageExtent,
147                                                                                                                   1, 1, vk::VK_SAMPLE_COUNT_1_BIT, vk::VK_IMAGE_TILING_OPTIMAL,
148                                                                                                                   vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
149                                                                                                                   vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
150
151                 m_depthStencilImage = Image::createAndAlloc(m_vk, device, depthStencilImageCreateInfo, m_context.getDefaultAllocator());
152
153                 const ImageViewCreateInfo colorTargetViewInfo(m_colorTargetImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, m_colorAttachmentFormat);
154                 m_colorTargetView = vk::createImageView(m_vk, device, &colorTargetViewInfo);
155
156                 const ImageViewCreateInfo attachmentViewInfo(m_depthStencilImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, m_depthStencilAttachmentFormat);
157                 m_attachmentView = vk::createImageView(m_vk, device, &attachmentViewInfo);
158
159                 RenderPassCreateInfo renderPassCreateInfo;
160                 renderPassCreateInfo.addAttachment(AttachmentDescription(m_colorAttachmentFormat,
161                                                                                                                                  vk::VK_SAMPLE_COUNT_1_BIT,
162                                                                                                                                  vk::VK_ATTACHMENT_LOAD_OP_LOAD,
163                                                                                                                                  vk::VK_ATTACHMENT_STORE_OP_STORE,
164                                                                                                                                  vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
165                                                                                                                                  vk::VK_ATTACHMENT_STORE_OP_STORE,
166                                                                                                                                  vk::VK_IMAGE_LAYOUT_GENERAL,
167                                                                                                                                  vk::VK_IMAGE_LAYOUT_GENERAL));
168
169                 renderPassCreateInfo.addAttachment(AttachmentDescription(m_depthStencilAttachmentFormat,
170                                                                                                                                  vk::VK_SAMPLE_COUNT_1_BIT,
171                                                                                                                                  vk::VK_ATTACHMENT_LOAD_OP_LOAD,
172                                                                                                                                  vk::VK_ATTACHMENT_STORE_OP_STORE,
173                                                                                                                                  vk::VK_ATTACHMENT_LOAD_OP_LOAD,
174                                                                                                                                  vk::VK_ATTACHMENT_STORE_OP_STORE,
175                                                                                                                                  vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
176                                                                                                                                  vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
177
178                 const vk::VkAttachmentReference colorAttachmentReference =
179                 {
180                         0,
181                         vk::VK_IMAGE_LAYOUT_GENERAL
182                 };
183
184                 const vk::VkAttachmentReference depthAttachmentReference =
185                 {
186                         1,
187                         vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
188                 };
189
190                 renderPassCreateInfo.addSubpass(SubpassDescription(
191                         vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
192                         0,
193                         0,
194                         DE_NULL,
195                         1,
196                         &colorAttachmentReference,
197                         DE_NULL,
198                         depthAttachmentReference,
199                         0,
200                         DE_NULL));
201
202                 m_renderPass = vk::createRenderPass(m_vk, device, &renderPassCreateInfo);
203
204                 const vk::VkVertexInputBindingDescription vertexInputBindingDescription =
205                 {
206                         0,
207                         (deUint32)sizeof(tcu::Vec4) * 2,
208                         vk::VK_VERTEX_INPUT_RATE_VERTEX,
209                 };
210
211                 const vk::VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
212                 {
213                         {
214                                 0u,
215                                 0u,
216                                 vk::VK_FORMAT_R32G32B32A32_SFLOAT,
217                                 0u
218                         },
219                         {
220                                 1u,
221                                 0u,
222                                 vk::VK_FORMAT_R32G32B32A32_SFLOAT,
223                                 (deUint32)(sizeof(float)* 4),
224                         }
225                 };
226
227                 m_vertexInputState = PipelineCreateInfo::VertexInputState(
228                         1,
229                         &vertexInputBindingDescription,
230                         2,
231                         vertexInputAttributeDescriptions);
232
233                 const PipelineCreateInfo::ColorBlendState::Attachment vkCbAttachmentState;
234
235                 PipelineCreateInfo pipelineCreateInfo_1(*m_pipelineLayout, *m_renderPass, 0, 0);
236                 pipelineCreateInfo_1.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", vk::VK_SHADER_STAGE_VERTEX_BIT));
237                 pipelineCreateInfo_1.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, "main", vk::VK_SHADER_STAGE_FRAGMENT_BIT));
238                 pipelineCreateInfo_1.addState(PipelineCreateInfo::VertexInputState(m_vertexInputState));
239                 pipelineCreateInfo_1.addState(PipelineCreateInfo::InputAssemblerState(m_topology));
240                 pipelineCreateInfo_1.addState(PipelineCreateInfo::ColorBlendState(1, &vkCbAttachmentState));
241                 pipelineCreateInfo_1.addState(PipelineCreateInfo::ViewportState(1));
242                 pipelineCreateInfo_1.addState(m_depthStencilState_1);
243                 pipelineCreateInfo_1.addState(PipelineCreateInfo::RasterizerState());
244                 pipelineCreateInfo_1.addState(PipelineCreateInfo::MultiSampleState());
245                 pipelineCreateInfo_1.addState(PipelineCreateInfo::DynamicState());
246
247                 PipelineCreateInfo pipelineCreateInfo_2(*m_pipelineLayout, *m_renderPass, 0, 0);
248                 pipelineCreateInfo_2.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", vk::VK_SHADER_STAGE_VERTEX_BIT));
249                 pipelineCreateInfo_2.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, "main", vk::VK_SHADER_STAGE_FRAGMENT_BIT));
250                 pipelineCreateInfo_2.addState(PipelineCreateInfo::VertexInputState(m_vertexInputState));
251                 pipelineCreateInfo_2.addState(PipelineCreateInfo::InputAssemblerState(m_topology));
252                 pipelineCreateInfo_2.addState(PipelineCreateInfo::ColorBlendState(1, &vkCbAttachmentState));
253                 pipelineCreateInfo_2.addState(PipelineCreateInfo::ViewportState(1));
254                 pipelineCreateInfo_2.addState(m_depthStencilState_2);
255                 pipelineCreateInfo_2.addState(PipelineCreateInfo::RasterizerState());
256                 pipelineCreateInfo_2.addState(PipelineCreateInfo::MultiSampleState());
257                 pipelineCreateInfo_2.addState(PipelineCreateInfo::DynamicState());
258
259                 m_pipeline_1 = vk::createGraphicsPipeline(m_vk, device, DE_NULL, &pipelineCreateInfo_1);
260                 m_pipeline_2 = vk::createGraphicsPipeline(m_vk, device, DE_NULL, &pipelineCreateInfo_2);
261
262                 std::vector<vk::VkImageView> attachments(2);
263                 attachments[0] = *m_colorTargetView;
264                 attachments[1] = *m_attachmentView;
265
266                 const FramebufferCreateInfo framebufferCreateInfo(*m_renderPass, attachments, WIDTH, HEIGHT, 1);
267
268                 m_framebuffer = vk::createFramebuffer(m_vk, device, &framebufferCreateInfo);
269
270                 const vk::VkDeviceSize dataSize = m_data.size() * sizeof(PositionColorVertex);
271                 m_vertexBuffer = Buffer::createAndAlloc(m_vk, device, BufferCreateInfo(dataSize, vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT),
272                                                                                                 m_context.getDefaultAllocator(), vk::MemoryRequirement::HostVisible);
273
274                 deUint8* ptr = reinterpret_cast<unsigned char *>(m_vertexBuffer->getBoundMemory().getHostPtr());
275                 deMemcpy(ptr, &m_data[0], (size_t)dataSize);
276
277                 vk::flushMappedMemoryRange(m_vk, device,
278                         m_vertexBuffer->getBoundMemory().getMemory(),
279                         m_vertexBuffer->getBoundMemory().getOffset(),
280                         sizeof(dataSize));
281
282                 const CmdPoolCreateInfo cmdPoolCreateInfo(m_context.getUniversalQueueFamilyIndex());
283                 m_cmdPool = vk::createCommandPool(m_vk, device, &cmdPoolCreateInfo);
284
285                 const vk::VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
286                 {
287                         vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,     // VkStructureType                      sType;
288                         DE_NULL,                                                                                        // const void*                          pNext;
289                         *m_cmdPool,                                                                                     // VkCommandPool                        commandPool;
290                         vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY,                            // VkCommandBufferLevel         level;
291                         1u,                                                                                                     // deUint32                                     bufferCount;
292                 };
293                 m_cmdBuffer = vk::allocateCommandBuffer(m_vk, device, &cmdBufferAllocateInfo);
294         }
295
296         virtual tcu::TestStatus iterate (void)
297         {
298                 DE_ASSERT(false);
299                 return tcu::TestStatus::fail("Implement iterate() method!");
300         }
301
302         void beginRenderPass (void)
303         {
304                 const vk::VkClearColorValue clearColor = { { 0.0f, 0.0f, 0.0f, 1.0f } };
305                 beginRenderPassWithClearColor(clearColor);
306         }
307
308         void beginRenderPassWithClearColor (const vk::VkClearColorValue &clearColor)
309         {
310                 const CmdBufferBeginInfo beginInfo;
311                 m_vk.beginCommandBuffer(*m_cmdBuffer, &beginInfo);
312
313                 initialTransitionColor2DImage(m_vk, *m_cmdBuffer, m_colorTargetImage->object(), vk::VK_IMAGE_LAYOUT_GENERAL);
314                 initialTransitionDepthStencil2DImage(m_vk, *m_cmdBuffer, m_depthStencilImage->object(), vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
315
316                 const ImageSubresourceRange subresourceRangeImage(vk::VK_IMAGE_ASPECT_COLOR_BIT);
317                 m_vk.cmdClearColorImage(*m_cmdBuffer, m_colorTargetImage->object(),
318                         vk::VK_IMAGE_LAYOUT_GENERAL, &clearColor, 1, &subresourceRangeImage);
319
320                 const vk::VkClearDepthStencilValue depthStencilClearValue = { 0.0f, 0 };
321
322                 const ImageSubresourceRange subresourceRangeDepthStencil[2] = { vk::VK_IMAGE_ASPECT_DEPTH_BIT, vk::VK_IMAGE_ASPECT_STENCIL_BIT };
323                 m_vk.cmdClearDepthStencilImage(*m_cmdBuffer, m_depthStencilImage->object(),
324                         vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &depthStencilClearValue, 2, subresourceRangeDepthStencil);
325
326                 vk::VkMemoryBarrier memBarrier;
327                 memBarrier.sType = vk::VK_STRUCTURE_TYPE_MEMORY_BARRIER;
328                 memBarrier.pNext = NULL;
329                 memBarrier.srcAccessMask = vk::VK_ACCESS_TRANSFER_WRITE_BIT;
330                 memBarrier.dstAccessMask = vk::VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
331                                            vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
332  
333                 m_vk.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
334                                                       vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
335                                                       vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
336                                                       0, 1, &memBarrier, 0, NULL, 0, NULL);
337  
338                 const vk::VkRect2D renderArea = { { 0, 0 }, { WIDTH, HEIGHT } };
339                 const RenderPassBeginInfo renderPassBegin(*m_renderPass, *m_framebuffer, renderArea);
340
341                 m_vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBegin, vk::VK_SUBPASS_CONTENTS_INLINE);
342         }
343
344         void setDynamicViewportState (const deUint32 width, const deUint32 height)
345         {
346                 vk::VkViewport viewport;
347                 viewport.x = 0;
348                 viewport.y = 0;
349                 viewport.width = static_cast<float>(width);
350                 viewport.height = static_cast<float>(height);
351                 viewport.minDepth = 0.0f;
352                 viewport.maxDepth = 1.0f;
353
354                 m_vk.cmdSetViewport(*m_cmdBuffer, 0, 1, &viewport);
355
356                 vk::VkRect2D scissor;
357                 scissor.offset.x = 0;
358                 scissor.offset.y = 0;
359                 scissor.extent.width = width;
360                 scissor.extent.height = height;
361                 m_vk.cmdSetScissor(*m_cmdBuffer, 0, 1, &scissor);
362         }
363
364         void setDynamicViewportState(const deUint32 viewportCount, const vk::VkViewport* pViewports, const vk::VkRect2D* pScissors)
365         {
366                 m_vk.cmdSetViewport(*m_cmdBuffer, 0, viewportCount, pViewports);
367                 m_vk.cmdSetScissor(*m_cmdBuffer, 0, viewportCount, pScissors);
368         }
369
370         void setDynamicRasterizationState(const float lineWidth = 1.0f,
371                                                            const float depthBiasConstantFactor = 0.0f,
372                                                            const float depthBiasClamp = 0.0f,
373                                                            const float depthBiasSlopeFactor = 0.0f)
374         {
375                 m_vk.cmdSetLineWidth(*m_cmdBuffer, lineWidth);
376                 m_vk.cmdSetDepthBias(*m_cmdBuffer, depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor);
377         }
378
379         void setDynamicBlendState(const float const1 = 0.0f, const float const2 = 0.0f,
380                                                           const float const3 = 0.0f, const float const4 = 0.0f)
381         {
382                 float blendConstantsants[4] = { const1, const2, const3, const4 };
383                 m_vk.cmdSetBlendConstants(*m_cmdBuffer, blendConstantsants);
384         }
385
386         void setDynamicDepthStencilState(const float minDepthBounds = -1.0f,
387                                                                          const float maxDepthBounds = 1.0f,
388                                                                          const deUint32 stencilFrontCompareMask = 0xffffffffu,
389                                                                          const deUint32 stencilFrontWriteMask = 0xffffffffu,
390                                                                          const deUint32 stencilFrontReference = 0,
391                                                                          const deUint32 stencilBackCompareMask = 0xffffffffu,
392                                                                          const deUint32 stencilBackWriteMask = 0xffffffffu,
393                                                                          const deUint32 stencilBackReference = 0)
394         {
395                 m_vk.cmdSetDepthBounds(*m_cmdBuffer, minDepthBounds, maxDepthBounds);
396                 m_vk.cmdSetStencilCompareMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontCompareMask);
397                 m_vk.cmdSetStencilWriteMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontWriteMask);
398                 m_vk.cmdSetStencilReference(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontReference);
399                 m_vk.cmdSetStencilCompareMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackCompareMask);
400                 m_vk.cmdSetStencilWriteMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackWriteMask);
401                 m_vk.cmdSetStencilReference(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackReference);
402         }
403 };
404
405 class DepthBoundsParamTestInstance : public DepthStencilBaseCase
406 {
407 public:
408         DepthBoundsParamTestInstance (Context &context, ShaderMap shaders)
409                 : DepthStencilBaseCase (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
410         {
411                 // Check if depth bounds test is supported
412                 {
413                         const vk::VkPhysicalDeviceFeatures& deviceFeatures = m_context.getDeviceFeatures();
414
415                         if (!deviceFeatures.depthBounds)
416                                 throw tcu::NotSupportedError("Depth bounds test is unsupported");
417                 }
418
419                 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 0.375f, 1.0f), tcu::RGBA::green().toVec()));
420                 m_data.push_back(PositionColorVertex(tcu::Vec4(0.0f, 1.0f, 0.375f, 1.0f), tcu::RGBA::green().toVec()));
421                 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 0.375f, 1.0f), tcu::RGBA::green().toVec()));
422                 m_data.push_back(PositionColorVertex(tcu::Vec4(0.0f, -1.0f, 0.375f, 1.0f), tcu::RGBA::green().toVec()));
423
424                 m_data.push_back(PositionColorVertex(tcu::Vec4(0.0f, 1.0f, 0.625f, 1.0f), tcu::RGBA::green().toVec()));
425                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 0.625f, 1.0f), tcu::RGBA::green().toVec()));
426                 m_data.push_back(PositionColorVertex(tcu::Vec4(0.0f, -1.0f, 0.625f, 1.0f), tcu::RGBA::green().toVec()));
427                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 0.625f, 1.0f), tcu::RGBA::green().toVec()));
428
429                 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
430                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
431                 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
432                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
433
434                 m_depthStencilState_1 = PipelineCreateInfo::DepthStencilState(
435                         vk::VK_TRUE, vk::VK_TRUE, vk::VK_COMPARE_OP_ALWAYS, vk::VK_FALSE);
436
437                 // enable depth bounds test
438                 m_depthStencilState_2 = PipelineCreateInfo::DepthStencilState(
439                         vk::VK_FALSE, vk::VK_FALSE, vk::VK_COMPARE_OP_NEVER, vk::VK_TRUE);
440
441                 DepthStencilBaseCase::initialize();
442         }
443
444         virtual tcu::TestStatus iterate (void)
445         {
446                 tcu::TestLog &log = m_context.getTestContext().getLog();
447                 const vk::VkQueue queue = m_context.getUniversalQueue();
448
449                 beginRenderPass();
450
451                 // set states here
452                 setDynamicViewportState(WIDTH, HEIGHT);
453                 setDynamicRasterizationState();
454                 setDynamicBlendState();
455                 setDynamicDepthStencilState(0.5f, 0.75f);
456
457                 const vk::VkDeviceSize vertexBufferOffset = 0;
458                 const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
459                 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
460
461                 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline_1);
462                 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
463                 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 4, 0);
464
465                 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline_2);
466                 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 8, 0);
467
468                 m_vk.cmdEndRenderPass(*m_cmdBuffer);
469                 m_vk.endCommandBuffer(*m_cmdBuffer);
470
471                 vk::VkSubmitInfo submitInfo =
472                 {
473                         vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,      // VkStructureType                      sType;
474                         DE_NULL,                                                        // const void*                          pNext;
475                         0,                                                                      // deUint32                                     waitSemaphoreCount;
476                         DE_NULL,                                                        // const VkSemaphore*           pWaitSemaphores;
477                         (const vk::VkPipelineStageFlags*)DE_NULL,
478                         1,                                                                      // deUint32                                     commandBufferCount;
479                         &m_cmdBuffer.get(),                                     // const VkCommandBuffer*       pCommandBuffers;
480                         0,                                                                      // deUint32                                     signalSemaphoreCount;
481                         DE_NULL                                                         // const VkSemaphore*           pSignalSemaphores;
482                 };
483                 m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL);
484
485                 // validation
486                 {
487                         VK_CHECK(m_vk.queueWaitIdle(queue));
488
489                         tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
490                         referenceFrame.allocLevel(0);
491
492                         const deInt32 frameWidth = referenceFrame.getWidth();
493                         const deInt32 frameHeight = referenceFrame.getHeight();
494
495                         tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
496
497                         for (int y = 0; y < frameHeight; y++)
498                         {
499                                 const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
500
501                                 for (int x = 0; x < frameWidth; x++)
502                                 {
503                                         const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
504
505                                         if (xCoord >= 0.0f && xCoord <= 1.0f && yCoord >= -1.0f && yCoord <= 1.0f)
506                                                 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
507                                         else
508                                                 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
509                                 }
510                         }
511
512                         const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
513                         const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
514                                 vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
515
516                         if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
517                                 referenceFrame.getLevel(0), renderedFrame, 0.05f,
518                                 tcu::COMPARE_LOG_RESULT))
519                         {
520                                 return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
521                         }
522
523                         return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
524                 }
525         }
526 };
527
528 class StencilParamsBasicTestInstance : public DepthStencilBaseCase
529 {
530 protected:
531         deUint32 m_writeMask;
532         deUint32 m_readMask;
533         deUint32 m_expectedValue;
534         tcu::Vec4 m_expectedColor;
535
536 public:
537         StencilParamsBasicTestInstance (Context& context, const char* vertexShaderName, const char* fragmentShaderName,
538                                                                         const deUint32 writeMask, const deUint32 readMask,
539                                                                         const deUint32 expectedValue, const tcu::Vec4 expectedColor)
540                 : DepthStencilBaseCase  (context, vertexShaderName, fragmentShaderName)
541                 , m_expectedColor               (1.0f, 1.0f, 1.0f, 1.0f)
542         {
543                 m_writeMask = writeMask;
544                 m_readMask = readMask;
545                 m_expectedValue = expectedValue;
546                 m_expectedColor = expectedColor;
547
548                 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
549                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
550                 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
551                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
552
553                 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
554                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
555                 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
556                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
557
558                 const PipelineCreateInfo::DepthStencilState::StencilOpState frontState_1 =
559                         PipelineCreateInfo::DepthStencilState::StencilOpState(
560                         vk::VK_STENCIL_OP_REPLACE,
561                         vk::VK_STENCIL_OP_REPLACE,
562                         vk::VK_STENCIL_OP_REPLACE,
563                         vk::VK_COMPARE_OP_ALWAYS);
564
565                 const PipelineCreateInfo::DepthStencilState::StencilOpState backState_1 =
566                         PipelineCreateInfo::DepthStencilState::StencilOpState(
567                         vk::VK_STENCIL_OP_REPLACE,
568                         vk::VK_STENCIL_OP_REPLACE,
569                         vk::VK_STENCIL_OP_REPLACE,
570                         vk::VK_COMPARE_OP_ALWAYS);
571
572                 const PipelineCreateInfo::DepthStencilState::StencilOpState frontState_2 =
573                         PipelineCreateInfo::DepthStencilState::StencilOpState(
574                         vk::VK_STENCIL_OP_REPLACE,
575                         vk::VK_STENCIL_OP_REPLACE,
576                         vk::VK_STENCIL_OP_REPLACE,
577                         vk::VK_COMPARE_OP_EQUAL);
578
579                 const PipelineCreateInfo::DepthStencilState::StencilOpState backState_2 =
580                         PipelineCreateInfo::DepthStencilState::StencilOpState(
581                         vk::VK_STENCIL_OP_REPLACE,
582                         vk::VK_STENCIL_OP_REPLACE,
583                         vk::VK_STENCIL_OP_REPLACE,
584                         vk::VK_COMPARE_OP_EQUAL);
585
586                 // enable stencil test
587                 m_depthStencilState_1 = PipelineCreateInfo::DepthStencilState(
588                         vk::VK_FALSE, vk::VK_FALSE, vk::VK_COMPARE_OP_NEVER, vk::VK_FALSE, vk::VK_TRUE, frontState_1, backState_1);
589
590                 m_depthStencilState_2 = PipelineCreateInfo::DepthStencilState(
591                         vk::VK_FALSE, vk::VK_FALSE, vk::VK_COMPARE_OP_NEVER, vk::VK_FALSE, vk::VK_TRUE, frontState_2, backState_2);
592
593                 DepthStencilBaseCase::initialize();
594         }
595
596         virtual tcu::TestStatus iterate (void)
597         {
598                 tcu::TestLog &log = m_context.getTestContext().getLog();
599                 const vk::VkQueue queue = m_context.getUniversalQueue();
600
601                 beginRenderPass();
602
603                 // set states here
604                 setDynamicViewportState(WIDTH, HEIGHT);
605                 setDynamicRasterizationState();
606                 setDynamicBlendState();
607
608                 const vk::VkDeviceSize vertexBufferOffset = 0;
609                 const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
610                 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
611
612                 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline_1);
613                 setDynamicDepthStencilState(-1.0f, 1.0f, 0xFF, m_writeMask, 0x0F, 0xFF, m_writeMask, 0x0F);
614                 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
615
616                 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline_2);
617                 setDynamicDepthStencilState(-1.0f, 1.0f, m_readMask, 0xFF, m_expectedValue, m_readMask, 0xFF, m_expectedValue);
618                 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 4, 0);
619
620                 m_vk.cmdEndRenderPass(*m_cmdBuffer);
621                 m_vk.endCommandBuffer(*m_cmdBuffer);
622
623                 vk::VkSubmitInfo submitInfo =
624                 {
625                         vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,      // VkStructureType                      sType;
626                         DE_NULL,                                                        // const void*                          pNext;
627                         0,                                                                      // deUint32                                     waitSemaphoreCount;
628                         DE_NULL,                                                        // const VkSemaphore*           pWaitSemaphores;
629                         (const vk::VkPipelineStageFlags*)DE_NULL,
630                         1,                                                                      // deUint32                                     commandBufferCount;
631                         &m_cmdBuffer.get(),                                     // const VkCommandBuffer*       pCommandBuffers;
632                         0,                                                                      // deUint32                                     signalSemaphoreCount;
633                         DE_NULL                                                         // const VkSemaphore*           pSignalSemaphores;
634                 };
635                 m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL);
636
637                 // validation
638                 {
639                         VK_CHECK(m_vk.queueWaitIdle(queue));
640
641                         tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
642                         referenceFrame.allocLevel(0);
643
644                         const deInt32 frameWidth = referenceFrame.getWidth();
645                         const deInt32 frameHeight = referenceFrame.getHeight();
646
647                         for (int y = 0; y < frameHeight; y++)
648                         {
649                                 const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
650
651                                 for (int x = 0; x < frameWidth; x++)
652                                 {
653                                         const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
654
655                                         if (xCoord >= -1.0f && xCoord <= 1.0f && yCoord >= -1.0f && yCoord <= 1.0f)
656                                                 referenceFrame.getLevel(0).setPixel(m_expectedColor, x, y);
657                                 }
658                         }
659
660                         const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
661                         const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
662                                 vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
663
664                         if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
665                                 referenceFrame.getLevel(0), renderedFrame, 0.05f,
666                                 tcu::COMPARE_LOG_RESULT))
667                         {
668                                 return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
669                         }
670
671                         return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
672                 }
673         }
674 };
675
676 class StencilParamsBasicTestCase : public TestCase
677 {
678 protected:
679         TestInstance* createInstance(Context& context) const
680         {
681                 return new StencilParamsBasicTestInstance(context, "VertexFetch.vert", "VertexFetch.frag",
682                         m_writeMask, m_readMask, m_expectedValue, m_expectedColor);
683         }
684
685         virtual void initPrograms(vk::SourceCollections& programCollection) const
686         {
687                 programCollection.glslSources.add("VertexFetch.vert") <<
688                         glu::VertexSource(ShaderSourceProvider::getSource(m_testCtx.getArchive(), "vulkan/dynamic_state/VertexFetch.vert"));
689
690                 programCollection.glslSources.add("VertexFetch.frag") <<
691                         glu::FragmentSource(ShaderSourceProvider::getSource(m_testCtx.getArchive(), "vulkan/dynamic_state/VertexFetch.frag"));
692         }
693
694         deUint32 m_writeMask;
695         deUint32 m_readMask;
696         deUint32 m_expectedValue;
697         tcu::Vec4 m_expectedColor;
698
699 public:
700         StencilParamsBasicTestCase (tcu::TestContext& context, const char *name, const char *description,
701                                                                 const deUint32 writeMask, const deUint32 readMask,
702                                                                 const deUint32 expectedValue, const tcu::Vec4 expectedColor)
703                 : TestCase                              (context, name, description)
704                 , m_writeMask                   (writeMask)
705                 , m_readMask                    (readMask)
706                 , m_expectedValue               (expectedValue)
707                 , m_expectedColor               (expectedColor)
708         {
709         }
710 };
711
712 class StencilParamsAdvancedTestInstance : public DepthStencilBaseCase
713 {
714 public:
715         StencilParamsAdvancedTestInstance (Context& context, ShaderMap shaders)
716                 : DepthStencilBaseCase (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
717         {
718                 m_data.push_back(PositionColorVertex(tcu::Vec4(-0.5f, 0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
719                 m_data.push_back(PositionColorVertex(tcu::Vec4(0.5f, 0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
720                 m_data.push_back(PositionColorVertex(tcu::Vec4(-0.5f, -0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
721                 m_data.push_back(PositionColorVertex(tcu::Vec4(0.5f, -0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
722
723                 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
724                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
725                 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
726                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
727
728                 const PipelineCreateInfo::DepthStencilState::StencilOpState frontState_1 =
729                         PipelineCreateInfo::DepthStencilState::StencilOpState(
730                         vk::VK_STENCIL_OP_REPLACE,
731                         vk::VK_STENCIL_OP_REPLACE,
732                         vk::VK_STENCIL_OP_REPLACE,
733                         vk::VK_COMPARE_OP_ALWAYS);
734
735                 const PipelineCreateInfo::DepthStencilState::StencilOpState backState_1 =
736                         PipelineCreateInfo::DepthStencilState::StencilOpState(
737                         vk::VK_STENCIL_OP_REPLACE,
738                         vk::VK_STENCIL_OP_REPLACE,
739                         vk::VK_STENCIL_OP_REPLACE,
740                         vk::VK_COMPARE_OP_ALWAYS);
741
742                 const PipelineCreateInfo::DepthStencilState::StencilOpState frontState_2 =
743                         PipelineCreateInfo::DepthStencilState::StencilOpState(
744                         vk::VK_STENCIL_OP_REPLACE,
745                         vk::VK_STENCIL_OP_REPLACE,
746                         vk::VK_STENCIL_OP_REPLACE,
747                         vk::VK_COMPARE_OP_NOT_EQUAL);
748
749                 const PipelineCreateInfo::DepthStencilState::StencilOpState backState_2 =
750                         PipelineCreateInfo::DepthStencilState::StencilOpState(
751                         vk::VK_STENCIL_OP_REPLACE,
752                         vk::VK_STENCIL_OP_REPLACE,
753                         vk::VK_STENCIL_OP_REPLACE,
754                         vk::VK_COMPARE_OP_NOT_EQUAL);
755
756                 // enable stencil test
757                 m_depthStencilState_1 = PipelineCreateInfo::DepthStencilState(
758                         vk::VK_FALSE, vk::VK_FALSE, vk::VK_COMPARE_OP_NEVER, vk::VK_FALSE, vk::VK_TRUE, frontState_1, backState_1);
759
760                 m_depthStencilState_2 = PipelineCreateInfo::DepthStencilState(
761                         vk::VK_FALSE, vk::VK_FALSE, vk::VK_COMPARE_OP_NEVER, vk::VK_FALSE, vk::VK_TRUE, frontState_2, backState_2);
762
763                 DepthStencilBaseCase::initialize();
764         }
765
766         virtual tcu::TestStatus iterate (void)
767         {
768                 tcu::TestLog &log = m_context.getTestContext().getLog();
769                 const vk::VkQueue queue = m_context.getUniversalQueue();
770
771                 beginRenderPass();
772
773                 // set states here
774                 setDynamicViewportState(WIDTH, HEIGHT);
775                 setDynamicRasterizationState();
776                 setDynamicBlendState();
777
778                 const vk::VkDeviceSize vertexBufferOffset = 0;
779                 const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
780                 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
781
782                 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline_1);
783                 setDynamicDepthStencilState(-1.0f, 1.0f, 0xFF, 0x0E, 0x0F, 0xFF, 0x0E, 0x0F);
784                 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
785
786                 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline_2);
787                 setDynamicDepthStencilState(-1.0f, 1.0f, 0xFF, 0xFF, 0x0E, 0xFF, 0xFF, 0x0E);
788                 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 4, 0);
789
790                 m_vk.cmdEndRenderPass(*m_cmdBuffer);
791                 m_vk.endCommandBuffer(*m_cmdBuffer);
792
793                 vk::VkSubmitInfo submitInfo =
794                 {
795                         vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,      // VkStructureType                      sType;
796                         DE_NULL,                                                        // const void*                          pNext;
797                         0,                                                                      // deUint32                                     waitSemaphoreCount;
798                         DE_NULL,                                                        // const VkSemaphore*           pWaitSemaphores;
799                         (const vk::VkPipelineStageFlags*)DE_NULL,
800                         1,                                                                      // deUint32                                     commandBufferCount;
801                         &m_cmdBuffer.get(),                                     // const VkCommandBuffer*       pCommandBuffers;
802                         0,                                                                      // deUint32                                     signalSemaphoreCount;
803                         DE_NULL                                                         // const VkSemaphore*           pSignalSemaphores;
804                 };
805                 m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL);
806
807                 // validation
808                 {
809                         VK_CHECK(m_vk.queueWaitIdle(queue));
810
811                         tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
812                         referenceFrame.allocLevel(0);
813
814                         const deInt32 frameWidth = referenceFrame.getWidth();
815                         const deInt32 frameHeight = referenceFrame.getHeight();
816
817                         for (int y = 0; y < frameHeight; y++)
818                         {
819                                 const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
820
821                                 for (int x = 0; x < frameWidth; x++)
822                                 {
823                                         const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
824
825                                         if (xCoord >= -0.5f && xCoord <= 0.5f && yCoord >= -0.5f && yCoord <= 0.5f)
826                                                 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
827                                         else
828                                                 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
829                                 }
830                         }
831
832                         const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
833                         const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
834                                 vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
835
836                         if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
837                                 referenceFrame.getLevel(0), renderedFrame, 0.05f,
838                                 tcu::COMPARE_LOG_RESULT))
839                         {
840                                 return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
841                         }
842
843                         return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
844                 }
845         }
846 };
847
848 } //anonymous
849
850 DynamicStateDSTests::DynamicStateDSTests (tcu::TestContext& testCtx)
851         : TestCaseGroup (testCtx, "ds_state", "Tests for depth stencil state")
852 {
853         /* Left blank on purpose */
854 }
855
856 DynamicStateDSTests::~DynamicStateDSTests ()
857 {
858 }
859
860 void DynamicStateDSTests::init (void)
861 {
862         ShaderMap shaderPaths;
863         shaderPaths[glu::SHADERTYPE_VERTEX] = "vulkan/dynamic_state/VertexFetch.vert";
864         shaderPaths[glu::SHADERTYPE_FRAGMENT] = "vulkan/dynamic_state/VertexFetch.frag";
865
866         addChild(new InstanceFactory<DepthBoundsParamTestInstance>(m_testCtx, "depth_bounds", "Perform depth bounds test", shaderPaths));
867         addChild(new StencilParamsBasicTestCase(m_testCtx, "stencil_params_basic_1", "Perform basic stencil test 1", 0x0D, 0x06, 0x05, tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f)));
868         addChild(new StencilParamsBasicTestCase(m_testCtx, "stencil_params_basic_2", "Perform basic stencil test 2", 0x06, 0x02, 0x05, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f)));
869         addChild(new InstanceFactory<StencilParamsAdvancedTestInstance>(m_testCtx, "stencil_params_advanced", "Perform advanced stencil test", shaderPaths));
870 }
871
872 } // DynamicState
873 } // vkt