Merge pull request #276 from Ella-0/master
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / dynamic_state / vktDynamicStateRSTests.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 Raster State Tests
23  *//*--------------------------------------------------------------------*/
24
25 #include "vktDynamicStateRSTests.hpp"
26
27 #include "vktDynamicStateBaseClass.hpp"
28 #include "vktDynamicStateTestCaseUtil.hpp"
29
30 #include "vkImageUtil.hpp"
31 #include "vkTypeUtil.hpp"
32 #include "vkCmdUtil.hpp"
33 #include "vkObjUtil.hpp"
34 #include "vkBuilderUtil.hpp"
35
36 #include "tcuTextureUtil.hpp"
37 #include "tcuImageCompare.hpp"
38 #include "tcuRGBA.hpp"
39
40 #include "deMath.h"
41
42 #include <vector>
43 #include <string>
44 #include <sstream>
45 #include <iomanip>
46
47 namespace vkt
48 {
49 namespace DynamicState
50 {
51
52 using namespace Draw;
53
54 namespace
55 {
56
57 class DepthBiasBaseCase : public TestInstance
58 {
59 public:
60         DepthBiasBaseCase (Context& context, const char* vertexShaderName, const char* fragmentShaderName)
61                 : TestInstance                                          (context)
62                 , m_colorAttachmentFormat                       (vk::VK_FORMAT_R8G8B8A8_UNORM)
63                 , m_depthStencilAttachmentFormat        (vk::VK_FORMAT_UNDEFINED)
64                 , m_topology                                            (vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
65                 , m_vk                                                          (context.getDeviceInterface())
66                 , m_vertexShaderName                            (vertexShaderName)
67                 , m_fragmentShaderName                          (fragmentShaderName)
68         {
69         }
70
71 protected:
72
73         enum
74         {
75                 WIDTH   = 128,
76                 HEIGHT  = 128
77         };
78
79         vk::VkFormat                                                                    m_colorAttachmentFormat;
80         vk::VkFormat                                                                    m_depthStencilAttachmentFormat;
81
82         vk::VkPrimitiveTopology                                                 m_topology;
83
84         const vk::DeviceInterface&                                              m_vk;
85
86         vk::Move<vk::VkPipeline>                                                m_pipeline;
87         vk::Move<vk::VkPipelineLayout>                                  m_pipelineLayout;
88
89         de::SharedPtr<Image>                                                    m_colorTargetImage;
90         vk::Move<vk::VkImageView>                                               m_colorTargetView;
91
92         de::SharedPtr<Image>                                                    m_depthStencilImage;
93         vk::Move<vk::VkImageView>                                               m_attachmentView;
94
95         PipelineCreateInfo::VertexInputState                    m_vertexInputState;
96         de::SharedPtr<Buffer>                                                   m_vertexBuffer;
97
98         vk::Move<vk::VkCommandPool>                                             m_cmdPool;
99         vk::Move<vk::VkCommandBuffer>                                   m_cmdBuffer;
100
101         vk::Move<vk::VkFramebuffer>                                             m_framebuffer;
102         vk::Move<vk::VkRenderPass>                                              m_renderPass;
103
104         std::string                                                                             m_vertexShaderName;
105         std::string                                                                             m_fragmentShaderName;
106
107         std::vector<PositionColorVertex>                                m_data;
108
109         PipelineCreateInfo::DepthStencilState                   m_depthStencilState;
110
111         void initialize (void)
112         {
113                 const vk::VkDevice device       = m_context.getDevice();
114
115                 vk::VkFormatProperties formatProperties;
116                 // check for VK_FORMAT_D24_UNORM_S8_UINT support
117                 m_context.getInstanceInterface().getPhysicalDeviceFormatProperties(m_context.getPhysicalDevice(), vk::VK_FORMAT_D24_UNORM_S8_UINT, &formatProperties);
118                 if (formatProperties.optimalTilingFeatures & vk::VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
119                 {
120                         m_depthStencilAttachmentFormat = vk::VK_FORMAT_D24_UNORM_S8_UINT;
121                 }
122                 else
123                 {
124                         // check for VK_FORMAT_D32_SFLOAT_S8_UINT support
125                         m_context.getInstanceInterface().getPhysicalDeviceFormatProperties(m_context.getPhysicalDevice(), vk::VK_FORMAT_D32_SFLOAT_S8_UINT, &formatProperties);
126                         if (formatProperties.optimalTilingFeatures & vk::VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
127                         {
128                                 m_depthStencilAttachmentFormat = vk::VK_FORMAT_D32_SFLOAT_S8_UINT;
129                         }
130                         else
131                                 throw tcu::NotSupportedError("No valid depth stencil attachment available");
132                 }
133
134                 const PipelineLayoutCreateInfo pipelineLayoutCreateInfo;
135                 m_pipelineLayout                        = vk::createPipelineLayout(m_vk, device, &pipelineLayoutCreateInfo);
136
137                 const vk::Unique<vk::VkShaderModule> vs(createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_vertexShaderName), 0));
138                 const vk::Unique<vk::VkShaderModule> fs(createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_fragmentShaderName), 0));
139
140                 const vk::VkExtent3D imageExtent = { WIDTH, HEIGHT, 1 };
141                 ImageCreateInfo targetImageCreateInfo(vk::VK_IMAGE_TYPE_2D, m_colorAttachmentFormat, imageExtent, 1, 1, vk::VK_SAMPLE_COUNT_1_BIT, vk::VK_IMAGE_TILING_OPTIMAL,
142                                                                                           vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
143
144                 m_colorTargetImage = Image::createAndAlloc(m_vk, device, targetImageCreateInfo, m_context.getDefaultAllocator(), m_context.getUniversalQueueFamilyIndex());
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 | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
149
150                 m_depthStencilImage = Image::createAndAlloc(m_vk, device, depthStencilImageCreateInfo, m_context.getDefaultAllocator(), m_context.getUniversalQueueFamilyIndex());
151
152                 const ImageViewCreateInfo colorTargetViewInfo(m_colorTargetImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, m_colorAttachmentFormat);
153                 m_colorTargetView = vk::createImageView(m_vk, device, &colorTargetViewInfo);
154
155                 const ImageViewCreateInfo attachmentViewInfo(m_depthStencilImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, m_depthStencilAttachmentFormat);
156                 m_attachmentView = vk::createImageView(m_vk, device, &attachmentViewInfo);
157
158                 RenderPassCreateInfo renderPassCreateInfo;
159                 renderPassCreateInfo.addAttachment(AttachmentDescription(m_colorAttachmentFormat,
160                                                                                                                                  vk::VK_SAMPLE_COUNT_1_BIT,
161                                                                                                                                  vk::VK_ATTACHMENT_LOAD_OP_LOAD,
162                                                                                                                                  vk::VK_ATTACHMENT_STORE_OP_STORE,
163                                                                                                                                  vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
164                                                                                                                                  vk::VK_ATTACHMENT_STORE_OP_STORE,
165                                                                                                                                  vk::VK_IMAGE_LAYOUT_GENERAL,
166                                                                                                                                  vk::VK_IMAGE_LAYOUT_GENERAL));
167
168                 renderPassCreateInfo.addAttachment(AttachmentDescription(m_depthStencilAttachmentFormat,
169                                                                                                                                  vk::VK_SAMPLE_COUNT_1_BIT,
170                                                                                                                                  vk::VK_ATTACHMENT_LOAD_OP_LOAD,
171                                                                                                                                  vk::VK_ATTACHMENT_STORE_OP_STORE,
172                                                                                                                                  vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
173                                                                                                                                  vk::VK_ATTACHMENT_STORE_OP_STORE,
174                                                                                                                                  vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
175                                                                                                                                  vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
176
177                 const vk::VkAttachmentReference colorAttachmentReference =
178                 {
179                         0,
180                         vk::VK_IMAGE_LAYOUT_GENERAL
181                 };
182
183                 const vk::VkAttachmentReference depthAttachmentReference =
184                 {
185                         1,
186                         vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
187                 };
188
189                 renderPassCreateInfo.addSubpass(SubpassDescription(vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
190                                                                                                                    0,
191                                                                                                                    0,
192                                                                                                                    DE_NULL,
193                                                                                                                    1,
194                                                                                                                    &colorAttachmentReference,
195                                                                                                                    DE_NULL,
196                                                                                                                    depthAttachmentReference,
197                                                                                                                    0,
198                                                                                                                    DE_NULL));
199
200                 m_renderPass = vk::createRenderPass(m_vk, device, &renderPassCreateInfo);
201
202                 const vk::VkVertexInputBindingDescription vertexInputBindingDescription =
203                 {
204                         0,
205                         (deUint32)sizeof(tcu::Vec4) * 2,
206                         vk::VK_VERTEX_INPUT_RATE_VERTEX,
207                 };
208
209                 const vk::VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
210                 {
211                         {
212                                 0u,
213                                 0u,
214                                 vk::VK_FORMAT_R32G32B32A32_SFLOAT,
215                                 0u
216                         },
217                         {
218                                 1u,
219                                 0u,
220                                 vk::VK_FORMAT_R32G32B32A32_SFLOAT,
221                                 (deUint32)(sizeof(float)* 4),
222                         }
223                 };
224
225                 m_vertexInputState = PipelineCreateInfo::VertexInputState(1,
226                                                                                                                                   &vertexInputBindingDescription,
227                                                                                                                                   2,
228                                                                                                                                   vertexInputAttributeDescriptions);
229
230                 const PipelineCreateInfo::ColorBlendState::Attachment vkCbAttachmentState;
231
232                 PipelineCreateInfo pipelineCreateInfo(*m_pipelineLayout, *m_renderPass, 0, 0);
233                 pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", vk::VK_SHADER_STAGE_VERTEX_BIT));
234                 pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, "main", vk::VK_SHADER_STAGE_FRAGMENT_BIT));
235                 pipelineCreateInfo.addState(PipelineCreateInfo::VertexInputState(m_vertexInputState));
236                 pipelineCreateInfo.addState(PipelineCreateInfo::InputAssemblerState(m_topology));
237                 pipelineCreateInfo.addState(PipelineCreateInfo::ColorBlendState(1, &vkCbAttachmentState));
238                 pipelineCreateInfo.addState(PipelineCreateInfo::ViewportState(1));
239                 pipelineCreateInfo.addState(m_depthStencilState);
240                 pipelineCreateInfo.addState(PipelineCreateInfo::RasterizerState());
241                 pipelineCreateInfo.addState(PipelineCreateInfo::MultiSampleState());
242                 pipelineCreateInfo.addState(PipelineCreateInfo::DynamicState());
243
244                 m_pipeline = vk::createGraphicsPipeline(m_vk, device, DE_NULL, &pipelineCreateInfo);
245
246                 std::vector<vk::VkImageView> attachments(2);
247                 attachments[0] = *m_colorTargetView;
248                 attachments[1] = *m_attachmentView;
249
250                 const FramebufferCreateInfo framebufferCreateInfo(*m_renderPass, attachments, WIDTH, HEIGHT, 1);
251
252                 m_framebuffer = vk::createFramebuffer(m_vk, device, &framebufferCreateInfo);
253
254                 const vk::VkDeviceSize dataSize = m_data.size() * sizeof(PositionColorVertex);
255                 m_vertexBuffer = Buffer::createAndAlloc(m_vk, device, BufferCreateInfo(dataSize,
256                         vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT),
257                         m_context.getDefaultAllocator(), vk::MemoryRequirement::HostVisible);
258
259                 deUint8* ptr = reinterpret_cast<unsigned char *>(m_vertexBuffer->getBoundMemory().getHostPtr());
260                 deMemcpy(ptr, &m_data[0], static_cast<size_t>(dataSize));
261
262                 vk::flushAlloc(m_vk, device, m_vertexBuffer->getBoundMemory());
263
264                 const CmdPoolCreateInfo cmdPoolCreateInfo(m_context.getUniversalQueueFamilyIndex());
265                 m_cmdPool = vk::createCommandPool(m_vk, device, &cmdPoolCreateInfo);
266                 m_cmdBuffer = vk::allocateCommandBuffer(m_vk, device, *m_cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
267         }
268
269         virtual tcu::TestStatus iterate (void)
270         {
271                 DE_ASSERT(false);
272                 return tcu::TestStatus::fail("Should reimplement iterate() method");
273         }
274
275         void beginRenderPass (void)
276         {
277                 const vk::VkClearColorValue clearColor = { { 0.0f, 0.0f, 0.0f, 1.0f } };
278                 beginRenderPassWithClearColor(clearColor);
279         }
280
281         void beginRenderPassWithClearColor (const vk::VkClearColorValue &clearColor)
282         {
283                 beginCommandBuffer(m_vk, *m_cmdBuffer, 0u);
284
285                 initialTransitionColor2DImage(m_vk, *m_cmdBuffer, m_colorTargetImage->object(), vk::VK_IMAGE_LAYOUT_GENERAL,
286                                                                           vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT);
287                 initialTransitionDepthStencil2DImage(m_vk, *m_cmdBuffer, m_depthStencilImage->object(), vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
288                                                                                          vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT);
289
290                 const ImageSubresourceRange subresourceRangeImage(vk::VK_IMAGE_ASPECT_COLOR_BIT);
291                 m_vk.cmdClearColorImage(*m_cmdBuffer, m_colorTargetImage->object(),
292                                                                 vk::VK_IMAGE_LAYOUT_GENERAL, &clearColor, 1, &subresourceRangeImage);
293
294                 const vk::VkClearDepthStencilValue depthStencilClearValue = { 0.0f, 0 };
295
296                 const ImageSubresourceRange subresourceRangeDepthStencil[2] = { vk::VK_IMAGE_ASPECT_DEPTH_BIT, vk::VK_IMAGE_ASPECT_STENCIL_BIT };
297
298                 m_vk.cmdClearDepthStencilImage(*m_cmdBuffer, m_depthStencilImage->object(),
299                                                                            vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &depthStencilClearValue, 2, subresourceRangeDepthStencil);
300
301                 const vk::VkMemoryBarrier memBarrier =
302                 {
303                         vk::VK_STRUCTURE_TYPE_MEMORY_BARRIER,
304                         DE_NULL,
305                         vk::VK_ACCESS_TRANSFER_WRITE_BIT,
306                         vk::VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
307                                 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
308                 };
309
310                 m_vk.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
311                         vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
312                         vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
313                         0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
314
315                 transition2DImage(m_vk, *m_cmdBuffer, m_depthStencilImage->object(), vk::VK_IMAGE_ASPECT_DEPTH_BIT | vk::VK_IMAGE_ASPECT_STENCIL_BIT,
316                                                   vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
317                                                   vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
318                                                   vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
319
320                 vk::beginRenderPass(m_vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, vk::makeRect2D(0, 0, WIDTH, HEIGHT));
321         }
322
323         void setDynamicViewportState (const deUint32 width, const deUint32 height)
324         {
325                 vk::VkViewport viewport = vk::makeViewport(tcu::UVec2(width, height));
326                 m_vk.cmdSetViewport(*m_cmdBuffer, 0, 1, &viewport);
327
328                 vk::VkRect2D scissor = vk::makeRect2D(tcu::UVec2(width, height));
329                 m_vk.cmdSetScissor(*m_cmdBuffer, 0, 1, &scissor);
330         }
331
332         void setDynamicViewportState (const deUint32 viewportCount, const vk::VkViewport* pViewports, const vk::VkRect2D* pScissors)
333         {
334                 m_vk.cmdSetViewport(*m_cmdBuffer, 0, viewportCount, pViewports);
335                 m_vk.cmdSetScissor(*m_cmdBuffer, 0, viewportCount, pScissors);
336         }
337
338         void setDynamicRasterizationState (const float lineWidth = 1.0f,
339                 const float depthBiasConstantFactor = 0.0f,
340                 const float depthBiasClamp = 0.0f,
341                 const float depthBiasSlopeFactor = 0.0f)
342         {
343                 m_vk.cmdSetLineWidth(*m_cmdBuffer, lineWidth);
344                 m_vk.cmdSetDepthBias(*m_cmdBuffer, depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor);
345         }
346
347         void setDynamicBlendState (const float const1 = 0.0f, const float const2 = 0.0f,
348                 const float const3 = 0.0f, const float const4 = 0.0f)
349         {
350                 float blendConstantsants[4] = { const1, const2, const3, const4 };
351                 m_vk.cmdSetBlendConstants(*m_cmdBuffer, blendConstantsants);
352         }
353
354         void setDynamicDepthStencilState (const float minDepthBounds = -1.0f, const float maxDepthBounds = 1.0f,
355                 const deUint32 stencilFrontCompareMask = 0xffffffffu, const deUint32 stencilFrontWriteMask = 0xffffffffu,
356                 const deUint32 stencilFrontReference = 0, const deUint32 stencilBackCompareMask = 0xffffffffu,
357                 const deUint32 stencilBackWriteMask = 0xffffffffu, const deUint32 stencilBackReference = 0)
358         {
359                 m_vk.cmdSetDepthBounds(*m_cmdBuffer, minDepthBounds, maxDepthBounds);
360                 m_vk.cmdSetStencilCompareMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontCompareMask);
361                 m_vk.cmdSetStencilWriteMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontWriteMask);
362                 m_vk.cmdSetStencilReference(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontReference);
363                 m_vk.cmdSetStencilCompareMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackCompareMask);
364                 m_vk.cmdSetStencilWriteMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackWriteMask);
365                 m_vk.cmdSetStencilReference(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackReference);
366         }
367 };
368
369 class DepthBiasParamTestInstance : public DepthBiasBaseCase
370 {
371 public:
372         DepthBiasParamTestInstance (Context& context, ShaderMap shaders)
373                 : DepthBiasBaseCase (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
374         {
375                 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 0.5f, 1.0f), tcu::RGBA::blue().toVec()));
376                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 0.5f, 1.0f), tcu::RGBA::blue().toVec()));
377                 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 0.5f, 1.0f), tcu::RGBA::blue().toVec()));
378                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 0.5f, 1.0f), tcu::RGBA::blue().toVec()));
379
380                 m_data.push_back(PositionColorVertex(tcu::Vec4(-0.5f, 0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
381                 m_data.push_back(PositionColorVertex(tcu::Vec4(0.5f, 0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
382                 m_data.push_back(PositionColorVertex(tcu::Vec4(-0.5f, -0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
383                 m_data.push_back(PositionColorVertex(tcu::Vec4(0.5f, -0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
384
385                 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 0.5f, 1.0f), tcu::RGBA::red().toVec()));
386                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 0.5f, 1.0f), tcu::RGBA::red().toVec()));
387                 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 0.5f, 1.0f), tcu::RGBA::red().toVec()));
388                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 0.5f, 1.0f), tcu::RGBA::red().toVec()));
389
390                 // enable depth test
391                 m_depthStencilState = PipelineCreateInfo::DepthStencilState(
392                         VK_TRUE, VK_TRUE, vk::VK_COMPARE_OP_GREATER_OR_EQUAL);
393
394                 DepthBiasBaseCase::initialize();
395         }
396
397         virtual tcu::TestStatus iterate (void)
398         {
399                 tcu::TestLog&           log             = m_context.getTestContext().getLog();
400                 const vk::VkQueue       queue   = m_context.getUniversalQueue();
401                 const vk::VkDevice      device  = m_context.getDevice();
402
403                 beginRenderPass();
404
405                 // set states here
406                 setDynamicViewportState(WIDTH, HEIGHT);
407                 setDynamicBlendState();
408                 setDynamicDepthStencilState();
409
410                 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
411
412                 const vk::VkDeviceSize vertexBufferOffset       = 0;
413                 const vk::VkBuffer vertexBuffer                         = m_vertexBuffer->object();
414                 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
415
416                 setDynamicRasterizationState(1.0f, 0.0f);
417                 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
418                 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 4, 0);
419
420                 setDynamicRasterizationState(1.0f, -1.0f);
421                 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 8, 0);
422
423                 endRenderPass(m_vk, *m_cmdBuffer);
424                 endCommandBuffer(m_vk, *m_cmdBuffer);
425
426                 submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
427
428                 // validation
429                 {
430                         VK_CHECK(m_vk.queueWaitIdle(queue));
431
432                         tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5f + static_cast<float>(WIDTH)), (int)(0.5f + static_cast<float>(HEIGHT)));
433                         referenceFrame.allocLevel(0);
434
435                         const deInt32 frameWidth = referenceFrame.getWidth();
436                         const deInt32 frameHeight = referenceFrame.getHeight();
437
438                         tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
439
440                         for (int y = 0; y < frameHeight; y++)
441                         {
442                                 const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
443
444                                 for (int x = 0; x < frameWidth; x++)
445                                 {
446                                         const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
447
448                                         if (xCoord >= -0.5f && xCoord <= 0.5f && yCoord >= -0.5f && yCoord <= 0.5f)
449                                                 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
450                                         else
451                                                 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
452                                 }
453                         }
454
455                         const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
456                         const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
457                                 vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
458
459                         if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
460                                 referenceFrame.getLevel(0), renderedFrame, 0.05f,
461                                 tcu::COMPARE_LOG_RESULT))
462                         {
463                                 return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
464                         }
465
466                         return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
467                 }
468         }
469 };
470
471 class DepthBiasClampParamTestInstance : public DepthBiasBaseCase
472 {
473 public:
474         DepthBiasClampParamTestInstance (Context& context, ShaderMap shaders)
475                 : DepthBiasBaseCase (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
476         {
477                 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f), tcu::RGBA::blue().toVec()));
478                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f), tcu::RGBA::blue().toVec()));
479                 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f), tcu::RGBA::blue().toVec()));
480                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 0.0f, 1.0f), tcu::RGBA::blue().toVec()));
481
482                 m_data.push_back(PositionColorVertex(tcu::Vec4(-0.5f, 0.5f, 0.01f, 1.0f), tcu::RGBA::green().toVec()));
483                 m_data.push_back(PositionColorVertex(tcu::Vec4(0.5f, 0.5f, 0.01f, 1.0f), tcu::RGBA::green().toVec()));
484                 m_data.push_back(PositionColorVertex(tcu::Vec4(-0.5f, -0.5f, 0.01f, 1.0f), tcu::RGBA::green().toVec()));
485                 m_data.push_back(PositionColorVertex(tcu::Vec4(0.5f, -0.5f, 0.01f, 1.0f), tcu::RGBA::green().toVec()));
486
487                 // enable depth test
488                 m_depthStencilState = PipelineCreateInfo::DepthStencilState(VK_TRUE, VK_TRUE, vk::VK_COMPARE_OP_GREATER_OR_EQUAL);
489
490                 DepthBiasBaseCase::initialize();
491         }
492
493         virtual tcu::TestStatus iterate (void)
494         {
495                 tcu::TestLog&           log             = m_context.getTestContext().getLog();
496                 const vk::VkQueue       queue   = m_context.getUniversalQueue();
497                 const vk::VkDevice      device  = m_context.getDevice();
498
499                 beginRenderPass();
500
501                 // set states here
502                 setDynamicViewportState(WIDTH, HEIGHT);
503                 setDynamicBlendState();
504                 setDynamicDepthStencilState();
505
506                 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
507
508                 const vk::VkDeviceSize vertexBufferOffset = 0;
509                 const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
510                 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
511
512                 setDynamicRasterizationState(1.0f, 1000.0f, 0.005f);
513                 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
514
515                 setDynamicRasterizationState(1.0f, 0.0f);
516                 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 4, 0);
517
518                 endRenderPass(m_vk, *m_cmdBuffer);
519                 endCommandBuffer(m_vk, *m_cmdBuffer);
520
521                 submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
522
523                 // validation
524                 {
525                         tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5f + static_cast<float>(WIDTH)), (int)(0.5f + static_cast<float>(HEIGHT)));
526                         referenceFrame.allocLevel(0);
527
528                         const deInt32 frameWidth        = referenceFrame.getWidth();
529                         const deInt32 frameHeight       = referenceFrame.getHeight();
530
531                         tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
532
533                         for (int y = 0; y < frameHeight; y++)
534                         {
535                                 float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
536
537                                 for (int x = 0; x < frameWidth; x++)
538                                 {
539                                         float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
540
541                                         if (xCoord >= -0.5f && xCoord <= 0.5f && yCoord >= -0.5f && yCoord <= 0.5f)
542                                                 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
543                                         else
544                                                 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
545                                 }
546                         }
547
548                         const vk::VkOffset3D zeroOffset                                 = { 0, 0, 0 };
549                         const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
550                                 vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
551
552                         if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
553                                 referenceFrame.getLevel(0), renderedFrame, 0.05f,
554                                 tcu::COMPARE_LOG_RESULT))
555                         {
556                                 return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
557                         }
558
559                         return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
560                 }
561         }
562 };
563
564 class LineWidthParamTestInstance : public DynamicStateBaseClass
565 {
566 public:
567         LineWidthParamTestInstance (Context& context, ShaderMap shaders)
568                 : DynamicStateBaseClass (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
569         {
570                 m_topology = vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
571
572                 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 0.0f, 0.0f, 1.0f), tcu::RGBA::green().toVec()));
573                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::RGBA::green().toVec()));
574
575                 DynamicStateBaseClass::initialize();
576         }
577
578         virtual tcu::TestStatus iterate (void)
579         {
580                 tcu::TestLog&           log             = m_context.getTestContext().getLog();
581                 const vk::VkQueue       queue   = m_context.getUniversalQueue();
582                 const vk::VkDevice      device  = m_context.getDevice();
583
584                 beginRenderPass();
585
586                 // set states here
587                 vk::VkPhysicalDeviceProperties deviceProperties;
588                 m_context.getInstanceInterface().getPhysicalDeviceProperties(m_context.getPhysicalDevice(), &deviceProperties);
589
590                 setDynamicViewportState(WIDTH, HEIGHT);
591                 setDynamicBlendState();
592                 setDynamicDepthStencilState();
593                 setDynamicRasterizationState(deFloatFloor(deviceProperties.limits.lineWidthRange[1]));
594
595                 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
596
597                 const vk::VkDeviceSize vertexBufferOffset       = 0;
598                 const vk::VkBuffer vertexBuffer                         = m_vertexBuffer->object();
599                 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
600
601                 m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
602
603                 endRenderPass(m_vk, *m_cmdBuffer);
604                 endCommandBuffer(m_vk, *m_cmdBuffer);
605
606                 submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
607
608                 // validation
609                 {
610                         tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5f + static_cast<float>(WIDTH)), (int)(0.5f + static_cast<float>(HEIGHT)));
611                         referenceFrame.allocLevel(0);
612
613                         const deInt32 frameWidth = referenceFrame.getWidth();
614                         const deInt32 frameHeight = referenceFrame.getHeight();
615
616                         tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
617
618                         for (int y = 0; y < frameHeight; y++)
619                         {
620                                 float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
621
622                                 for (int x = 0; x < frameWidth; x++)
623                                 {
624                                         float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
625                                         float lineHalfWidth = (float)(deFloor(deviceProperties.limits.lineWidthRange[1]) / frameHeight);
626
627                                         if (xCoord >= -1.0f && xCoord <= 1.0f && yCoord >= -lineHalfWidth && yCoord <= lineHalfWidth)
628                                                 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
629                                 }
630                         }
631
632                         const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
633                         const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
634                                                                                                                                                                                           vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT,
635                                                                                                                                                                                           vk::VK_IMAGE_ASPECT_COLOR_BIT);
636
637                         if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
638                                 referenceFrame.getLevel(0), renderedFrame, 0.05f,
639                                 tcu::COMPARE_LOG_RESULT))
640                         {
641                                 return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
642                         }
643
644                         return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
645                 }
646         }
647 };
648
649 void checkDepthBiasClampSupport (Context& context)
650 {
651         context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_DEPTH_BIAS_CLAMP);
652 }
653
654 void checkWideLinesSupport (Context& context)
655 {
656         context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_WIDE_LINES);
657 }
658
659 // Tests that fail if both the depth bias clamp or depth constant factor stay at 0.0f instead of applying the real values.
660 struct DepthBiasNonZeroPushConstants
661 {
662         float geometryDepth;
663         float minDepth;
664         float maxDepth;
665 };
666
667 struct DepthBiasNonZeroParams
668 {
669         float                                                   depthBiasConstant;
670         float                                                   depthBiasClamp;
671         DepthBiasNonZeroPushConstants   pushConstants;
672 };
673
674 class DepthBiasNonZeroCase : public vkt::TestCase
675 {
676 private:
677         DepthBiasNonZeroParams m_params;
678
679 public:
680                                                 DepthBiasNonZeroCase    (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const DepthBiasNonZeroParams& params);
681         virtual                         ~DepthBiasNonZeroCase   (void) {}
682
683         void                            checkSupport                    (Context& context) const override;
684         void                            initPrograms                    (vk::SourceCollections& programCollection) const override;
685         TestInstance*           createInstance                  (Context& context) const override;
686
687         static tcu::Vec4        getExpectedColor                () { return tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f); }
688 };
689
690 class DepthBiasNonZeroInstance : public vkt::TestInstance
691 {
692 private:
693         DepthBiasNonZeroParams m_params;
694
695 public:
696                                                 DepthBiasNonZeroInstance        (Context& context, const DepthBiasNonZeroParams& params);
697         virtual                         ~DepthBiasNonZeroInstance       (void) {}
698
699         tcu::TestStatus         iterate                                         (void) override;
700 };
701
702 DepthBiasNonZeroCase::DepthBiasNonZeroCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const DepthBiasNonZeroParams& params)
703         : vkt::TestCase         (testCtx, name, description)
704         , m_params                      (params)
705 {}
706
707 TestInstance* DepthBiasNonZeroCase::createInstance (Context& context) const
708 {
709         return new DepthBiasNonZeroInstance(context, m_params);
710 }
711
712 DepthBiasNonZeroInstance::DepthBiasNonZeroInstance (Context& context, const DepthBiasNonZeroParams& params)
713         : vkt::TestInstance     (context)
714         , m_params                      (params)
715 {}
716
717 void DepthBiasNonZeroCase::checkSupport (Context& context) const
718 {
719         const auto& features = context.getDeviceFeatures();
720         if (m_params.depthBiasClamp != 0.0f && !features.depthBiasClamp)
721                 TCU_THROW(NotSupportedError, "Depth bias clamping not supported");
722 }
723
724 void DepthBiasNonZeroCase::initPrograms (vk::SourceCollections& programCollection) const
725 {
726         std::ostringstream vert;
727         vert
728                 << "#version 450\n"
729                 << "\n"
730                 << "layout (push_constant, std430) uniform PushConstantBlock {\n"
731                 << "    float geometryDepth;\n"
732                 << "    float minDepth;\n"
733                 << "    float maxDepth;\n"
734                 << "} pc;\n"
735                 << "\n"
736                 << "vec2 positions[3] = vec2[](\n"
737                 << "    vec2(-1.0, -1.0),\n"
738                 << "    vec2(3.0, -1.0),\n"
739                 << "    vec2(-1.0, 3.0)\n"
740                 << ");\n"
741                 << "\n"
742                 << "void main() {\n"
743                 << "    gl_Position = vec4(positions[gl_VertexIndex], pc.geometryDepth, 1.0);\n"
744                 << "}\n"
745                 ;
746
747         const auto outColor = getExpectedColor();
748         std::ostringstream frag;
749         frag
750                 << std::fixed << std::setprecision(1)
751                 << "#version 450\n"
752                 << "\n"
753                 << "layout (push_constant, std430) uniform PushConstantBlock {\n"
754                 << "    float geometryDepth;\n"
755                 << "    float minDepth;\n"
756                 << "    float maxDepth;\n"
757                 << "} pc;\n"
758                 << "\n"
759                 << "layout (location=0) out vec4 outColor;\n"
760                 << "\n"
761                 << "void main() {\n"
762                 << "    const float depth = gl_FragCoord.z;\n"
763                 << "    if (depth >= pc.minDepth && depth <= pc.maxDepth) {\n"
764                 << "        outColor = vec4(" << outColor.x() << ", " << outColor.y() << ", " << outColor.z() << ", " << outColor.w() << ");\n"
765                 << "    }\n"
766                 << "}\n"
767                 ;
768
769         programCollection.glslSources.add("vert") << glu::VertexSource(vert.str());
770         programCollection.glslSources.add("frag") << glu::FragmentSource(frag.str());
771 }
772
773 tcu::TestStatus DepthBiasNonZeroInstance::iterate (void)
774 {
775         const auto&     vkd                     = m_context.getDeviceInterface();
776         const auto      device          = m_context.getDevice();
777         auto&           alloc           = m_context.getDefaultAllocator();
778         const auto      qIndex          = m_context.getUniversalQueueFamilyIndex();
779         const auto      queue           = m_context.getUniversalQueue();
780
781         const auto      depthFormat     = vk::VK_FORMAT_D16_UNORM;
782         const auto      colorFormat     = vk::VK_FORMAT_R8G8B8A8_UNORM;
783         const auto      colorUsage      = (vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
784         const auto      depthUsage      = (vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
785         const auto      extent          = vk::makeExtent3D(8u, 8u, 1u);
786         const auto&     pcData          = m_params.pushConstants;
787         const auto      pcDataSize      = static_cast<deUint32>(sizeof(pcData));
788         const auto      pcStages        = (vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT);
789         const auto      pcRange         = vk::makePushConstantRange(pcStages, 0u, pcDataSize);
790         const auto      renderPass      = vk::makeRenderPass(vkd, device, colorFormat, depthFormat, vk::VK_ATTACHMENT_LOAD_OP_CLEAR, vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
791         const auto      stencilOp       = vk::makeStencilOpState(vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_COMPARE_OP_NEVER, 0u, 0u, 0u);
792
793         // Color buffer.
794         const vk::VkImageCreateInfo colorBufferInfo =
795         {
796                 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,        //      VkStructureType                 sType;
797                 nullptr,                                                                        //      const void*                             pNext;
798                 0u,                                                                                     //      VkImageCreateFlags              flags;
799                 vk::VK_IMAGE_TYPE_2D,                                           //      VkImageType                             imageType;
800                 colorFormat,                                                            //      VkFormat                                format;
801                 extent,                                                                         //      VkExtent3D                              extent;
802                 1u,                                                                                     //      deUint32                                mipLevels;
803                 1u,                                                                                     //      deUint32                                arrayLayers;
804                 vk::VK_SAMPLE_COUNT_1_BIT,                                      //      VkSampleCountFlagBits   samples;
805                 vk::VK_IMAGE_TILING_OPTIMAL,                            //      VkImageTiling                   tiling;
806                 colorUsage,                                                                     //      VkImageUsageFlags               usage;
807                 vk::VK_SHARING_MODE_EXCLUSIVE,                          //      VkSharingMode                   sharingMode;
808                 0u,                                                                                     //      deUint32                                queueFamilyIndexCount;
809                 nullptr,                                                                        //      const deUint32*                 pQueueFamilyIndices;
810                 vk::VK_IMAGE_LAYOUT_UNDEFINED,                          //      VkImageLayout                   initialLayout;
811         };
812         const auto colorBuffer = Image::createAndAlloc(vkd, device, colorBufferInfo, alloc, qIndex);
813
814         // Depth buffer.
815         const vk::VkImageCreateInfo depthBufferInfo =
816         {
817                 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,        //      VkStructureType                 sType;
818                 nullptr,                                                                        //      const void*                             pNext;
819                 0u,                                                                                     //      VkImageCreateFlags              flags;
820                 vk::VK_IMAGE_TYPE_2D,                                           //      VkImageType                             imageType;
821                 depthFormat,                                                            //      VkFormat                                format;
822                 extent,                                                                         //      VkExtent3D                              extent;
823                 1u,                                                                                     //      deUint32                                mipLevels;
824                 1u,                                                                                     //      deUint32                                arrayLayers;
825                 vk::VK_SAMPLE_COUNT_1_BIT,                                      //      VkSampleCountFlagBits   samples;
826                 vk::VK_IMAGE_TILING_OPTIMAL,                            //      VkImageTiling                   tiling;
827                 depthUsage,                                                                     //      VkImageUsageFlags               usage;
828                 vk::VK_SHARING_MODE_EXCLUSIVE,                          //      VkSharingMode                   sharingMode;
829                 0u,                                                                                     //      deUint32                                queueFamilyIndexCount;
830                 nullptr,                                                                        //      const deUint32*                 pQueueFamilyIndices;
831                 vk::VK_IMAGE_LAYOUT_UNDEFINED,                          //      VkImageLayout                   initialLayout;
832         };
833         const auto depthBuffer = Image::createAndAlloc(vkd, device, depthBufferInfo, alloc, qIndex);
834
835         const auto colorSubresourceRange        = vk::makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
836         const auto colorView                            = vk::makeImageView(vkd, device, colorBuffer->object(), vk::VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresourceRange);
837
838         const auto depthSubresourceRange        = vk::makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 1u, 0u, 1u);
839         const auto depthView                            = vk::makeImageView(vkd, device, depthBuffer->object(), vk::VK_IMAGE_VIEW_TYPE_2D, depthFormat, depthSubresourceRange);
840
841         // Create framebuffer.
842         const std::vector<vk::VkImageView>      attachments     = { colorView.get(), depthView.get() };
843         const auto                                                      framebuffer     = vk::makeFramebuffer(vkd, device, renderPass.get(), static_cast<deUint32>(attachments.size()), de::dataOrNull(attachments), extent.width, extent.height);
844
845         // Descriptor set and pipeline layout.
846         vk::DescriptorSetLayoutBuilder setLayoutBuilder;
847         const auto dsLayout                     = setLayoutBuilder.build(vkd, device);
848         const auto pipelineLayout       = vk::makePipelineLayout(vkd, device, 1u, &dsLayout.get(), 1u, &pcRange);
849
850         // Shader modules.
851         const auto vertModule = vk::createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
852         const auto fragModule = vk::createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag"), 0u);
853
854         const std::vector<vk::VkViewport>       viewports       = { vk::makeViewport(extent) };
855         const std::vector<vk::VkRect2D>         scissors        = { vk::makeRect2D(extent) };
856
857         // Vertex input state without bindings and attributes.
858         const vk::VkPipelineVertexInputStateCreateInfo vertexInputInfo =
859         {
860                 vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,  // VkStructureType                             sType
861                 nullptr,                                                                                                                // const void*                                 pNext
862                 0u,                                                                                                                             // VkPipelineVertexInputStateCreateFlags       flags
863                 0u,                                                                                                                             // deUint32                                    vertexBindingDescriptionCount
864                 nullptr,                                                                                                                // const VkVertexInputBindingDescription*      pVertexBindingDescriptions
865                 0u,                                                                                                                             // deUint32                                    vertexAttributeDescriptionCount
866                 nullptr,                                                                                                                // const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions
867         };
868
869         // Depth/stencil state, with depth test and writes enabled.
870         const vk::VkPipelineDepthStencilStateCreateInfo depthStencilStateInfo =
871         {
872                 vk::VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType                          sType
873                 nullptr,                                                                                                                // const void*                              pNext
874                 0u,                                                                                                                             // VkPipelineDepthStencilStateCreateFlags   flags
875                 VK_TRUE,                                                                                                                // VkBool32                                 depthTestEnable
876                 VK_TRUE,                                                                                                                // VkBool32                                 depthWriteEnable
877                 vk::VK_COMPARE_OP_ALWAYS,                                                                               // VkCompareOp                              depthCompareOp
878                 VK_FALSE,                                                                                                               // VkBool32                                 depthBoundsTestEnable
879                 VK_FALSE,                                                                                                               // VkBool32                                 stencilTestEnable
880                 stencilOp,                                                                                                              // VkStencilOpState                         front
881                 stencilOp,                                                                                                              // VkStencilOpState                         back
882                 0.0f,                                                                                                                   // float                                    minDepthBounds
883                 1.0f,                                                                                                                   // float                                    maxDepthBounds
884         };
885
886         // Rasterization state with depth bias enabled.
887         const vk::VkPipelineRasterizationStateCreateInfo rasterizationInfo =
888         {
889                 vk::VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType                            sType
890                 nullptr,                                                                                                                // const void*                                pNext
891                 0u,                                                                                                                             // VkPipelineRasterizationStateCreateFlags    flags
892                 VK_FALSE,                                                                                                               // VkBool32                                   depthClampEnable
893                 VK_FALSE,                                                                                                               // VkBool32                                   rasterizerDiscardEnable
894                 vk::VK_POLYGON_MODE_FILL,                                                                               // VkPolygonMode                              polygonMode
895                 vk::VK_CULL_MODE_NONE,                                                                                  // VkCullModeFlags                            cullMode
896                 vk::VK_FRONT_FACE_CLOCKWISE,                                                                    // VkFrontFace                                frontFace
897                 VK_TRUE,                                                                                                                // VkBool32                                   depthBiasEnable
898                 0.0f,                                                                                                                   // float                                      depthBiasConstantFactor
899                 0.0f,                                                                                                                   // float                                      depthBiasClamp
900                 0.0f,                                                                                                                   // float                                      depthBiasSlopeFactor
901                 1.0f                                                                                                                    // float                                      lineWidth
902         };
903
904         // Dynamic state.
905         const std::vector<vk::VkDynamicState> dynamicStates (1u, vk::VK_DYNAMIC_STATE_DEPTH_BIAS);
906
907         const vk::VkPipelineDynamicStateCreateInfo dynamicStateInfo =
908         {
909                 vk::VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,       //      VkStructureType                                         sType;
910                 nullptr,                                                                                                        //      const void*                                                     pNext;
911                 0u,                                                                                                                     //      VkPipelineDynamicStateCreateFlags       flags;
912                 static_cast<deUint32>(dynamicStates.size()),                            //      deUint32                                                        dynamicStateCount;
913                 de::dataOrNull(dynamicStates),                                                          //      const VkDynamicState*                           pDynamicStates;
914         };
915
916         // Graphics pipeline.
917         const auto pipeline = vk::makeGraphicsPipeline(vkd, device, pipelineLayout.get(),
918                 vertModule.get(), DE_NULL, DE_NULL, DE_NULL, fragModule.get(), // shaders
919                 renderPass.get(), viewports, scissors, vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0u/*subpass*/, 0u/*patchControlPoints*/,
920                 &vertexInputInfo, &rasterizationInfo, nullptr, &depthStencilStateInfo, nullptr, &dynamicStateInfo);
921
922         // Command pool and buffer.
923         const auto cmdPool              = vk::makeCommandPool(vkd, device, qIndex);
924         const auto cmdBufferPtr = vk::allocateCommandBuffer(vkd, device, cmdPool.get(), vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
925         const auto cmdBuffer    = cmdBufferPtr.get();
926
927         // Clear colors.
928         const std::vector<vk::VkClearValue> clearColors =
929         {
930                 vk::makeClearValueColorF32(0.0f, 0.0f, 0.0f, 1.0f),
931                 vk::makeClearValueDepthStencil(0.0f, 0u),
932         };
933
934         vk::beginCommandBuffer(vkd, cmdBuffer);
935         vk::beginRenderPass(vkd, cmdBuffer, renderPass.get(), framebuffer.get(), scissors.at(0), static_cast<deUint32>(clearColors.size()), de::dataOrNull(clearColors));
936         vkd.cmdBindPipeline(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.get());
937         vkd.cmdSetDepthBias(cmdBuffer, m_params.depthBiasConstant, m_params.depthBiasClamp, 0.0f);
938         vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), pcStages, 0u, pcDataSize, &pcData);
939         vkd.cmdDraw(cmdBuffer, 3u, 1u, 0u, 0u);
940         vk::endRenderPass(vkd, cmdBuffer);
941         vk::endCommandBuffer(vkd, cmdBuffer);
942         vk::submitCommandsAndWait(vkd, device, queue, cmdBuffer);
943
944         // Check color buffer contents.
945         const auto              offset          = vk::makeOffset3D(0, 0, 0);
946         const auto              iWidth          = static_cast<int>(extent.width);
947         const auto              iHeight         = static_cast<int>(extent.height);
948         const auto              colorPixels     = colorBuffer->readSurface(queue, alloc, vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, offset, iWidth, iHeight, vk::VK_IMAGE_ASPECT_COLOR_BIT);
949         const auto              expected        = DepthBiasNonZeroCase::getExpectedColor();
950         const tcu::Vec4 threshold       (0.0f);
951         auto&                   log                     = m_context.getTestContext().getLog();
952
953         if (!tcu::floatThresholdCompare(log, "Result", "Result", expected, colorPixels, threshold, tcu::COMPARE_LOG_ON_ERROR))
954                 return tcu::TestStatus::fail("Unexpected color buffer value; check log for details");
955
956         return tcu::TestStatus::pass("Pass");
957 }
958
959 } //anonymous
960
961 DynamicStateRSTests::DynamicStateRSTests (tcu::TestContext& testCtx)
962         : TestCaseGroup (testCtx, "rs_state", "Tests for rasterizer state")
963 {
964         /* Left blank on purpose */
965 }
966
967 DynamicStateRSTests::~DynamicStateRSTests ()
968 {
969 }
970
971 void DynamicStateRSTests::init (void)
972 {
973         ShaderMap shaderPaths;
974         shaderPaths[glu::SHADERTYPE_VERTEX]             = "vulkan/dynamic_state/VertexFetch.vert";
975         shaderPaths[glu::SHADERTYPE_FRAGMENT]   = "vulkan/dynamic_state/VertexFetch.frag";
976
977         addChild(new InstanceFactory<DepthBiasParamTestInstance>(m_testCtx, "depth_bias", "Test depth bias functionality", shaderPaths));
978         addChild(new InstanceFactory<DepthBiasClampParamTestInstance, FunctionSupport0>(m_testCtx, "depth_bias_clamp", "Test depth bias clamp functionality", shaderPaths, checkDepthBiasClampSupport));
979         addChild(new InstanceFactory<LineWidthParamTestInstance, FunctionSupport0>(m_testCtx, "line_width", "Draw a line with width set to max defined by physical device", shaderPaths, checkWideLinesSupport));
980
981         {
982                 const DepthBiasNonZeroParams params =
983                 {
984                         16384.0f,       //      float                                                   depthBiasConstant;
985                         0.0f,           //      float                                                   depthBiasClamp;
986                         {                       //      DepthBiasNonZeroPushConstants   pushConstants;
987                                 0.375f, //              float geometryDepth;
988                                 0.5f,   //              float minDepth;
989                                 1.0f,   //              float maxDepth;
990                         },
991                 };
992                 addChild(new DepthBiasNonZeroCase(m_testCtx, "nonzero_depth_bias_constant", "", params));
993         }
994         {
995                 const DepthBiasNonZeroParams params =
996                 {
997                         16384.0f,               //      float                                                   depthBiasConstant;
998                         0.125f,                 //      float                                                   depthBiasClamp;
999                         {                               //      DepthBiasNonZeroPushConstants   pushConstants;
1000                                 0.375f,         //              float geometryDepth;
1001                                 0.46875f,       //              float minDepth;
1002                                 0.53125f,       //              float maxDepth;
1003                         },
1004                 };
1005                 addChild(new DepthBiasNonZeroCase(m_testCtx, "nonzero_depth_bias_clamp", "", params));
1006         }
1007 }
1008
1009 } // DynamicState
1010 } // vkt