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