• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 The Khronos Group Inc.
6  * Copyright (c) 2015 Intel Corporation
7  * Copyright (c) 2023 LunarG, Inc.
8  * Copyright (c) 2023 Nintendo
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  *      http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  *//*!
23  * \file
24  * \brief Dynamic Raster State Tests
25  *//*--------------------------------------------------------------------*/
26 
27 #include "vktDynamicStateRSTests.hpp"
28 
29 #include "vktDynamicStateBaseClass.hpp"
30 #include "vktDynamicStateTestCaseUtil.hpp"
31 
32 #include "vkImageUtil.hpp"
33 #include "vkTypeUtil.hpp"
34 #include "vkCmdUtil.hpp"
35 #include "vkObjUtil.hpp"
36 #include "vkBuilderUtil.hpp"
37 
38 #include "tcuTextureUtil.hpp"
39 #include "tcuImageCompare.hpp"
40 #include "tcuRGBA.hpp"
41 
42 #include "deMath.h"
43 
44 #include <vector>
45 #include <string>
46 #include <sstream>
47 #include <iomanip>
48 
49 namespace vkt
50 {
51 namespace DynamicState
52 {
53 
54 using namespace Draw;
55 
56 namespace
57 {
58 
59 class DepthBiasBaseCase : public TestInstance
60 {
61 public:
DepthBiasBaseCase(Context & context,vk::PipelineConstructionType pipelineConstructionType,const char * vertexShaderName,const char * fragmentShaderName,const char * meshShaderName)62 	DepthBiasBaseCase (Context& context, vk::PipelineConstructionType pipelineConstructionType, const char* vertexShaderName, const char* fragmentShaderName, const char* meshShaderName)
63 		: TestInstance						(context)
64 		, m_pipelineConstructionType		(pipelineConstructionType)
65 		, m_colorAttachmentFormat			(vk::VK_FORMAT_R8G8B8A8_UNORM)
66 		, m_depthStencilAttachmentFormat	(vk::VK_FORMAT_UNDEFINED)
67 		, m_topology						(vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
68 		, m_vk								(context.getDeviceInterface())
69 		, m_pipeline						(context.getInstanceInterface(), m_vk, context.getPhysicalDevice(), context.getDevice(), context.getDeviceExtensions(), pipelineConstructionType)
70 		, m_vertexShaderName				(vertexShaderName ? vertexShaderName : "")
71 		, m_fragmentShaderName				(fragmentShaderName)
72 		, m_meshShaderName					(meshShaderName ? meshShaderName : "")
73 		, m_isMesh							(meshShaderName != nullptr)
74 	{
75 		// Either mesh or vertex shader, but not both or none.
76 		DE_ASSERT((vertexShaderName != nullptr) != (meshShaderName != nullptr));
77 	}
78 
79 protected:
80 
81 	enum
82 	{
83 		WIDTH	= 128,
84 		HEIGHT	= 128
85 	};
86 
87 	vk::PipelineConstructionType					m_pipelineConstructionType;
88 	vk::VkFormat									m_colorAttachmentFormat;
89 	vk::VkFormat									m_depthStencilAttachmentFormat;
90 
91 	vk::VkPrimitiveTopology							m_topology;
92 
93 	const vk::DeviceInterface&						m_vk;
94 
95 	vk::Move<vk::VkDescriptorPool>					m_descriptorPool;
96 	vk::Move<vk::VkDescriptorSetLayout>				m_setLayout;
97 	vk::PipelineLayoutWrapper						m_pipelineLayout;
98 	vk::Move<vk::VkDescriptorSet>					m_descriptorSet;
99 	vk::GraphicsPipelineWrapper						m_pipeline;
100 
101 	de::SharedPtr<Image>							m_colorTargetImage;
102 	vk::Move<vk::VkImageView>						m_colorTargetView;
103 
104 	de::SharedPtr<Image>							m_depthStencilImage;
105 	vk::Move<vk::VkImageView>						m_attachmentView;
106 
107 	PipelineCreateInfo::VertexInputState			m_vertexInputState;
108 	de::SharedPtr<Buffer>							m_vertexBuffer;
109 
110 	vk::Move<vk::VkCommandPool>						m_cmdPool;
111 	vk::Move<vk::VkCommandBuffer>					m_cmdBuffer;
112 
113 	vk::RenderPassWrapper							m_renderPass;
114 
115 	std::string										m_vertexShaderName;
116 	std::string										m_fragmentShaderName;
117 	std::string										m_meshShaderName;
118 
119 	std::vector<PositionColorVertex>				m_data;
120 
121 	PipelineCreateInfo::DepthStencilState			m_depthStencilState;
122 
123 	const bool										m_isMesh;
124 
initialize(void)125 	void initialize (void)
126 	{
127 		const vk::VkDevice						device				= m_context.getDevice();
128 		const auto								vertDescType		= (m_isMesh ? vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER : vk::VK_DESCRIPTOR_TYPE_MAX_ENUM);
129 		std::vector<vk::VkPushConstantRange>	pcRanges;
130 
131 		vk::VkFormatProperties formatProperties;
132 		// check for VK_FORMAT_D24_UNORM_S8_UINT support
133 		m_context.getInstanceInterface().getPhysicalDeviceFormatProperties(m_context.getPhysicalDevice(), vk::VK_FORMAT_D24_UNORM_S8_UINT, &formatProperties);
134 		if (formatProperties.optimalTilingFeatures & vk::VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
135 		{
136 			m_depthStencilAttachmentFormat = vk::VK_FORMAT_D24_UNORM_S8_UINT;
137 		}
138 		else
139 		{
140 			// check for VK_FORMAT_D32_SFLOAT_S8_UINT support
141 			m_context.getInstanceInterface().getPhysicalDeviceFormatProperties(m_context.getPhysicalDevice(), vk::VK_FORMAT_D32_SFLOAT_S8_UINT, &formatProperties);
142 			if (formatProperties.optimalTilingFeatures & vk::VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
143 			{
144 				m_depthStencilAttachmentFormat = vk::VK_FORMAT_D32_SFLOAT_S8_UINT;
145 			}
146 			else
147 				throw tcu::NotSupportedError("No valid depth stencil attachment available");
148 		}
149 
150 		// The mesh shading pipeline will contain a set with vertex data.
151 #ifndef CTS_USES_VULKANSC
152 		if (m_isMesh)
153 		{
154 			vk::DescriptorSetLayoutBuilder	setLayoutBuilder;
155 			vk::DescriptorPoolBuilder		poolBuilder;
156 
157 			setLayoutBuilder.addSingleBinding(vertDescType, vk::VK_SHADER_STAGE_MESH_BIT_EXT);
158 			m_setLayout = setLayoutBuilder.build(m_vk, device);
159 
160 			poolBuilder.addType(vertDescType);
161 			m_descriptorPool = poolBuilder.build(m_vk, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
162 
163 			m_descriptorSet = vk::makeDescriptorSet(m_vk, device, m_descriptorPool.get(), m_setLayout.get());
164 			pcRanges.push_back(vk::makePushConstantRange(vk::VK_SHADER_STAGE_MESH_BIT_EXT, 0u, static_cast<uint32_t>(sizeof(uint32_t))));
165 		}
166 #endif // CTS_USES_VULKANSC
167 
168 		m_pipelineLayout = vk::PipelineLayoutWrapper(m_pipelineConstructionType, m_vk, device, m_setLayout.get(), de::dataOrNull(pcRanges));
169 
170 		const vk::VkExtent3D imageExtent = { WIDTH, HEIGHT, 1 };
171 		ImageCreateInfo targetImageCreateInfo(vk::VK_IMAGE_TYPE_2D, m_colorAttachmentFormat, imageExtent, 1, 1, vk::VK_SAMPLE_COUNT_1_BIT, vk::VK_IMAGE_TILING_OPTIMAL,
172 											  vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
173 
174 		m_colorTargetImage = Image::createAndAlloc(m_vk, device, targetImageCreateInfo, m_context.getDefaultAllocator(), m_context.getUniversalQueueFamilyIndex());
175 
176 		const ImageCreateInfo depthStencilImageCreateInfo(vk::VK_IMAGE_TYPE_2D, m_depthStencilAttachmentFormat, imageExtent,
177 														  1, 1, vk::VK_SAMPLE_COUNT_1_BIT, vk::VK_IMAGE_TILING_OPTIMAL,
178 														  vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
179 
180 		m_depthStencilImage = Image::createAndAlloc(m_vk, device, depthStencilImageCreateInfo, m_context.getDefaultAllocator(), m_context.getUniversalQueueFamilyIndex());
181 
182 		const ImageViewCreateInfo colorTargetViewInfo(m_colorTargetImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, m_colorAttachmentFormat);
183 		m_colorTargetView = vk::createImageView(m_vk, device, &colorTargetViewInfo);
184 
185 		const ImageViewCreateInfo attachmentViewInfo(m_depthStencilImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, m_depthStencilAttachmentFormat);
186 		m_attachmentView = vk::createImageView(m_vk, device, &attachmentViewInfo);
187 
188 		RenderPassCreateInfo renderPassCreateInfo;
189 		renderPassCreateInfo.addAttachment(AttachmentDescription(m_colorAttachmentFormat,
190 																 vk::VK_SAMPLE_COUNT_1_BIT,
191 																 vk::VK_ATTACHMENT_LOAD_OP_LOAD,
192 																 vk::VK_ATTACHMENT_STORE_OP_STORE,
193 																 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
194 																 vk::VK_ATTACHMENT_STORE_OP_STORE,
195 																 vk::VK_IMAGE_LAYOUT_GENERAL,
196 																 vk::VK_IMAGE_LAYOUT_GENERAL));
197 
198 		renderPassCreateInfo.addAttachment(AttachmentDescription(m_depthStencilAttachmentFormat,
199 																 vk::VK_SAMPLE_COUNT_1_BIT,
200 																 vk::VK_ATTACHMENT_LOAD_OP_LOAD,
201 																 vk::VK_ATTACHMENT_STORE_OP_STORE,
202 																 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
203 																 vk::VK_ATTACHMENT_STORE_OP_STORE,
204 																 vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
205 																 vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
206 
207 		const vk::VkAttachmentReference colorAttachmentReference =
208 		{
209 			0,
210 			vk::VK_IMAGE_LAYOUT_GENERAL
211 		};
212 
213 		const vk::VkAttachmentReference depthAttachmentReference =
214 		{
215 			1,
216 			vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
217 		};
218 
219 		renderPassCreateInfo.addSubpass(SubpassDescription(vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
220 														   0,
221 														   0,
222 														   DE_NULL,
223 														   1,
224 														   &colorAttachmentReference,
225 														   DE_NULL,
226 														   depthAttachmentReference,
227 														   0,
228 														   DE_NULL));
229 
230 		m_renderPass = vk::RenderPassWrapper(m_pipelineConstructionType, m_vk, device, &renderPassCreateInfo);
231 
232 		const vk::VkVertexInputBindingDescription vertexInputBindingDescription =
233 		{
234 			0,
235 			(deUint32)sizeof(tcu::Vec4) * 2,
236 			vk::VK_VERTEX_INPUT_RATE_VERTEX,
237 		};
238 
239 		const vk::VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
240 		{
241 			{
242 				0u,
243 				0u,
244 				vk::VK_FORMAT_R32G32B32A32_SFLOAT,
245 				0u
246 			},
247 			{
248 				1u,
249 				0u,
250 				vk::VK_FORMAT_R32G32B32A32_SFLOAT,
251 				(deUint32)(sizeof(float)* 4),
252 			}
253 		};
254 
255 		m_vertexInputState = PipelineCreateInfo::VertexInputState(1,
256 																  &vertexInputBindingDescription,
257 																  2,
258 																  vertexInputAttributeDescriptions);
259 
260 		std::vector<vk::VkViewport>		viewports	{ { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } };
261 		std::vector<vk::VkRect2D>		scissors	{ { { 0u, 0u }, { 0u, 0u } } };
262 
263 		// Shader modules.
264 		const auto&							binaries	= m_context.getBinaryCollection();
265 		const vk::ShaderWrapper				vs			= (m_isMesh ? vk::ShaderWrapper() : vk::ShaderWrapper(m_vk, device, binaries.get(m_vertexShaderName)));
266 		const vk::ShaderWrapper				ms			= (m_isMesh ? vk::ShaderWrapper(m_vk, device, binaries.get(m_meshShaderName)) : vk::ShaderWrapper());
267 		const vk::ShaderWrapper				fs			= vk::ShaderWrapper(m_vk, device, binaries.get(m_fragmentShaderName));
268 
269 		const PipelineCreateInfo::ColorBlendState::Attachment	attachmentState;
270 		const PipelineCreateInfo::ColorBlendState				colorBlendState(1u, static_cast<const vk::VkPipelineColorBlendAttachmentState*>(&attachmentState));
271 		const PipelineCreateInfo::RasterizerState				rasterizerState;
272 		PipelineCreateInfo::DynamicState						dynamicState;
273 
274 		m_pipeline.setDefaultTopology(m_topology)
275 				  .setDynamicState(static_cast<const vk::VkPipelineDynamicStateCreateInfo*>(&dynamicState))
276 				  .setDefaultMultisampleState();
277 
278 #ifndef CTS_USES_VULKANSC
279 		if (m_isMesh)
280 		{
281 			m_pipeline
282 				  .setupPreRasterizationMeshShaderState(viewports,
283 														scissors,
284 														m_pipelineLayout,
285 														*m_renderPass,
286 														0u,
287 														vk::ShaderWrapper(),
288 														ms,
289 														static_cast<const vk::VkPipelineRasterizationStateCreateInfo*>(&rasterizerState));
290 		}
291 		else
292 #endif // CTS_USES_VULKANSC
293 		{
294 			m_pipeline
295 				  .setupVertexInputState(&m_vertexInputState)
296 				  .setupPreRasterizationShaderState(viewports,
297 													scissors,
298 													m_pipelineLayout,
299 													*m_renderPass,
300 													0u,
301 													vs,
302 													static_cast<const vk::VkPipelineRasterizationStateCreateInfo*>(&rasterizerState));
303 		}
304 
305 		m_pipeline.setupFragmentShaderState(m_pipelineLayout, *m_renderPass, 0u, fs, static_cast<const vk::VkPipelineDepthStencilStateCreateInfo*>(&m_depthStencilState))
306 				  .setupFragmentOutputState(*m_renderPass, 0u, static_cast<const vk::VkPipelineColorBlendStateCreateInfo*>(&colorBlendState))
307 				  .setMonolithicPipelineLayout(m_pipelineLayout)
308 				  .buildPipeline();
309 
310 
311 		std::vector<vk::VkImageView> attachments(2);
312 		attachments[0] = *m_colorTargetView;
313 		attachments[1] = *m_attachmentView;
314 
315 		const FramebufferCreateInfo framebufferCreateInfo(*m_renderPass, attachments, WIDTH, HEIGHT, 1);
316 
317 		m_renderPass.createFramebuffer(m_vk, device, &framebufferCreateInfo, {m_colorTargetImage->object(), m_depthStencilImage->object()});
318 
319 		const vk::VkDeviceSize			dataSize	= m_data.size() * sizeof(PositionColorVertex);
320 		const vk::VkBufferUsageFlags	bufferUsage	= (m_isMesh ? vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT : vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
321 		m_vertexBuffer = Buffer::createAndAlloc(m_vk, device, BufferCreateInfo(dataSize, bufferUsage),
322 			m_context.getDefaultAllocator(), vk::MemoryRequirement::HostVisible);
323 
324 		deUint8* ptr = reinterpret_cast<unsigned char *>(m_vertexBuffer->getBoundMemory().getHostPtr());
325 		deMemcpy(ptr, &m_data[0], static_cast<size_t>(dataSize));
326 
327 		vk::flushAlloc(m_vk, device, m_vertexBuffer->getBoundMemory());
328 
329 		// Update descriptor set for mesh shaders.
330 		if (m_isMesh)
331 		{
332 			vk::DescriptorSetUpdateBuilder	updateBuilder;
333 			const auto						location		= vk::DescriptorSetUpdateBuilder::Location::binding(0u);
334 			const auto						bufferInfo		= vk::makeDescriptorBufferInfo(m_vertexBuffer->object(), 0ull, dataSize);
335 
336 			updateBuilder.writeSingle(m_descriptorSet.get(), location, vertDescType, &bufferInfo);
337 			updateBuilder.update(m_vk, device);
338 		}
339 
340 		const CmdPoolCreateInfo cmdPoolCreateInfo(m_context.getUniversalQueueFamilyIndex());
341 		m_cmdPool = vk::createCommandPool(m_vk, device, &cmdPoolCreateInfo);
342 		m_cmdBuffer = vk::allocateCommandBuffer(m_vk, device, *m_cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
343 	}
344 
iterate(void)345 	virtual tcu::TestStatus iterate (void)
346 	{
347 		DE_ASSERT(false);
348 		return tcu::TestStatus::fail("Should reimplement iterate() method");
349 	}
350 
beginRenderPass(void)351 	void beginRenderPass (void)
352 	{
353 		const vk::VkClearColorValue clearColor = { { 0.0f, 0.0f, 0.0f, 1.0f } };
354 		beginRenderPassWithClearColor(clearColor);
355 	}
356 
beginRenderPassWithClearColor(const vk::VkClearColorValue & clearColor)357 	void beginRenderPassWithClearColor (const vk::VkClearColorValue &clearColor)
358 	{
359 		beginCommandBuffer(m_vk, *m_cmdBuffer, 0u);
360 
361 		initialTransitionColor2DImage(m_vk, *m_cmdBuffer, m_colorTargetImage->object(), vk::VK_IMAGE_LAYOUT_GENERAL,
362 									  vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT);
363 		initialTransitionDepthStencil2DImage(m_vk, *m_cmdBuffer, m_depthStencilImage->object(), vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
364 											 vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT);
365 
366 		const ImageSubresourceRange subresourceRangeImage(vk::VK_IMAGE_ASPECT_COLOR_BIT);
367 		m_vk.cmdClearColorImage(*m_cmdBuffer, m_colorTargetImage->object(),
368 								vk::VK_IMAGE_LAYOUT_GENERAL, &clearColor, 1, &subresourceRangeImage);
369 
370 		const vk::VkClearDepthStencilValue depthStencilClearValue = { 0.0f, 0 };
371 
372 		const ImageSubresourceRange subresourceRangeDepthStencil[2] = { vk::VK_IMAGE_ASPECT_DEPTH_BIT, vk::VK_IMAGE_ASPECT_STENCIL_BIT };
373 
374 		m_vk.cmdClearDepthStencilImage(*m_cmdBuffer, m_depthStencilImage->object(),
375 									   vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &depthStencilClearValue, 2, subresourceRangeDepthStencil);
376 
377 		const vk::VkMemoryBarrier memBarrier =
378 		{
379 			vk::VK_STRUCTURE_TYPE_MEMORY_BARRIER,
380 			DE_NULL,
381 			vk::VK_ACCESS_TRANSFER_WRITE_BIT,
382 			vk::VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
383 				vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
384 		};
385 
386 		m_vk.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
387 			vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
388 			vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
389 			0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
390 
391 		transition2DImage(m_vk, *m_cmdBuffer, m_depthStencilImage->object(), vk::VK_IMAGE_ASPECT_DEPTH_BIT | vk::VK_IMAGE_ASPECT_STENCIL_BIT,
392 						  vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
393 						  vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
394 						  vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
395 
396 		m_renderPass.begin(m_vk, *m_cmdBuffer, vk::makeRect2D(0, 0, WIDTH, HEIGHT));
397 	}
398 
setDynamicViewportState(const deUint32 width,const deUint32 height)399 	void setDynamicViewportState (const deUint32 width, const deUint32 height)
400 	{
401 		vk::VkViewport viewport = vk::makeViewport(tcu::UVec2(width, height));
402 		vk::VkRect2D scissor = vk::makeRect2D(tcu::UVec2(width, height));
403 		if (vk::isConstructionTypeShaderObject(m_pipelineConstructionType))
404 		{
405 #ifndef CTS_USES_VULKANSC
406 			m_vk.cmdSetViewportWithCount(*m_cmdBuffer, 1, &viewport);
407 			m_vk.cmdSetScissorWithCount(*m_cmdBuffer, 1, &scissor);
408 #else
409 			m_vk.cmdSetViewportWithCountEXT(*m_cmdBuffer, 1, &viewport);
410 			m_vk.cmdSetScissorWithCountEXT(*m_cmdBuffer, 1, &scissor);
411 #endif
412 		}
413 		else
414 		{
415 			m_vk.cmdSetViewport(*m_cmdBuffer, 0, 1, &viewport);
416 			m_vk.cmdSetScissor(*m_cmdBuffer, 0, 1, &scissor);
417 		}
418 
419 	}
420 
setDynamicViewportState(const deUint32 viewportCount,const vk::VkViewport * pViewports,const vk::VkRect2D * pScissors)421 	void setDynamicViewportState (const deUint32 viewportCount, const vk::VkViewport* pViewports, const vk::VkRect2D* pScissors)
422 	{
423 		if (vk::isConstructionTypeShaderObject(m_pipelineConstructionType))
424 		{
425 #ifndef CTS_USES_VULKANSC
426 			m_vk.cmdSetViewportWithCount(*m_cmdBuffer, viewportCount, pViewports);
427 			m_vk.cmdSetScissorWithCount(*m_cmdBuffer, viewportCount, pScissors);
428 #else
429 			m_vk.cmdSetViewportWithCountEXT(*m_cmdBuffer, viewportCount, pViewports);
430 			m_vk.cmdSetScissorWithCountEXT(*m_cmdBuffer, viewportCount, pScissors);
431 #endif
432 		}
433 		else
434 		{
435 			m_vk.cmdSetViewport(*m_cmdBuffer, 0, viewportCount, pViewports);
436 			m_vk.cmdSetScissor(*m_cmdBuffer, 0, viewportCount, pScissors);
437 		}
438 	}
439 
setDynamicRasterizationState(const float lineWidth=1.0f,const float depthBiasConstantFactor=0.0f,const float depthBiasClamp=0.0f,const float depthBiasSlopeFactor=0.0f)440 	void setDynamicRasterizationState (const float lineWidth = 1.0f,
441 		const float depthBiasConstantFactor = 0.0f,
442 		const float depthBiasClamp = 0.0f,
443 		const float depthBiasSlopeFactor = 0.0f)
444 	{
445 		m_vk.cmdSetLineWidth(*m_cmdBuffer, lineWidth);
446 		m_vk.cmdSetDepthBias(*m_cmdBuffer, depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor);
447 	}
448 
setDynamicBlendState(const float const1=0.0f,const float const2=0.0f,const float const3=0.0f,const float const4=0.0f)449 	void setDynamicBlendState (const float const1 = 0.0f, const float const2 = 0.0f,
450 		const float const3 = 0.0f, const float const4 = 0.0f)
451 	{
452 		float blendConstantsants[4] = { const1, const2, const3, const4 };
453 		m_vk.cmdSetBlendConstants(*m_cmdBuffer, blendConstantsants);
454 	}
455 
setDynamicDepthStencilState(const float minDepthBounds=0.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)456 	void setDynamicDepthStencilState (const float minDepthBounds = 0.0f, const float maxDepthBounds = 1.0f,
457 		const deUint32 stencilFrontCompareMask = 0xffffffffu, const deUint32 stencilFrontWriteMask = 0xffffffffu,
458 		const deUint32 stencilFrontReference = 0, const deUint32 stencilBackCompareMask = 0xffffffffu,
459 		const deUint32 stencilBackWriteMask = 0xffffffffu, const deUint32 stencilBackReference = 0)
460 	{
461 		m_vk.cmdSetDepthBounds(*m_cmdBuffer, minDepthBounds, maxDepthBounds);
462 		m_vk.cmdSetStencilCompareMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontCompareMask);
463 		m_vk.cmdSetStencilWriteMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontWriteMask);
464 		m_vk.cmdSetStencilReference(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontReference);
465 		m_vk.cmdSetStencilCompareMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackCompareMask);
466 		m_vk.cmdSetStencilWriteMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackWriteMask);
467 		m_vk.cmdSetStencilReference(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackReference);
468 	}
469 
470 #ifndef CTS_USES_VULKANSC
pushVertexOffset(const uint32_t vertexOffset,const vk::VkShaderStageFlags stageFlags=vk::VK_SHADER_STAGE_MESH_BIT_EXT)471 	void pushVertexOffset (const uint32_t				vertexOffset,
472 						   const vk::VkShaderStageFlags	stageFlags = vk::VK_SHADER_STAGE_MESH_BIT_EXT)
473 	{
474 		m_vk.cmdPushConstants(*m_cmdBuffer, *m_pipelineLayout, stageFlags, 0u, static_cast<uint32_t>(sizeof(uint32_t)), &vertexOffset);
475 	}
476 #endif // CTS_USES_VULKANSC
477 };
478 
479 class DepthBiasParamTestInstance : public DepthBiasBaseCase
480 {
481 public:
DepthBiasParamTestInstance(Context & context,vk::PipelineConstructionType pipelineConstructionType,const ShaderMap & shaders)482 	DepthBiasParamTestInstance (Context& context, vk::PipelineConstructionType pipelineConstructionType, const ShaderMap& shaders)
483 		: DepthBiasBaseCase (context, pipelineConstructionType, shaders.at(glu::SHADERTYPE_VERTEX), shaders.at(glu::SHADERTYPE_FRAGMENT), shaders.at(glu::SHADERTYPE_MESH))
484 	{
485 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 0.5f, 1.0f), tcu::RGBA::blue().toVec()));
486 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 0.5f, 1.0f), tcu::RGBA::blue().toVec()));
487 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 0.5f, 1.0f), tcu::RGBA::blue().toVec()));
488 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 0.5f, 1.0f), tcu::RGBA::blue().toVec()));
489 
490 		m_data.push_back(PositionColorVertex(tcu::Vec4(-0.5f, 0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
491 		m_data.push_back(PositionColorVertex(tcu::Vec4(0.5f, 0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
492 		m_data.push_back(PositionColorVertex(tcu::Vec4(-0.5f, -0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
493 		m_data.push_back(PositionColorVertex(tcu::Vec4(0.5f, -0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
494 
495 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 0.5f, 1.0f), tcu::RGBA::red().toVec()));
496 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 0.5f, 1.0f), tcu::RGBA::red().toVec()));
497 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 0.5f, 1.0f), tcu::RGBA::red().toVec()));
498 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 0.5f, 1.0f), tcu::RGBA::red().toVec()));
499 
500 		// enable depth test
501 		m_depthStencilState = PipelineCreateInfo::DepthStencilState(
502 			VK_TRUE, VK_TRUE, vk::VK_COMPARE_OP_GREATER_OR_EQUAL);
503 
504 		DepthBiasBaseCase::initialize();
505 	}
506 
iterate(void)507 	virtual tcu::TestStatus iterate (void)
508 	{
509 		tcu::TestLog&		log		= m_context.getTestContext().getLog();
510 		const vk::VkQueue	queue	= m_context.getUniversalQueue();
511 		const vk::VkDevice	device	= m_context.getDevice();
512 
513 		beginRenderPass();
514 
515 		// set states here
516 		setDynamicViewportState(WIDTH, HEIGHT);
517 		setDynamicBlendState();
518 		setDynamicDepthStencilState();
519 
520 		m_pipeline.bind(*m_cmdBuffer);
521 
522 #ifndef CTS_USES_VULKANSC
523 		if (m_isMesh)
524 		{
525 			m_vk.cmdBindDescriptorSets(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout.get(), 0u, 1u, &m_descriptorSet.get(), 0u, nullptr);
526 
527 			setDynamicRasterizationState(1.0f, 0.0f);
528 			pushVertexOffset(0u); m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, 2u, 1u, 1u);
529 			pushVertexOffset(4u); m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, 2u, 1u, 1u);
530 
531 			setDynamicRasterizationState(1.0f, -1.0f);
532 			pushVertexOffset(8u); m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, 2u, 1u, 1u);
533 		}
534 		else
535 #endif // CTS_USES_VULKANSC
536 		{
537 			const vk::VkDeviceSize vertexBufferOffset	= 0;
538 			const vk::VkBuffer vertexBuffer				= m_vertexBuffer->object();
539 			m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
540 
541 			setDynamicRasterizationState(1.0f, 0.0f);
542 			m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
543 			m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 4, 0);
544 
545 			setDynamicRasterizationState(1.0f, -1.0f);
546 			m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 8, 0);
547 		}
548 
549 		m_renderPass.end(m_vk, *m_cmdBuffer);
550 		endCommandBuffer(m_vk, *m_cmdBuffer);
551 
552 		submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
553 
554 		// validation
555 		{
556 			VK_CHECK(m_vk.queueWaitIdle(queue));
557 
558 			tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5f + static_cast<float>(WIDTH)), (int)(0.5f + static_cast<float>(HEIGHT)));
559 			referenceFrame.allocLevel(0);
560 
561 			const deInt32 frameWidth = referenceFrame.getWidth();
562 			const deInt32 frameHeight = referenceFrame.getHeight();
563 
564 			tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
565 
566 			for (int y = 0; y < frameHeight; y++)
567 			{
568 				const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
569 
570 				for (int x = 0; x < frameWidth; x++)
571 				{
572 					const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
573 
574 					if (xCoord >= -0.5f && xCoord <= 0.5f && yCoord >= -0.5f && yCoord <= 0.5f)
575 						referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
576 					else
577 						referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
578 				}
579 			}
580 
581 			const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
582 			const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
583 				vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
584 
585 			if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
586 				referenceFrame.getLevel(0), renderedFrame, 0.05f,
587 				tcu::COMPARE_LOG_RESULT))
588 			{
589 				return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
590 			}
591 
592 			return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
593 		}
594 	}
595 };
596 
597 class DepthBiasClampParamTestInstance : public DepthBiasBaseCase
598 {
599 public:
DepthBiasClampParamTestInstance(Context & context,vk::PipelineConstructionType pipelineConstructionType,const ShaderMap & shaders)600 	DepthBiasClampParamTestInstance (Context& context, vk::PipelineConstructionType pipelineConstructionType, const ShaderMap& shaders)
601 		: DepthBiasBaseCase (context, pipelineConstructionType, shaders.at(glu::SHADERTYPE_VERTEX), shaders.at(glu::SHADERTYPE_FRAGMENT), shaders.at(glu::SHADERTYPE_MESH))
602 	{
603 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f), tcu::RGBA::blue().toVec()));
604 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f), tcu::RGBA::blue().toVec()));
605 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f), tcu::RGBA::blue().toVec()));
606 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 0.0f, 1.0f), tcu::RGBA::blue().toVec()));
607 
608 		m_data.push_back(PositionColorVertex(tcu::Vec4(-0.5f, 0.5f, 0.01f, 1.0f), tcu::RGBA::green().toVec()));
609 		m_data.push_back(PositionColorVertex(tcu::Vec4(0.5f, 0.5f, 0.01f, 1.0f), tcu::RGBA::green().toVec()));
610 		m_data.push_back(PositionColorVertex(tcu::Vec4(-0.5f, -0.5f, 0.01f, 1.0f), tcu::RGBA::green().toVec()));
611 		m_data.push_back(PositionColorVertex(tcu::Vec4(0.5f, -0.5f, 0.01f, 1.0f), tcu::RGBA::green().toVec()));
612 
613 		// enable depth test
614 		m_depthStencilState = PipelineCreateInfo::DepthStencilState(VK_TRUE, VK_TRUE, vk::VK_COMPARE_OP_GREATER_OR_EQUAL);
615 
616 		DepthBiasBaseCase::initialize();
617 	}
618 
iterate(void)619 	virtual tcu::TestStatus iterate (void)
620 	{
621 		tcu::TestLog&		log		= m_context.getTestContext().getLog();
622 		const vk::VkQueue	queue	= m_context.getUniversalQueue();
623 		const vk::VkDevice	device	= m_context.getDevice();
624 
625 		beginRenderPass();
626 
627 		// set states here
628 		setDynamicViewportState(WIDTH, HEIGHT);
629 		setDynamicBlendState();
630 		setDynamicDepthStencilState();
631 
632 		m_pipeline.bind(*m_cmdBuffer);
633 
634 #ifndef CTS_USES_VULKANSC
635 		if (m_isMesh)
636 		{
637 			m_vk.cmdBindDescriptorSets(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout.get(), 0u, 1u, &m_descriptorSet.get(), 0u, nullptr);
638 
639 			setDynamicRasterizationState(1.0f, 1000.0f, 0.005f);
640 			pushVertexOffset(0u); m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, 2u, 1u, 1u);
641 
642 			setDynamicRasterizationState(1.0f, 0.0f);
643 			pushVertexOffset(4u); m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, 2u, 1u, 1u);
644 		}
645 		else
646 #endif // CTS_USES_VULKANSC
647 		{
648 			const vk::VkDeviceSize vertexBufferOffset = 0;
649 			const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
650 			m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
651 
652 			setDynamicRasterizationState(1.0f, 1000.0f, 0.005f);
653 			m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
654 
655 			setDynamicRasterizationState(1.0f, 0.0f);
656 			m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 4, 0);
657 		}
658 
659 		m_renderPass.end(m_vk, *m_cmdBuffer);
660 		endCommandBuffer(m_vk, *m_cmdBuffer);
661 
662 		submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
663 
664 		// validation
665 		{
666 			tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5f + static_cast<float>(WIDTH)), (int)(0.5f + static_cast<float>(HEIGHT)));
667 			referenceFrame.allocLevel(0);
668 
669 			const deInt32 frameWidth	= referenceFrame.getWidth();
670 			const deInt32 frameHeight	= referenceFrame.getHeight();
671 
672 			tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
673 
674 			for (int y = 0; y < frameHeight; y++)
675 			{
676 				float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
677 
678 				for (int x = 0; x < frameWidth; x++)
679 				{
680 					float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
681 
682 					if (xCoord >= -0.5f && xCoord <= 0.5f && yCoord >= -0.5f && yCoord <= 0.5f)
683 						referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
684 					else
685 						referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
686 				}
687 			}
688 
689 			const vk::VkOffset3D zeroOffset					= { 0, 0, 0 };
690 			const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
691 				vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
692 
693 			if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
694 				referenceFrame.getLevel(0), renderedFrame, 0.05f,
695 				tcu::COMPARE_LOG_RESULT))
696 			{
697 				return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
698 			}
699 
700 			return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
701 		}
702 	}
703 };
704 
705 class LineWidthParamTestInstance : public DynamicStateBaseClass
706 {
707 public:
LineWidthParamTestInstance(Context & context,vk::PipelineConstructionType pipelineConstructionType,const ShaderMap & shaders)708 	LineWidthParamTestInstance (Context& context, vk::PipelineConstructionType pipelineConstructionType, const ShaderMap& shaders)
709 		: DynamicStateBaseClass (context, pipelineConstructionType, shaders.at(glu::SHADERTYPE_VERTEX), shaders.at(glu::SHADERTYPE_FRAGMENT), shaders.at(glu::SHADERTYPE_MESH))
710 	{
711 		m_topology = vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
712 
713 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 0.0f, 0.0f, 1.0f), tcu::RGBA::green().toVec()));
714 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::RGBA::green().toVec()));
715 
716 		DynamicStateBaseClass::initialize();
717 	}
718 
iterate(void)719 	virtual tcu::TestStatus iterate (void)
720 	{
721 		tcu::TestLog&		log		= m_context.getTestContext().getLog();
722 		const vk::VkQueue	queue	= m_context.getUniversalQueue();
723 		const vk::VkDevice	device	= m_context.getDevice();
724 
725 		beginRenderPass();
726 
727 		// set states here
728 		vk::VkPhysicalDeviceProperties deviceProperties;
729 		m_context.getInstanceInterface().getPhysicalDeviceProperties(m_context.getPhysicalDevice(), &deviceProperties);
730 
731 		setDynamicViewportState(WIDTH, HEIGHT);
732 		setDynamicBlendState();
733 		setDynamicDepthStencilState();
734 		setDynamicRasterizationState(deFloatFloor(deviceProperties.limits.lineWidthRange[1]));
735 
736 		m_pipeline.bind(*m_cmdBuffer);
737 
738 #ifndef CTS_USES_VULKANSC
739 		if (m_isMesh)
740 		{
741 			const auto numVert = static_cast<uint32_t>(m_data.size());
742 			DE_ASSERT(numVert >= 1u);
743 
744 			m_vk.cmdBindDescriptorSets(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout.get(), 0u, 1u, &m_descriptorSet.get(), 0u, nullptr);
745 			pushVertexOffset(0u, *m_pipelineLayout);
746 			m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, numVert - 1u, 1u, 1u);
747 		}
748 		else
749 #endif // CTS_USES_VULKANSC
750 		{
751 			const vk::VkDeviceSize vertexBufferOffset	= 0;
752 			const vk::VkBuffer vertexBuffer				= m_vertexBuffer->object();
753 			m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
754 
755 			m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
756 		}
757 
758 		m_renderPass.end(m_vk, *m_cmdBuffer);
759 		endCommandBuffer(m_vk, *m_cmdBuffer);
760 
761 		submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
762 
763 		// validation
764 		{
765 			tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5f + static_cast<float>(WIDTH)), (int)(0.5f + static_cast<float>(HEIGHT)));
766 			referenceFrame.allocLevel(0);
767 
768 			const deInt32 frameWidth = referenceFrame.getWidth();
769 			const deInt32 frameHeight = referenceFrame.getHeight();
770 
771 			tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
772 
773 			for (int y = 0; y < frameHeight; y++)
774 			{
775 				float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
776 
777 				for (int x = 0; x < frameWidth; x++)
778 				{
779 					float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
780 					float lineHalfWidth = (float)(deFloor(deviceProperties.limits.lineWidthRange[1]) / frameHeight);
781 
782 					if (xCoord >= -1.0f && xCoord <= 1.0f && yCoord >= -lineHalfWidth && yCoord <= lineHalfWidth)
783 						referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
784 				}
785 			}
786 
787 			const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
788 			const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
789 																							  vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT,
790 																							  vk::VK_IMAGE_ASPECT_COLOR_BIT);
791 
792 			if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
793 				referenceFrame.getLevel(0), renderedFrame, 0.05f,
794 				tcu::COMPARE_LOG_RESULT))
795 			{
796 				return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
797 			}
798 
799 			return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
800 		}
801 	}
802 };
803 
804 // Tests that fail if both the depth bias clamp or depth constant factor stay at 0.0f instead of applying the real values.
805 struct DepthBiasNonZeroPushConstants
806 {
807 	float geometryDepth;
808 	float minDepth;
809 	float maxDepth;
810 };
811 
812 struct DepthBiasNonZeroParams
813 {
814 	vk::PipelineConstructionType	pipelineConstructionType;
815 	float							depthBiasConstant;
816 	float							depthBiasClamp;
817 	DepthBiasNonZeroPushConstants	pushConstants;
818 	bool							useMeshShaders;
819 };
820 
821 class DepthBiasNonZeroCase : public vkt::TestCase
822 {
823 private:
824 	DepthBiasNonZeroParams m_params;
825 
826 public:
827 						DepthBiasNonZeroCase	(tcu::TestContext& testCtx, const std::string& name, const DepthBiasNonZeroParams& params);
~DepthBiasNonZeroCase(void)828 	virtual				~DepthBiasNonZeroCase	(void) {}
829 
830 	void				checkSupport			(Context& context) const override;
831 	void				initPrograms			(vk::SourceCollections& programCollection) const override;
832 	TestInstance*		createInstance			(Context& context) const override;
833 
getExpectedColor()834 	static tcu::Vec4	getExpectedColor		() { return tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f); }
835 };
836 
837 class DepthBiasNonZeroInstance : public vkt::TestInstance
838 {
839 private:
840 	DepthBiasNonZeroParams m_params;
841 
842 public:
843 						DepthBiasNonZeroInstance	(Context& context, const DepthBiasNonZeroParams& params);
~DepthBiasNonZeroInstance(void)844 	virtual				~DepthBiasNonZeroInstance	(void) {}
845 
846 	tcu::TestStatus		iterate						(void) override;
847 };
848 
DepthBiasNonZeroCase(tcu::TestContext & testCtx,const std::string & name,const DepthBiasNonZeroParams & params)849 DepthBiasNonZeroCase::DepthBiasNonZeroCase (tcu::TestContext& testCtx, const std::string& name, const DepthBiasNonZeroParams& params)
850 	: vkt::TestCase		(testCtx, name)
851 	, m_params			(params)
852 {}
853 
createInstance(Context & context) const854 TestInstance* DepthBiasNonZeroCase::createInstance (Context& context) const
855 {
856 	return new DepthBiasNonZeroInstance(context, m_params);
857 }
858 
DepthBiasNonZeroInstance(Context & context,const DepthBiasNonZeroParams & params)859 DepthBiasNonZeroInstance::DepthBiasNonZeroInstance (Context& context, const DepthBiasNonZeroParams& params)
860 	: vkt::TestInstance	(context)
861 	, m_params			(params)
862 {}
863 
checkSupport(Context & context) const864 void DepthBiasNonZeroCase::checkSupport (Context& context) const
865 {
866 	if (m_params.depthBiasClamp != 0.0f)
867 		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_DEPTH_BIAS_CLAMP);
868 
869 	if (m_params.useMeshShaders)
870 		context.requireDeviceFunctionality("VK_EXT_mesh_shader");
871 
872 	checkPipelineConstructionRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_params.pipelineConstructionType);
873 }
874 
initPrograms(vk::SourceCollections & programCollection) const875 void DepthBiasNonZeroCase::initPrograms (vk::SourceCollections& programCollection) const
876 {
877 	if (m_params.useMeshShaders)
878 	{
879 		std::ostringstream mesh;
880 		mesh
881 			<< "#version 450\n"
882 			<< "#extension GL_EXT_mesh_shader : enable\n"
883 			<< "\n"
884 			<< "layout (push_constant, std430) uniform PushConstantBlock {\n"
885 			<< "	float geometryDepth;\n"
886 			<< "	float minDepth;\n"
887 			<< "	float maxDepth;\n"
888 			<< "} pc;\n"
889 			<< "\n"
890 			<< "vec2 positions[3] = vec2[](\n"
891 			<< "    vec2(-1.0, -1.0),\n"
892 			<< "    vec2(3.0, -1.0),\n"
893 			<< "    vec2(-1.0, 3.0)\n"
894 			<< ");\n"
895 			<< "\n"
896 			<< "layout(local_size_x=3) in;\n"
897 			<< "layout(triangles) out;\n"
898 			<< "layout(max_vertices=3, max_primitives=1) out;\n"
899 			<< "\n"
900 			<< "void main() {\n"
901 			<< "    SetMeshOutputsEXT(3u, 1u);\n"
902 			<< "    gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position = vec4(positions[gl_LocalInvocationIndex], pc.geometryDepth, 1.0);\n"
903 			<< "    gl_PrimitiveTriangleIndicesEXT[0] = uvec3(0, 1, 2);\n"
904 			<< "}\n"
905 			;
906 
907 		const vk::ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
908 		programCollection.glslSources.add("mesh") << glu::MeshSource(mesh.str()) << buildOptions;
909 	}
910 	else
911 	{
912 		std::ostringstream vert;
913 		vert
914 			<< "#version 450\n"
915 			<< "\n"
916 			<< "layout (push_constant, std430) uniform PushConstantBlock {\n"
917 			<< "	float geometryDepth;\n"
918 			<< "	float minDepth;\n"
919 			<< "	float maxDepth;\n"
920 			<< "} pc;\n"
921 			<< "\n"
922 			<< "vec2 positions[3] = vec2[](\n"
923 			<< "    vec2(-1.0, -1.0),\n"
924 			<< "    vec2(3.0, -1.0),\n"
925 			<< "    vec2(-1.0, 3.0)\n"
926 			<< ");\n"
927 			<< "\n"
928 			<< "void main() {\n"
929 			<< "    gl_Position = vec4(positions[gl_VertexIndex], pc.geometryDepth, 1.0);\n"
930 			<< "}\n"
931 			;
932 		programCollection.glslSources.add("vert") << glu::VertexSource(vert.str());
933 	}
934 
935 	const auto outColor = getExpectedColor();
936 	std::ostringstream frag;
937 	frag
938 		<< std::fixed << std::setprecision(1)
939 		<< "#version 450\n"
940 		<< "\n"
941 		<< "layout (push_constant, std430) uniform PushConstantBlock {\n"
942 		<< "	float geometryDepth;\n"
943 		<< "	float minDepth;\n"
944 		<< "	float maxDepth;\n"
945 		<< "} pc;\n"
946 		<< "\n"
947 		<< "layout (location=0) out vec4 outColor;\n"
948 		<< "\n"
949 		<< "void main() {\n"
950 		<< "    const float depth = gl_FragCoord.z;\n"
951 		<< "    if (depth >= pc.minDepth && depth <= pc.maxDepth) {\n"
952 		<< "	    outColor = vec4(" << outColor.x() << ", " << outColor.y() << ", " << outColor.z() << ", " << outColor.w() << ");\n"
953 		<< "    }\n"
954 		<< "}\n"
955 		;
956 
957 	programCollection.glslSources.add("frag") << glu::FragmentSource(frag.str());
958 }
959 
iterate(void)960 tcu::TestStatus DepthBiasNonZeroInstance::iterate (void)
961 {
962 	const auto& vki			= m_context.getInstanceInterface();
963 	const auto&	vkd			= m_context.getDeviceInterface();
964 	const auto  physDevice	= m_context.getPhysicalDevice();
965 	const auto	device		= m_context.getDevice();
966 	auto&		alloc		= m_context.getDefaultAllocator();
967 	const auto	qIndex		= m_context.getUniversalQueueFamilyIndex();
968 	const auto	queue		= m_context.getUniversalQueue();
969 
970 	const auto	depthFormat	= vk::VK_FORMAT_D16_UNORM;
971 	const auto	colorFormat	= vk::VK_FORMAT_R8G8B8A8_UNORM;
972 	const auto	colorUsage	= (vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
973 	const auto	depthUsage	= (vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
974 	const auto	extent		= vk::makeExtent3D(8u, 8u, 1u);
975 	const auto&	pcData		= m_params.pushConstants;
976 	const auto	pcDataSize	= static_cast<deUint32>(sizeof(pcData));
977 	const auto	pcStages	= ((m_params.useMeshShaders
978 #ifndef CTS_USES_VULKANSC
979 								? vk::VK_SHADER_STAGE_MESH_BIT_EXT
980 #else
981 								? 0
982 #endif // CTS_USES_VULKANSC
983 								: vk::VK_SHADER_STAGE_VERTEX_BIT)
984 							   | vk::VK_SHADER_STAGE_FRAGMENT_BIT);
985 	const auto	pcRange		= vk::makePushConstantRange(pcStages, 0u, pcDataSize);
986 	vk::RenderPassWrapper	renderPass	(m_params.pipelineConstructionType, vkd, device, colorFormat, depthFormat, vk::VK_ATTACHMENT_LOAD_OP_CLEAR, vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
987 	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);
988 
989 	// Color buffer.
990 	const vk::VkImageCreateInfo colorBufferInfo =
991 	{
992 		vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	//	VkStructureType			sType;
993 		nullptr,									//	const void*				pNext;
994 		0u,											//	VkImageCreateFlags		flags;
995 		vk::VK_IMAGE_TYPE_2D,						//	VkImageType				imageType;
996 		colorFormat,								//	VkFormat				format;
997 		extent,										//	VkExtent3D				extent;
998 		1u,											//	deUint32				mipLevels;
999 		1u,											//	deUint32				arrayLayers;
1000 		vk::VK_SAMPLE_COUNT_1_BIT,					//	VkSampleCountFlagBits	samples;
1001 		vk::VK_IMAGE_TILING_OPTIMAL,				//	VkImageTiling			tiling;
1002 		colorUsage,									//	VkImageUsageFlags		usage;
1003 		vk::VK_SHARING_MODE_EXCLUSIVE,				//	VkSharingMode			sharingMode;
1004 		0u,											//	deUint32				queueFamilyIndexCount;
1005 		nullptr,									//	const deUint32*			pQueueFamilyIndices;
1006 		vk::VK_IMAGE_LAYOUT_UNDEFINED,				//	VkImageLayout			initialLayout;
1007 	};
1008 	const auto colorBuffer = Image::createAndAlloc(vkd, device, colorBufferInfo, alloc, qIndex);
1009 
1010 	// Depth buffer.
1011 	const vk::VkImageCreateInfo depthBufferInfo =
1012 	{
1013 		vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	//	VkStructureType			sType;
1014 		nullptr,									//	const void*				pNext;
1015 		0u,											//	VkImageCreateFlags		flags;
1016 		vk::VK_IMAGE_TYPE_2D,						//	VkImageType				imageType;
1017 		depthFormat,								//	VkFormat				format;
1018 		extent,										//	VkExtent3D				extent;
1019 		1u,											//	deUint32				mipLevels;
1020 		1u,											//	deUint32				arrayLayers;
1021 		vk::VK_SAMPLE_COUNT_1_BIT,					//	VkSampleCountFlagBits	samples;
1022 		vk::VK_IMAGE_TILING_OPTIMAL,				//	VkImageTiling			tiling;
1023 		depthUsage,									//	VkImageUsageFlags		usage;
1024 		vk::VK_SHARING_MODE_EXCLUSIVE,				//	VkSharingMode			sharingMode;
1025 		0u,											//	deUint32				queueFamilyIndexCount;
1026 		nullptr,									//	const deUint32*			pQueueFamilyIndices;
1027 		vk::VK_IMAGE_LAYOUT_UNDEFINED,				//	VkImageLayout			initialLayout;
1028 	};
1029 	const auto depthBuffer = Image::createAndAlloc(vkd, device, depthBufferInfo, alloc, qIndex);
1030 
1031 	const auto colorSubresourceRange	= vk::makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
1032 	const auto colorView				= vk::makeImageView(vkd, device, colorBuffer->object(), vk::VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresourceRange);
1033 
1034 	const auto depthSubresourceRange	= vk::makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 1u, 0u, 1u);
1035 	const auto depthView				= vk::makeImageView(vkd, device, depthBuffer->object(), vk::VK_IMAGE_VIEW_TYPE_2D, depthFormat, depthSubresourceRange);
1036 
1037 	// Create framebuffer.
1038 	const std::vector<vk::VkImage>		images		{ colorBuffer->object(), depthBuffer->object()};
1039 	const std::vector<vk::VkImageView>	attachments	{ colorView.get(), depthView.get() };
1040 	renderPass.createFramebuffer(vkd, device, static_cast<deUint32>(attachments.size()), de::dataOrNull(images), de::dataOrNull(attachments), extent.width, extent.height);
1041 
1042 	// Descriptor set and pipeline layout.
1043 	vk::DescriptorSetLayoutBuilder setLayoutBuilder;
1044 	const auto dsLayout			= setLayoutBuilder.build(vkd, device);
1045 	const vk::PipelineLayoutWrapper pipelineLayout	(m_params.pipelineConstructionType, vkd, device, 1u, &dsLayout.get(), 1u, &pcRange);
1046 
1047 	// Shader modules.
1048 	vk::ShaderWrapper	vertModule;
1049 	vk::ShaderWrapper	meshModule;
1050 	vk::ShaderWrapper	fragModule;
1051 	const auto&						binaries	= m_context.getBinaryCollection();
1052 
1053 	if (binaries.contains("vert"))
1054 		vertModule = vk::ShaderWrapper(vkd, device, binaries.get("vert"));
1055 	if (binaries.contains("mesh"))
1056 		meshModule = vk::ShaderWrapper(vkd, device, binaries.get("mesh"));
1057 	fragModule = vk::ShaderWrapper(vkd, device, binaries.get("frag"), 0u);
1058 
1059 	const std::vector<vk::VkViewport>	viewports	{ vk::makeViewport(extent) };
1060 	const std::vector<vk::VkRect2D>		scissors	{ vk::makeRect2D(extent) };
1061 
1062 	// Vertex input state without bindings and attributes.
1063 	const vk::VkPipelineVertexInputStateCreateInfo vertexInputInfo =
1064 	{
1065 		vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType                             sType
1066 		nullptr,														// const void*                                 pNext
1067 		0u,																// VkPipelineVertexInputStateCreateFlags       flags
1068 		0u,																// deUint32                                    vertexBindingDescriptionCount
1069 		nullptr,														// const VkVertexInputBindingDescription*      pVertexBindingDescriptions
1070 		0u,																// deUint32                                    vertexAttributeDescriptionCount
1071 		nullptr,														// const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions
1072 	};
1073 
1074 	// Depth/stencil state, with depth test and writes enabled.
1075 	const vk::VkPipelineDepthStencilStateCreateInfo depthStencilStateInfo =
1076 	{
1077 		vk::VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType                          sType
1078 		nullptr,														// const void*                              pNext
1079 		0u,																// VkPipelineDepthStencilStateCreateFlags   flags
1080 		VK_TRUE,														// VkBool32                                 depthTestEnable
1081 		VK_TRUE,														// VkBool32                                 depthWriteEnable
1082 		vk::VK_COMPARE_OP_ALWAYS,										// VkCompareOp                              depthCompareOp
1083 		VK_FALSE,														// VkBool32                                 depthBoundsTestEnable
1084 		VK_FALSE,														// VkBool32                                 stencilTestEnable
1085 		stencilOp,														// VkStencilOpState                         front
1086 		stencilOp,														// VkStencilOpState                         back
1087 		0.0f,															// float                                    minDepthBounds
1088 		1.0f,															// float                                    maxDepthBounds
1089 	};
1090 
1091 	// Rasterization state with depth bias enabled.
1092 	const vk::VkPipelineRasterizationStateCreateInfo rasterizationInfo =
1093 	{
1094 		vk::VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,	// VkStructureType                            sType
1095 		nullptr,														// const void*                                pNext
1096 		0u,																// VkPipelineRasterizationStateCreateFlags    flags
1097 		VK_FALSE,														// VkBool32                                   depthClampEnable
1098 		VK_FALSE,														// VkBool32                                   rasterizerDiscardEnable
1099 		vk::VK_POLYGON_MODE_FILL,										// VkPolygonMode                              polygonMode
1100 		vk::VK_CULL_MODE_NONE,											// VkCullModeFlags                            cullMode
1101 		vk::VK_FRONT_FACE_CLOCKWISE,									// VkFrontFace                                frontFace
1102 		VK_TRUE,														// VkBool32                                   depthBiasEnable
1103 		0.0f,															// float                                      depthBiasConstantFactor
1104 		0.0f,															// float                                      depthBiasClamp
1105 		0.0f,															// float                                      depthBiasSlopeFactor
1106 		1.0f															// float                                      lineWidth
1107 	};
1108 
1109 	// Dynamic state.
1110 	const std::vector<vk::VkDynamicState> dynamicStates (1u, vk::VK_DYNAMIC_STATE_DEPTH_BIAS);
1111 
1112 	const vk::VkPipelineDynamicStateCreateInfo dynamicStateInfo =
1113 	{
1114 		vk::VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,	//	VkStructureType						sType;
1115 		nullptr,													//	const void*							pNext;
1116 		0u,															//	VkPipelineDynamicStateCreateFlags	flags;
1117 		static_cast<deUint32>(dynamicStates.size()),				//	deUint32							dynamicStateCount;
1118 		de::dataOrNull(dynamicStates),								//	const VkDynamicState*				pDynamicStates;
1119 	};
1120 
1121 	// Graphics pipeline.
1122 	vk::GraphicsPipelineWrapper pipeline(vki, vkd, physDevice, device, m_context.getDeviceExtensions(), m_params.pipelineConstructionType);
1123 
1124 #ifndef CTS_USES_VULKANSC
1125 	if (m_params.useMeshShaders)
1126 	{
1127 		pipeline.setDefaultTopology(vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
1128 			.setDefaultColorBlendState()
1129 			.setDynamicState(static_cast<const vk::VkPipelineDynamicStateCreateInfo*>(&dynamicStateInfo))
1130 			.setDefaultMultisampleState()
1131 			.setupPreRasterizationMeshShaderState(viewports, scissors, pipelineLayout, *renderPass, 0u, vk::ShaderWrapper(), meshModule, &rasterizationInfo)
1132 			.setupFragmentShaderState(pipelineLayout, *renderPass, 0u, fragModule, static_cast<const vk::VkPipelineDepthStencilStateCreateInfo*>(&depthStencilStateInfo))
1133 			.setupFragmentOutputState(*renderPass, 0u)
1134 			.setMonolithicPipelineLayout(pipelineLayout)
1135 			.buildPipeline();
1136 	}
1137 	else
1138 #endif // CTS_USES_VULKANSC
1139 	{
1140 		pipeline.setDefaultTopology(vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
1141 			.setDefaultColorBlendState()
1142 			.setDynamicState(static_cast<const vk::VkPipelineDynamicStateCreateInfo*>(&dynamicStateInfo))
1143 			.setDefaultMultisampleState()
1144 			.setupVertexInputState(&vertexInputInfo)
1145 			.setupPreRasterizationShaderState(viewports, scissors, pipelineLayout, *renderPass, 0u, vertModule, &rasterizationInfo)
1146 			.setupFragmentShaderState(pipelineLayout, *renderPass, 0u, fragModule, static_cast<const vk::VkPipelineDepthStencilStateCreateInfo*>(&depthStencilStateInfo))
1147 			.setupFragmentOutputState(*renderPass, 0u)
1148 			.setMonolithicPipelineLayout(pipelineLayout)
1149 			.buildPipeline();
1150 	}
1151 
1152 	// Command pool and buffer.
1153 	const auto cmdPool		= vk::makeCommandPool(vkd, device, qIndex);
1154 	const auto cmdBufferPtr	= vk::allocateCommandBuffer(vkd, device, cmdPool.get(), vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1155 	const auto cmdBuffer	= cmdBufferPtr.get();
1156 
1157 	// Clear colors.
1158 	const std::vector<vk::VkClearValue> clearColors =
1159 	{
1160 		vk::makeClearValueColorF32(0.0f, 0.0f, 0.0f, 1.0f),
1161 		vk::makeClearValueDepthStencil(0.0f, 0u),
1162 	};
1163 
1164 	vk::beginCommandBuffer(vkd, cmdBuffer);
1165 	renderPass.begin(vkd, cmdBuffer, scissors.at(0), static_cast<deUint32>(clearColors.size()), de::dataOrNull(clearColors));
1166 	pipeline.bind(cmdBuffer);
1167 	vkd.cmdSetDepthBias(cmdBuffer, m_params.depthBiasConstant, m_params.depthBiasClamp, 0.0f);
1168 	vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), pcStages, 0u, pcDataSize, &pcData);
1169 #ifndef CTS_USES_VULKANSC
1170 	if (m_params.useMeshShaders)
1171 	{
1172 		vkd.cmdDrawMeshTasksEXT(cmdBuffer, 1u, 1u, 1u);
1173 	}
1174 	else
1175 #endif // CTS_USES_VULKANSC
1176 	{
1177 		vkd.cmdDraw(cmdBuffer, 3u, 1u, 0u, 0u);
1178 	}
1179 	renderPass.end(vkd, cmdBuffer);
1180 	vk::endCommandBuffer(vkd, cmdBuffer);
1181 	vk::submitCommandsAndWait(vkd, device, queue, cmdBuffer);
1182 
1183 	// Check color buffer contents.
1184 	const auto		offset		= vk::makeOffset3D(0, 0, 0);
1185 	const auto		iWidth		= static_cast<int>(extent.width);
1186 	const auto		iHeight		= static_cast<int>(extent.height);
1187 	const auto		colorPixels	= colorBuffer->readSurface(queue, alloc, vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, offset, iWidth, iHeight, vk::VK_IMAGE_ASPECT_COLOR_BIT);
1188 	const auto		expected	= DepthBiasNonZeroCase::getExpectedColor();
1189 	const tcu::Vec4	threshold	(0.0f);
1190 	auto&			log			= m_context.getTestContext().getLog();
1191 
1192 	if (!tcu::floatThresholdCompare(log, "Result", "Result", expected, colorPixels, threshold, tcu::COMPARE_LOG_ON_ERROR))
1193 		return tcu::TestStatus::fail("Unexpected color buffer value; check log for details");
1194 
1195 	return tcu::TestStatus::pass("Pass");
1196 }
1197 
checkDepthBiasClampSupport(Context & context)1198 void checkDepthBiasClampSupport (Context& context)
1199 {
1200 	context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_DEPTH_BIAS_CLAMP);
1201 }
1202 
checkWideLinesSupport(Context & context)1203 void checkWideLinesSupport (Context& context)
1204 {
1205 	context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_WIDE_LINES);
1206 }
1207 
checkMeshShaderSupport(Context & context)1208 void checkMeshShaderSupport (Context& context)
1209 {
1210 	context.requireDeviceFunctionality("VK_EXT_mesh_shader");
1211 }
1212 
checkMeshAndBiasClampSupport(Context & context)1213 void checkMeshAndBiasClampSupport(Context& context)
1214 {
1215 	checkMeshShaderSupport(context);
1216 	checkDepthBiasClampSupport(context);
1217 }
1218 
checkMeshAndWideLinesSupport(Context & context)1219 void checkMeshAndWideLinesSupport(Context& context)
1220 {
1221 	checkMeshShaderSupport(context);
1222 	checkWideLinesSupport(context);
1223 }
1224 
checkNothing(Context &)1225 void checkNothing (Context&)
1226 {}
1227 
1228 } //anonymous
1229 
DynamicStateRSTests(tcu::TestContext & testCtx,vk::PipelineConstructionType pipelineConstructionType)1230 DynamicStateRSTests::DynamicStateRSTests (tcu::TestContext& testCtx, vk::PipelineConstructionType pipelineConstructionType)
1231 	: TestCaseGroup					(testCtx, "rs_state")
1232 	, m_pipelineConstructionType	(pipelineConstructionType)
1233 {
1234 	/* Left blank on purpose */
1235 }
1236 
~DynamicStateRSTests()1237 DynamicStateRSTests::~DynamicStateRSTests ()
1238 {
1239 }
1240 
init(void)1241 void DynamicStateRSTests::init (void)
1242 {
1243 	ShaderMap basePaths;
1244 	basePaths[glu::SHADERTYPE_FRAGMENT]	= "vulkan/dynamic_state/VertexFetch.frag";
1245 	basePaths[glu::SHADERTYPE_VERTEX]	= nullptr;
1246 	basePaths[glu::SHADERTYPE_MESH]		= nullptr;
1247 
1248 	for (int i = 0; i < 2; ++i)
1249 	{
1250 		ShaderMap shaderPaths(basePaths);
1251 		const bool isMesh = (i > 0);
1252 		std::string nameSuffix;
1253 
1254 		if (isMesh)
1255 		{
1256 #ifndef CTS_USES_VULKANSC
1257 			nameSuffix = "_mesh";
1258 			shaderPaths[glu::SHADERTYPE_MESH] = "vulkan/dynamic_state/VertexFetch.mesh";
1259 #else
1260 			continue;
1261 #endif // CTS_USES_VULKANSC
1262 		}
1263 		else
1264 		{
1265 			shaderPaths[glu::SHADERTYPE_VERTEX] = "vulkan/dynamic_state/VertexFetch.vert";
1266 		}
1267 
1268 		addChild(new InstanceFactory<DepthBiasParamTestInstance, FunctionSupport0>(m_testCtx, "depth_bias" + nameSuffix, m_pipelineConstructionType, shaderPaths, (isMesh ? checkMeshShaderSupport : checkNothing)));
1269 		addChild(new InstanceFactory<DepthBiasClampParamTestInstance, FunctionSupport0>(m_testCtx, "depth_bias_clamp" + nameSuffix, m_pipelineConstructionType, shaderPaths, (isMesh ? checkMeshAndBiasClampSupport : checkDepthBiasClampSupport)));
1270 		if (isMesh)
1271 			shaderPaths[glu::SHADERTYPE_MESH] = "vulkan/dynamic_state/VertexFetchLines.mesh";
1272 		// Draw a line with width set to max defined by physical device
1273 		addChild(new InstanceFactory<LineWidthParamTestInstance, FunctionSupport0>(m_testCtx, "line_width" + nameSuffix, m_pipelineConstructionType, shaderPaths, (isMesh ? checkMeshAndWideLinesSupport : checkWideLinesSupport)));
1274 
1275 		{
1276 			const DepthBiasNonZeroParams params =
1277 			{
1278 				m_pipelineConstructionType,
1279 				16384.0f,	//	float							depthBiasConstant;
1280 				0.0f,		//	float							depthBiasClamp;
1281 				{			//	DepthBiasNonZeroPushConstants	pushConstants;
1282 					0.375f,	//		float geometryDepth;
1283 					0.5f,	//		float minDepth;
1284 					1.0f,	//		float maxDepth;
1285 				},
1286 				isMesh,
1287 			};
1288 			addChild(new DepthBiasNonZeroCase(m_testCtx, "nonzero_depth_bias_constant" + nameSuffix, params));
1289 		}
1290 		{
1291 			const DepthBiasNonZeroParams params =
1292 			{
1293 				m_pipelineConstructionType,
1294 				16384.0f,		//	float							depthBiasConstant;
1295 				0.125f,			//	float							depthBiasClamp;
1296 				{				//	DepthBiasNonZeroPushConstants	pushConstants;
1297 					0.375f,		//		float geometryDepth;
1298 					0.46875f,	//		float minDepth;
1299 					0.53125f,	//		float maxDepth;
1300 				},
1301 				isMesh,
1302 			};
1303 			addChild(new DepthBiasNonZeroCase(m_testCtx, "nonzero_depth_bias_clamp" + nameSuffix, params));
1304 		}
1305 	}
1306 }
1307 
1308 } // DynamicState
1309 } // vkt
1310