Bug Fix: Corrected barriers in the tests dEQP-VK.dynamic_state.
[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, 0, vk::VK_ACCESS_TRANSFER_WRITE_BIT);
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                 transition2DImage(m_vk, *m_cmdBuffer, m_depthStencilImage->object(), vk::VK_IMAGE_ASPECT_DEPTH_BIT | vk::VK_IMAGE_ASPECT_STENCIL_BIT, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT);
342
343                 m_vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBegin, vk::VK_SUBPASS_CONTENTS_INLINE);
344         }
345
346         void setDynamicViewportState (const deUint32 width, const deUint32 height)
347         {
348                 vk::VkViewport viewport;
349                 viewport.x = 0;
350                 viewport.y = 0;
351                 viewport.width = static_cast<float>(width);
352                 viewport.height = static_cast<float>(height);
353                 viewport.minDepth = 0.0f;
354                 viewport.maxDepth = 1.0f;
355
356                 m_vk.cmdSetViewport(*m_cmdBuffer, 0, 1, &viewport);
357
358                 vk::VkRect2D scissor;
359                 scissor.offset.x = 0;
360                 scissor.offset.y = 0;
361                 scissor.extent.width = width;
362                 scissor.extent.height = height;
363                 m_vk.cmdSetScissor(*m_cmdBuffer, 0, 1, &scissor);
364         }
365
366         void setDynamicViewportState(const deUint32 viewportCount, const vk::VkViewport* pViewports, const vk::VkRect2D* pScissors)
367         {
368                 m_vk.cmdSetViewport(*m_cmdBuffer, 0, viewportCount, pViewports);
369                 m_vk.cmdSetScissor(*m_cmdBuffer, 0, viewportCount, pScissors);
370         }
371
372         void setDynamicRasterizationState(const float lineWidth = 1.0f,
373                                                            const float depthBiasConstantFactor = 0.0f,
374                                                            const float depthBiasClamp = 0.0f,
375                                                            const float depthBiasSlopeFactor = 0.0f)
376         {
377                 m_vk.cmdSetLineWidth(*m_cmdBuffer, lineWidth);
378                 m_vk.cmdSetDepthBias(*m_cmdBuffer, depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor);
379         }
380
381         void setDynamicBlendState(const float const1 = 0.0f, const float const2 = 0.0f,
382                                                           const float const3 = 0.0f, const float const4 = 0.0f)
383         {
384                 float blendConstantsants[4] = { const1, const2, const3, const4 };
385                 m_vk.cmdSetBlendConstants(*m_cmdBuffer, blendConstantsants);
386         }
387
388         void setDynamicDepthStencilState(const float minDepthBounds = -1.0f,
389                                                                          const float maxDepthBounds = 1.0f,
390                                                                          const deUint32 stencilFrontCompareMask = 0xffffffffu,
391                                                                          const deUint32 stencilFrontWriteMask = 0xffffffffu,
392                                                                          const deUint32 stencilFrontReference = 0,
393                                                                          const deUint32 stencilBackCompareMask = 0xffffffffu,
394                                                                          const deUint32 stencilBackWriteMask = 0xffffffffu,
395                                                                          const deUint32 stencilBackReference = 0)
396         {
397                 m_vk.cmdSetDepthBounds(*m_cmdBuffer, minDepthBounds, maxDepthBounds);
398                 m_vk.cmdSetStencilCompareMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontCompareMask);
399                 m_vk.cmdSetStencilWriteMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontWriteMask);
400                 m_vk.cmdSetStencilReference(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontReference);
401                 m_vk.cmdSetStencilCompareMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackCompareMask);
402                 m_vk.cmdSetStencilWriteMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackWriteMask);
403                 m_vk.cmdSetStencilReference(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackReference);
404         }
405 };
406
407 class DepthBoundsParamTestInstance : public DepthStencilBaseCase
408 {
409 public:
410         DepthBoundsParamTestInstance (Context &context, ShaderMap shaders)
411                 : DepthStencilBaseCase (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
412         {
413                 // Check if depth bounds test is supported
414                 {
415                         const vk::VkPhysicalDeviceFeatures& deviceFeatures = m_context.getDeviceFeatures();
416
417                         if (!deviceFeatures.depthBounds)
418                                 throw tcu::NotSupportedError("Depth bounds test is unsupported");
419                 }
420
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                 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 0.375f, 1.0f), tcu::RGBA::green().toVec()));
424                 m_data.push_back(PositionColorVertex(tcu::Vec4(0.0f, -1.0f, 0.375f, 1.0f), tcu::RGBA::green().toVec()));
425
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                 m_data.push_back(PositionColorVertex(tcu::Vec4(0.0f, -1.0f, 0.625f, 1.0f), tcu::RGBA::green().toVec()));
429                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 0.625f, 1.0f), tcu::RGBA::green().toVec()));
430
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                 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
434                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
435
436                 m_depthStencilState_1 = PipelineCreateInfo::DepthStencilState(
437                         vk::VK_TRUE, vk::VK_TRUE, vk::VK_COMPARE_OP_ALWAYS, vk::VK_FALSE);
438
439                 // enable depth bounds test
440                 m_depthStencilState_2 = PipelineCreateInfo::DepthStencilState(
441                         vk::VK_FALSE, vk::VK_FALSE, vk::VK_COMPARE_OP_NEVER, vk::VK_TRUE);
442
443                 DepthStencilBaseCase::initialize();
444         }
445
446         virtual tcu::TestStatus iterate (void)
447         {
448                 tcu::TestLog &log = m_context.getTestContext().getLog();
449                 const vk::VkQueue queue = m_context.getUniversalQueue();
450
451                 beginRenderPass();
452
453                 // set states here
454                 setDynamicViewportState(WIDTH, HEIGHT);
455                 setDynamicRasterizationState();
456                 setDynamicBlendState();
457                 setDynamicDepthStencilState(0.5f, 0.75f);
458
459                 const vk::VkDeviceSize vertexBufferOffset = 0;
460                 const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
461                 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
462
463                 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline_1);
464                 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
465                 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 4, 0);
466
467                 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline_2);
468                 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 8, 0);
469
470                 m_vk.cmdEndRenderPass(*m_cmdBuffer);
471                 m_vk.endCommandBuffer(*m_cmdBuffer);
472
473                 vk::VkSubmitInfo submitInfo =
474                 {
475                         vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,      // VkStructureType                      sType;
476                         DE_NULL,                                                        // const void*                          pNext;
477                         0,                                                                      // deUint32                                     waitSemaphoreCount;
478                         DE_NULL,                                                        // const VkSemaphore*           pWaitSemaphores;
479                         (const vk::VkPipelineStageFlags*)DE_NULL,
480                         1,                                                                      // deUint32                                     commandBufferCount;
481                         &m_cmdBuffer.get(),                                     // const VkCommandBuffer*       pCommandBuffers;
482                         0,                                                                      // deUint32                                     signalSemaphoreCount;
483                         DE_NULL                                                         // const VkSemaphore*           pSignalSemaphores;
484                 };
485                 m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL);
486
487                 // validation
488                 {
489                         VK_CHECK(m_vk.queueWaitIdle(queue));
490
491                         tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
492                         referenceFrame.allocLevel(0);
493
494                         const deInt32 frameWidth = referenceFrame.getWidth();
495                         const deInt32 frameHeight = referenceFrame.getHeight();
496
497                         tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
498
499                         for (int y = 0; y < frameHeight; y++)
500                         {
501                                 const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
502
503                                 for (int x = 0; x < frameWidth; x++)
504                                 {
505                                         const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
506
507                                         if (xCoord >= 0.0f && xCoord <= 1.0f && yCoord >= -1.0f && yCoord <= 1.0f)
508                                                 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
509                                         else
510                                                 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
511                                 }
512                         }
513
514                         const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
515                         const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
516                                 vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
517
518                         if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
519                                 referenceFrame.getLevel(0), renderedFrame, 0.05f,
520                                 tcu::COMPARE_LOG_RESULT))
521                         {
522                                 return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
523                         }
524
525                         return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
526                 }
527         }
528 };
529
530 class StencilParamsBasicTestInstance : public DepthStencilBaseCase
531 {
532 protected:
533         deUint32 m_writeMask;
534         deUint32 m_readMask;
535         deUint32 m_expectedValue;
536         tcu::Vec4 m_expectedColor;
537
538 public:
539         StencilParamsBasicTestInstance (Context& context, const char* vertexShaderName, const char* fragmentShaderName,
540                                                                         const deUint32 writeMask, const deUint32 readMask,
541                                                                         const deUint32 expectedValue, const tcu::Vec4 expectedColor)
542                 : DepthStencilBaseCase  (context, vertexShaderName, fragmentShaderName)
543                 , m_expectedColor               (1.0f, 1.0f, 1.0f, 1.0f)
544         {
545                 m_writeMask = writeMask;
546                 m_readMask = readMask;
547                 m_expectedValue = expectedValue;
548                 m_expectedColor = expectedColor;
549
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                 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
553                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
554
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                 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
558                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
559
560                 const PipelineCreateInfo::DepthStencilState::StencilOpState frontState_1 =
561                         PipelineCreateInfo::DepthStencilState::StencilOpState(
562                         vk::VK_STENCIL_OP_REPLACE,
563                         vk::VK_STENCIL_OP_REPLACE,
564                         vk::VK_STENCIL_OP_REPLACE,
565                         vk::VK_COMPARE_OP_ALWAYS);
566
567                 const PipelineCreateInfo::DepthStencilState::StencilOpState backState_1 =
568                         PipelineCreateInfo::DepthStencilState::StencilOpState(
569                         vk::VK_STENCIL_OP_REPLACE,
570                         vk::VK_STENCIL_OP_REPLACE,
571                         vk::VK_STENCIL_OP_REPLACE,
572                         vk::VK_COMPARE_OP_ALWAYS);
573
574                 const PipelineCreateInfo::DepthStencilState::StencilOpState frontState_2 =
575                         PipelineCreateInfo::DepthStencilState::StencilOpState(
576                         vk::VK_STENCIL_OP_REPLACE,
577                         vk::VK_STENCIL_OP_REPLACE,
578                         vk::VK_STENCIL_OP_REPLACE,
579                         vk::VK_COMPARE_OP_EQUAL);
580
581                 const PipelineCreateInfo::DepthStencilState::StencilOpState backState_2 =
582                         PipelineCreateInfo::DepthStencilState::StencilOpState(
583                         vk::VK_STENCIL_OP_REPLACE,
584                         vk::VK_STENCIL_OP_REPLACE,
585                         vk::VK_STENCIL_OP_REPLACE,
586                         vk::VK_COMPARE_OP_EQUAL);
587
588                 // enable stencil test
589                 m_depthStencilState_1 = PipelineCreateInfo::DepthStencilState(
590                         vk::VK_FALSE, vk::VK_FALSE, vk::VK_COMPARE_OP_NEVER, vk::VK_FALSE, vk::VK_TRUE, frontState_1, backState_1);
591
592                 m_depthStencilState_2 = PipelineCreateInfo::DepthStencilState(
593                         vk::VK_FALSE, vk::VK_FALSE, vk::VK_COMPARE_OP_NEVER, vk::VK_FALSE, vk::VK_TRUE, frontState_2, backState_2);
594
595                 DepthStencilBaseCase::initialize();
596         }
597
598         virtual tcu::TestStatus iterate (void)
599         {
600                 tcu::TestLog &log = m_context.getTestContext().getLog();
601                 const vk::VkQueue queue = m_context.getUniversalQueue();
602
603                 beginRenderPass();
604
605                 // set states here
606                 setDynamicViewportState(WIDTH, HEIGHT);
607                 setDynamicRasterizationState();
608                 setDynamicBlendState();
609
610                 const vk::VkDeviceSize vertexBufferOffset = 0;
611                 const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
612                 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
613
614                 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline_1);
615                 setDynamicDepthStencilState(-1.0f, 1.0f, 0xFF, m_writeMask, 0x0F, 0xFF, m_writeMask, 0x0F);
616                 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
617
618                 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline_2);
619                 setDynamicDepthStencilState(-1.0f, 1.0f, m_readMask, 0xFF, m_expectedValue, m_readMask, 0xFF, m_expectedValue);
620                 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 4, 0);
621
622                 m_vk.cmdEndRenderPass(*m_cmdBuffer);
623                 m_vk.endCommandBuffer(*m_cmdBuffer);
624
625                 vk::VkSubmitInfo submitInfo =
626                 {
627                         vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,      // VkStructureType                      sType;
628                         DE_NULL,                                                        // const void*                          pNext;
629                         0,                                                                      // deUint32                                     waitSemaphoreCount;
630                         DE_NULL,                                                        // const VkSemaphore*           pWaitSemaphores;
631                         (const vk::VkPipelineStageFlags*)DE_NULL,
632                         1,                                                                      // deUint32                                     commandBufferCount;
633                         &m_cmdBuffer.get(),                                     // const VkCommandBuffer*       pCommandBuffers;
634                         0,                                                                      // deUint32                                     signalSemaphoreCount;
635                         DE_NULL                                                         // const VkSemaphore*           pSignalSemaphores;
636                 };
637                 m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL);
638
639                 // validation
640                 {
641                         VK_CHECK(m_vk.queueWaitIdle(queue));
642
643                         tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
644                         referenceFrame.allocLevel(0);
645
646                         const deInt32 frameWidth = referenceFrame.getWidth();
647                         const deInt32 frameHeight = referenceFrame.getHeight();
648
649                         for (int y = 0; y < frameHeight; y++)
650                         {
651                                 const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
652
653                                 for (int x = 0; x < frameWidth; x++)
654                                 {
655                                         const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
656
657                                         if (xCoord >= -1.0f && xCoord <= 1.0f && yCoord >= -1.0f && yCoord <= 1.0f)
658                                                 referenceFrame.getLevel(0).setPixel(m_expectedColor, x, y);
659                                 }
660                         }
661
662                         const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
663                         const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
664                                 vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
665
666                         if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
667                                 referenceFrame.getLevel(0), renderedFrame, 0.05f,
668                                 tcu::COMPARE_LOG_RESULT))
669                         {
670                                 return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
671                         }
672
673                         return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
674                 }
675         }
676 };
677
678 class StencilParamsBasicTestCase : public TestCase
679 {
680 protected:
681         TestInstance* createInstance(Context& context) const
682         {
683                 return new StencilParamsBasicTestInstance(context, "VertexFetch.vert", "VertexFetch.frag",
684                         m_writeMask, m_readMask, m_expectedValue, m_expectedColor);
685         }
686
687         virtual void initPrograms(vk::SourceCollections& programCollection) const
688         {
689                 programCollection.glslSources.add("VertexFetch.vert") <<
690                         glu::VertexSource(ShaderSourceProvider::getSource(m_testCtx.getArchive(), "vulkan/dynamic_state/VertexFetch.vert"));
691
692                 programCollection.glslSources.add("VertexFetch.frag") <<
693                         glu::FragmentSource(ShaderSourceProvider::getSource(m_testCtx.getArchive(), "vulkan/dynamic_state/VertexFetch.frag"));
694         }
695
696         deUint32 m_writeMask;
697         deUint32 m_readMask;
698         deUint32 m_expectedValue;
699         tcu::Vec4 m_expectedColor;
700
701 public:
702         StencilParamsBasicTestCase (tcu::TestContext& context, const char *name, const char *description,
703                                                                 const deUint32 writeMask, const deUint32 readMask,
704                                                                 const deUint32 expectedValue, const tcu::Vec4 expectedColor)
705                 : TestCase                              (context, name, description)
706                 , m_writeMask                   (writeMask)
707                 , m_readMask                    (readMask)
708                 , m_expectedValue               (expectedValue)
709                 , m_expectedColor               (expectedColor)
710         {
711         }
712 };
713
714 class StencilParamsAdvancedTestInstance : public DepthStencilBaseCase
715 {
716 public:
717         StencilParamsAdvancedTestInstance (Context& context, ShaderMap shaders)
718                 : DepthStencilBaseCase (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
719         {
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                 m_data.push_back(PositionColorVertex(tcu::Vec4(-0.5f, -0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
723                 m_data.push_back(PositionColorVertex(tcu::Vec4(0.5f, -0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
724
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                 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
728                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
729
730                 const PipelineCreateInfo::DepthStencilState::StencilOpState frontState_1 =
731                         PipelineCreateInfo::DepthStencilState::StencilOpState(
732                         vk::VK_STENCIL_OP_REPLACE,
733                         vk::VK_STENCIL_OP_REPLACE,
734                         vk::VK_STENCIL_OP_REPLACE,
735                         vk::VK_COMPARE_OP_ALWAYS);
736
737                 const PipelineCreateInfo::DepthStencilState::StencilOpState backState_1 =
738                         PipelineCreateInfo::DepthStencilState::StencilOpState(
739                         vk::VK_STENCIL_OP_REPLACE,
740                         vk::VK_STENCIL_OP_REPLACE,
741                         vk::VK_STENCIL_OP_REPLACE,
742                         vk::VK_COMPARE_OP_ALWAYS);
743
744                 const PipelineCreateInfo::DepthStencilState::StencilOpState frontState_2 =
745                         PipelineCreateInfo::DepthStencilState::StencilOpState(
746                         vk::VK_STENCIL_OP_REPLACE,
747                         vk::VK_STENCIL_OP_REPLACE,
748                         vk::VK_STENCIL_OP_REPLACE,
749                         vk::VK_COMPARE_OP_NOT_EQUAL);
750
751                 const PipelineCreateInfo::DepthStencilState::StencilOpState backState_2 =
752                         PipelineCreateInfo::DepthStencilState::StencilOpState(
753                         vk::VK_STENCIL_OP_REPLACE,
754                         vk::VK_STENCIL_OP_REPLACE,
755                         vk::VK_STENCIL_OP_REPLACE,
756                         vk::VK_COMPARE_OP_NOT_EQUAL);
757
758                 // enable stencil test
759                 m_depthStencilState_1 = PipelineCreateInfo::DepthStencilState(
760                         vk::VK_FALSE, vk::VK_FALSE, vk::VK_COMPARE_OP_NEVER, vk::VK_FALSE, vk::VK_TRUE, frontState_1, backState_1);
761
762                 m_depthStencilState_2 = PipelineCreateInfo::DepthStencilState(
763                         vk::VK_FALSE, vk::VK_FALSE, vk::VK_COMPARE_OP_NEVER, vk::VK_FALSE, vk::VK_TRUE, frontState_2, backState_2);
764
765                 DepthStencilBaseCase::initialize();
766         }
767
768         virtual tcu::TestStatus iterate (void)
769         {
770                 tcu::TestLog &log = m_context.getTestContext().getLog();
771                 const vk::VkQueue queue = m_context.getUniversalQueue();
772
773                 beginRenderPass();
774
775                 // set states here
776                 setDynamicViewportState(WIDTH, HEIGHT);
777                 setDynamicRasterizationState();
778                 setDynamicBlendState();
779
780                 const vk::VkDeviceSize vertexBufferOffset = 0;
781                 const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
782                 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
783
784                 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline_1);
785                 setDynamicDepthStencilState(-1.0f, 1.0f, 0xFF, 0x0E, 0x0F, 0xFF, 0x0E, 0x0F);
786                 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
787
788                 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline_2);
789                 setDynamicDepthStencilState(-1.0f, 1.0f, 0xFF, 0xFF, 0x0E, 0xFF, 0xFF, 0x0E);
790                 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 4, 0);
791
792                 m_vk.cmdEndRenderPass(*m_cmdBuffer);
793                 m_vk.endCommandBuffer(*m_cmdBuffer);
794
795                 vk::VkSubmitInfo submitInfo =
796                 {
797                         vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,      // VkStructureType                      sType;
798                         DE_NULL,                                                        // const void*                          pNext;
799                         0,                                                                      // deUint32                                     waitSemaphoreCount;
800                         DE_NULL,                                                        // const VkSemaphore*           pWaitSemaphores;
801                         (const vk::VkPipelineStageFlags*)DE_NULL,
802                         1,                                                                      // deUint32                                     commandBufferCount;
803                         &m_cmdBuffer.get(),                                     // const VkCommandBuffer*       pCommandBuffers;
804                         0,                                                                      // deUint32                                     signalSemaphoreCount;
805                         DE_NULL                                                         // const VkSemaphore*           pSignalSemaphores;
806                 };
807                 m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL);
808
809                 // validation
810                 {
811                         VK_CHECK(m_vk.queueWaitIdle(queue));
812
813                         tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
814                         referenceFrame.allocLevel(0);
815
816                         const deInt32 frameWidth = referenceFrame.getWidth();
817                         const deInt32 frameHeight = referenceFrame.getHeight();
818
819                         for (int y = 0; y < frameHeight; y++)
820                         {
821                                 const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
822
823                                 for (int x = 0; x < frameWidth; x++)
824                                 {
825                                         const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
826
827                                         if (xCoord >= -0.5f && xCoord <= 0.5f && yCoord >= -0.5f && yCoord <= 0.5f)
828                                                 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
829                                         else
830                                                 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
831                                 }
832                         }
833
834                         const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
835                         const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
836                                 vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
837
838                         if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
839                                 referenceFrame.getLevel(0), renderedFrame, 0.05f,
840                                 tcu::COMPARE_LOG_RESULT))
841                         {
842                                 return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
843                         }
844
845                         return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
846                 }
847         }
848 };
849
850 } //anonymous
851
852 DynamicStateDSTests::DynamicStateDSTests (tcu::TestContext& testCtx)
853         : TestCaseGroup (testCtx, "ds_state", "Tests for depth stencil state")
854 {
855         /* Left blank on purpose */
856 }
857
858 DynamicStateDSTests::~DynamicStateDSTests ()
859 {
860 }
861
862 void DynamicStateDSTests::init (void)
863 {
864         ShaderMap shaderPaths;
865         shaderPaths[glu::SHADERTYPE_VERTEX] = "vulkan/dynamic_state/VertexFetch.vert";
866         shaderPaths[glu::SHADERTYPE_FRAGMENT] = "vulkan/dynamic_state/VertexFetch.frag";
867
868         addChild(new InstanceFactory<DepthBoundsParamTestInstance>(m_testCtx, "depth_bounds", "Perform depth bounds test", shaderPaths));
869         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)));
870         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)));
871         addChild(new InstanceFactory<StencilParamsAdvancedTestInstance>(m_testCtx, "stencil_params_advanced", "Perform advanced stencil test", shaderPaths));
872 }
873
874 } // DynamicState
875 } // vkt