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