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:
DepthBiasBaseCase(Context & context,const char * vertexShaderName,const char * fragmentShaderName)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
initialize(void)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
iterate(void)269 virtual tcu::TestStatus iterate (void)
270 {
271 DE_ASSERT(false);
272 return tcu::TestStatus::fail("Should reimplement iterate() method");
273 }
274
beginRenderPass(void)275 void beginRenderPass (void)
276 {
277 const vk::VkClearColorValue clearColor = { { 0.0f, 0.0f, 0.0f, 1.0f } };
278 beginRenderPassWithClearColor(clearColor);
279 }
280
beginRenderPassWithClearColor(const vk::VkClearColorValue & clearColor)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
setDynamicViewportState(const deUint32 width,const deUint32 height)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
setDynamicViewportState(const deUint32 viewportCount,const vk::VkViewport * pViewports,const vk::VkRect2D * pScissors)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
setDynamicRasterizationState(const float lineWidth=1.0f,const float depthBiasConstantFactor=0.0f,const float depthBiasClamp=0.0f,const float depthBiasSlopeFactor=0.0f)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
setDynamicBlendState(const float const1=0.0f,const float const2=0.0f,const float const3=0.0f,const float const4=0.0f)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
setDynamicDepthStencilState(const float minDepthBounds=-1.0f,const float maxDepthBounds=1.0f,const deUint32 stencilFrontCompareMask=0xffffffffu,const deUint32 stencilFrontWriteMask=0xffffffffu,const deUint32 stencilFrontReference=0,const deUint32 stencilBackCompareMask=0xffffffffu,const deUint32 stencilBackWriteMask=0xffffffffu,const deUint32 stencilBackReference=0)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:
DepthBiasParamTestInstance(Context & context,ShaderMap shaders)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
iterate(void)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:
DepthBiasClampParamTestInstance(Context & context,ShaderMap shaders)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
iterate(void)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:
LineWidthParamTestInstance(Context & context,ShaderMap shaders)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
iterate(void)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
checkDepthBiasClampSupport(Context & context)649 void checkDepthBiasClampSupport (Context& context)
650 {
651 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_DEPTH_BIAS_CLAMP);
652 }
653
checkWideLinesSupport(Context & context)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);
~DepthBiasNonZeroCase(void)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
getExpectedColor()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);
~DepthBiasNonZeroInstance(void)697 virtual ~DepthBiasNonZeroInstance (void) {}
698
699 tcu::TestStatus iterate (void) override;
700 };
701
DepthBiasNonZeroCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const DepthBiasNonZeroParams & params)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
createInstance(Context & context) const707 TestInstance* DepthBiasNonZeroCase::createInstance (Context& context) const
708 {
709 return new DepthBiasNonZeroInstance(context, m_params);
710 }
711
DepthBiasNonZeroInstance(Context & context,const DepthBiasNonZeroParams & params)712 DepthBiasNonZeroInstance::DepthBiasNonZeroInstance (Context& context, const DepthBiasNonZeroParams& params)
713 : vkt::TestInstance (context)
714 , m_params (params)
715 {}
716
checkSupport(Context & context) const717 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
initPrograms(vk::SourceCollections & programCollection) const724 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
iterate(void)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
DynamicStateRSTests(tcu::TestContext & testCtx)961 DynamicStateRSTests::DynamicStateRSTests (tcu::TestContext& testCtx)
962 : TestCaseGroup (testCtx, "rs_state", "Tests for rasterizer state")
963 {
964 /* Left blank on purpose */
965 }
966
~DynamicStateRSTests()967 DynamicStateRSTests::~DynamicStateRSTests ()
968 {
969 }
970
init(void)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
1011