• 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 State Depth Stencil Tests
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktDynamicStateDSTests.hpp"
26 
27 #include "vktTestCaseUtil.hpp"
28 #include "vktDynamicStateTestCaseUtil.hpp"
29 #include "vktDynamicStateBaseClass.hpp"
30 
31 #include "tcuTestLog.hpp"
32 #include "tcuResource.hpp"
33 #include "tcuImageCompare.hpp"
34 #include "tcuCommandLine.hpp"
35 #include "tcuTextureUtil.hpp"
36 #include "tcuRGBA.hpp"
37 
38 #include "vkRefUtil.hpp"
39 #include "vkImageUtil.hpp"
40 #include "vkTypeUtil.hpp"
41 #include "vkCmdUtil.hpp"
42 #include "vkBuilderUtil.hpp"
43 #include "vkObjUtil.hpp"
44 
45 #include "vktDrawCreateInfoUtil.hpp"
46 #include "vktDrawImageObjectUtil.hpp"
47 #include "vktDrawBufferObjectUtil.hpp"
48 #include "vkPrograms.hpp"
49 
50 namespace vkt
51 {
52 namespace DynamicState
53 {
54 
55 using namespace Draw;
56 
57 namespace
58 {
59 
60 class DepthStencilBaseCase : public TestInstance
61 {
62 public:
DepthStencilBaseCase(Context & context,vk::PipelineConstructionType pipelineConstructionType,const char * vertexShaderName,const char * fragmentShaderName,const char * meshShaderName=nullptr)63 	DepthStencilBaseCase (Context& context, vk::PipelineConstructionType pipelineConstructionType, const char* vertexShaderName, const char* fragmentShaderName, const char* meshShaderName = nullptr)
64 		: TestInstance						(context)
65 		, m_colorAttachmentFormat			(vk::VK_FORMAT_R8G8B8A8_UNORM)
66 		, m_depthStencilAttachmentFormat	(vk::VK_FORMAT_UNDEFINED)
67 		, m_topology						(vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
68 		, m_vk								(context.getDeviceInterface())
69 		, m_pipeline_1						(m_vk, context.getDevice(), pipelineConstructionType)
70 		, m_pipeline_2						(m_vk, context.getDevice(), pipelineConstructionType)
71 		, m_vertexShaderName				(vertexShaderName ? vertexShaderName : "")
72 		, m_fragmentShaderName				(fragmentShaderName)
73 		, m_meshShaderName					(meshShaderName ? meshShaderName : "")
74 		, m_isMesh							(meshShaderName != nullptr)
75 	{
76 		// Either a classic or mesh pipeline, but not both or none.
77 		DE_ASSERT((vertexShaderName != nullptr) != (meshShaderName != nullptr));
78 	}
79 
80 protected:
81 
82 	enum
83 	{
84 		WIDTH   = 128,
85 		HEIGHT  = 128
86 	};
87 
88 	vk::VkFormat									m_colorAttachmentFormat;
89 	vk::VkFormat									m_depthStencilAttachmentFormat;
90 
91 	vk::VkPrimitiveTopology							m_topology;
92 
93 	const vk::DeviceInterface&						m_vk;
94 
95 	vk::Move<vk::VkDescriptorPool>					m_descriptorPool;
96 	vk::Move<vk::VkDescriptorSetLayout>				m_setLayout;
97 	vk::Move<vk::VkPipelineLayout>					m_pipelineLayout;
98 	vk::Move<vk::VkDescriptorSet>					m_descriptorSet;
99 	vk::GraphicsPipelineWrapper						m_pipeline_1;
100 	vk::GraphicsPipelineWrapper						m_pipeline_2;
101 
102 	de::SharedPtr<Image>							m_colorTargetImage;
103 	vk::Move<vk::VkImageView>						m_colorTargetView;
104 
105 	de::SharedPtr<Image>							m_depthStencilImage;
106 	vk::Move<vk::VkImageView>						m_attachmentView;
107 
108 	PipelineCreateInfo::VertexInputState			m_vertexInputState;
109 	de::SharedPtr<Buffer>							m_vertexBuffer;
110 
111 	vk::Move<vk::VkCommandPool>						m_cmdPool;
112 	vk::Move<vk::VkCommandBuffer>					m_cmdBuffer;
113 
114 	vk::Move<vk::VkFramebuffer>						m_framebuffer;
115 	vk::Move<vk::VkRenderPass>						m_renderPass;
116 
117 	const std::string								m_vertexShaderName;
118 	const std::string								m_fragmentShaderName;
119 	const std::string								m_meshShaderName;
120 
121 	std::vector<PositionColorVertex>				m_data;
122 
123 	PipelineCreateInfo::DepthStencilState			m_depthStencilState_1;
124 	PipelineCreateInfo::DepthStencilState			m_depthStencilState_2;
125 
126 	const bool										m_isMesh;
127 
initialize(void)128 	void initialize (void)
129 	{
130 		const vk::VkDevice device = m_context.getDevice();
131 
132 		vk::VkFormatProperties formatProperties;
133 		// check for VK_FORMAT_D24_UNORM_S8_UINT support
134 		m_context.getInstanceInterface().getPhysicalDeviceFormatProperties(m_context.getPhysicalDevice(), vk::VK_FORMAT_D24_UNORM_S8_UINT, &formatProperties);
135 		if (formatProperties.optimalTilingFeatures & vk::VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
136 		{
137 			m_depthStencilAttachmentFormat = vk::VK_FORMAT_D24_UNORM_S8_UINT;
138 		}
139 		else
140 		{
141 			// check for VK_FORMAT_D32_SFLOAT_S8_UINT support
142 			m_context.getInstanceInterface().getPhysicalDeviceFormatProperties(m_context.getPhysicalDevice(), vk::VK_FORMAT_D32_SFLOAT_S8_UINT, &formatProperties);
143 			if (formatProperties.optimalTilingFeatures & vk::VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
144 			{
145 				m_depthStencilAttachmentFormat = vk::VK_FORMAT_D32_SFLOAT_S8_UINT;
146 			}
147 			else
148 				throw tcu::NotSupportedError("No valid depth stencil attachment available");
149 		}
150 		const auto								vertDescType		= (m_isMesh ? vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER : vk::VK_DESCRIPTOR_TYPE_MAX_ENUM);
151 		std::vector<vk::VkPushConstantRange>	pcRanges;
152 
153 #ifndef CTS_USES_VULKANSC
154 		// The mesh shading pipeline will contain a set with vertex data.
155 		if (m_isMesh)
156 		{
157 			vk::DescriptorSetLayoutBuilder	setLayoutBuilder;
158 			vk::DescriptorPoolBuilder		poolBuilder;
159 
160 			setLayoutBuilder.addSingleBinding(vertDescType, vk::VK_SHADER_STAGE_MESH_BIT_EXT);
161 			m_setLayout = setLayoutBuilder.build(m_vk, device);
162 
163 			poolBuilder.addType(vertDescType);
164 			m_descriptorPool = poolBuilder.build(m_vk, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
165 
166 			m_descriptorSet = vk::makeDescriptorSet(m_vk, device, m_descriptorPool.get(), m_setLayout.get());
167 			pcRanges.push_back(vk::makePushConstantRange(vk::VK_SHADER_STAGE_MESH_BIT_EXT, 0u, static_cast<uint32_t>(sizeof(uint32_t))));
168 		}
169 #endif // CTS_USES_VULKANSC
170 
171 		m_pipelineLayout = vk::makePipelineLayout(m_vk, device, m_setLayout.get(), de::dataOrNull(pcRanges));
172 
173 		const vk::VkExtent3D imageExtent = { WIDTH, HEIGHT, 1 };
174 		const ImageCreateInfo targetImageCreateInfo(vk::VK_IMAGE_TYPE_2D, m_colorAttachmentFormat, imageExtent, 1, 1, vk::VK_SAMPLE_COUNT_1_BIT,
175 													vk::VK_IMAGE_TILING_OPTIMAL,
176 													vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
177 													vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
178 													vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
179 
180 		m_colorTargetImage = Image::createAndAlloc(m_vk, device, targetImageCreateInfo, m_context.getDefaultAllocator(), m_context.getUniversalQueueFamilyIndex());
181 
182 		const ImageCreateInfo depthStencilImageCreateInfo(vk::VK_IMAGE_TYPE_2D, m_depthStencilAttachmentFormat, imageExtent,
183 														  1, 1, vk::VK_SAMPLE_COUNT_1_BIT, vk::VK_IMAGE_TILING_OPTIMAL,
184 														  vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
185 														  vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
186 
187 		m_depthStencilImage = Image::createAndAlloc(m_vk, device, depthStencilImageCreateInfo, m_context.getDefaultAllocator(), m_context.getUniversalQueueFamilyIndex());
188 
189 		const ImageViewCreateInfo colorTargetViewInfo(m_colorTargetImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, m_colorAttachmentFormat);
190 		m_colorTargetView = vk::createImageView(m_vk, device, &colorTargetViewInfo);
191 
192 		const ImageViewCreateInfo attachmentViewInfo(m_depthStencilImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, m_depthStencilAttachmentFormat);
193 		m_attachmentView = vk::createImageView(m_vk, device, &attachmentViewInfo);
194 
195 		RenderPassCreateInfo renderPassCreateInfo;
196 		renderPassCreateInfo.addAttachment(AttachmentDescription(m_colorAttachmentFormat,
197 																 vk::VK_SAMPLE_COUNT_1_BIT,
198 																 vk::VK_ATTACHMENT_LOAD_OP_LOAD,
199 																 vk::VK_ATTACHMENT_STORE_OP_STORE,
200 																 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
201 																 vk::VK_ATTACHMENT_STORE_OP_STORE,
202 																 vk::VK_IMAGE_LAYOUT_GENERAL,
203 																 vk::VK_IMAGE_LAYOUT_GENERAL));
204 
205 		renderPassCreateInfo.addAttachment(AttachmentDescription(m_depthStencilAttachmentFormat,
206 																 vk::VK_SAMPLE_COUNT_1_BIT,
207 																 vk::VK_ATTACHMENT_LOAD_OP_LOAD,
208 																 vk::VK_ATTACHMENT_STORE_OP_STORE,
209 																 vk::VK_ATTACHMENT_LOAD_OP_LOAD,
210 																 vk::VK_ATTACHMENT_STORE_OP_STORE,
211 																 vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
212 																 vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
213 
214 		const vk::VkAttachmentReference colorAttachmentReference =
215 		{
216 			0,
217 			vk::VK_IMAGE_LAYOUT_GENERAL
218 		};
219 
220 		const vk::VkAttachmentReference depthAttachmentReference =
221 		{
222 			1,
223 			vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
224 		};
225 
226 		renderPassCreateInfo.addSubpass(SubpassDescription(
227 			vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
228 			0,
229 			0,
230 			DE_NULL,
231 			1,
232 			&colorAttachmentReference,
233 			DE_NULL,
234 			depthAttachmentReference,
235 			0,
236 			DE_NULL));
237 
238 		m_renderPass = vk::createRenderPass(m_vk, device, &renderPassCreateInfo);
239 
240 		const vk::VkVertexInputBindingDescription vertexInputBindingDescription =
241 		{
242 			0,
243 			(deUint32)sizeof(tcu::Vec4) * 2,
244 			vk::VK_VERTEX_INPUT_RATE_VERTEX,
245 		};
246 
247 		const vk::VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
248 		{
249 			{
250 				0u,
251 				0u,
252 				vk::VK_FORMAT_R32G32B32A32_SFLOAT,
253 				0u
254 			},
255 			{
256 				1u,
257 				0u,
258 				vk::VK_FORMAT_R32G32B32A32_SFLOAT,
259 				(deUint32)(sizeof(float)* 4),
260 			}
261 		};
262 
263 		m_vertexInputState = PipelineCreateInfo::VertexInputState(
264 			1,
265 			&vertexInputBindingDescription,
266 			2,
267 			vertexInputAttributeDescriptions);
268 
269 		std::vector<vk::VkViewport>		viewports	{ { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } };
270 		std::vector<vk::VkRect2D>		scissors	{ { { 0u, 0u }, { 0u, 0u } } };
271 
272 		// Shaders.
273 		const auto&							binaries	= m_context.getBinaryCollection();
274 		const vk::Move<vk::VkShaderModule>	fs			= createShaderModule(m_vk, device, binaries.get(m_fragmentShaderName));
275 		const vk::Move<vk::VkShaderModule>	vs			= (m_isMesh ? vk::Move<vk::VkShaderModule>() : createShaderModule(m_vk, device, binaries.get(m_vertexShaderName)));
276 		const vk::Move<vk::VkShaderModule>	ms			= (m_isMesh ? createShaderModule(m_vk, device, binaries.get(m_meshShaderName)) : vk::Move<vk::VkShaderModule>());
277 
278 		const PipelineCreateInfo::ColorBlendState::Attachment	attachmentState;
279 		const PipelineCreateInfo::ColorBlendState				colorBlendState(1u, static_cast<const vk::VkPipelineColorBlendAttachmentState*>(&attachmentState));
280 		const PipelineCreateInfo::RasterizerState				rasterizerState;
281 		PipelineCreateInfo::DynamicState						dynamicState;
282 
283 		m_pipeline_1.setDefaultTopology(m_topology)
284 					.setDynamicState(static_cast<const vk::VkPipelineDynamicStateCreateInfo*>(&dynamicState))
285 					.setDefaultMultisampleState();
286 
287 #ifndef CTS_USES_VULKANSC
288 		if (m_isMesh)
289 		{
290 			m_pipeline_1
291 					.setupPreRasterizationMeshShaderState(viewports,
292 														  scissors,
293 														  *m_pipelineLayout,
294 														  *m_renderPass,
295 														  0u,
296 														  DE_NULL,
297 														  *ms,
298 														  static_cast<const vk::VkPipelineRasterizationStateCreateInfo*>(&rasterizerState));
299 		}
300 		else
301 #endif // CTS_USES_VULKANSC
302 		{
303 			m_pipeline_1
304 					.setupVertexInputState(&m_vertexInputState)
305 					.setupPreRasterizationShaderState(viewports,
306 													  scissors,
307 													  *m_pipelineLayout,
308 													  *m_renderPass,
309 													  0u,
310 													  *vs,
311 													  static_cast<const vk::VkPipelineRasterizationStateCreateInfo*>(&rasterizerState));
312 		}
313 
314 		m_pipeline_1.setupFragmentShaderState(*m_pipelineLayout, *m_renderPass, 0u, *fs, static_cast<const vk::VkPipelineDepthStencilStateCreateInfo*>(&m_depthStencilState_1))
315 					.setupFragmentOutputState(*m_renderPass, 0u, static_cast<const vk::VkPipelineColorBlendStateCreateInfo*>(&colorBlendState))
316 					.setMonolithicPipelineLayout(*m_pipelineLayout)
317 					.buildPipeline();
318 
319 		m_pipeline_2.setDefaultTopology(m_topology)
320 					.setDynamicState(static_cast<const vk::VkPipelineDynamicStateCreateInfo*>(&dynamicState))
321 					.setDefaultMultisampleState();
322 
323 #ifndef CTS_USES_VULKANSC
324 		if (m_isMesh)
325 		{
326 			m_pipeline_2
327 					.setupPreRasterizationMeshShaderState(viewports,
328 														  scissors,
329 														  *m_pipelineLayout,
330 														  *m_renderPass,
331 														  0u,
332 														  DE_NULL,
333 														  *ms,
334 														  static_cast<const vk::VkPipelineRasterizationStateCreateInfo*>(&rasterizerState));
335 		}
336 		else
337 #endif // CTS_USES_VULKANSC
338 		{
339 			m_pipeline_2
340 					.setupVertexInputState(&m_vertexInputState)
341 					.setupPreRasterizationShaderState(viewports,
342 													  scissors,
343 													  *m_pipelineLayout,
344 													  *m_renderPass,
345 													  0u,
346 													  *vs,
347 													  static_cast<const vk::VkPipelineRasterizationStateCreateInfo*>(&rasterizerState));
348 		}
349 
350 		m_pipeline_2.setupFragmentShaderState(*m_pipelineLayout, *m_renderPass, 0u, *fs, static_cast<const vk::VkPipelineDepthStencilStateCreateInfo*>(&m_depthStencilState_2))
351 					.setupFragmentOutputState(*m_renderPass, 0u, static_cast<const vk::VkPipelineColorBlendStateCreateInfo*>(&colorBlendState))
352 					.setMonolithicPipelineLayout(*m_pipelineLayout)
353 					.buildPipeline();
354 
355 		std::vector<vk::VkImageView> attachments(2);
356 		attachments[0] = *m_colorTargetView;
357 		attachments[1] = *m_attachmentView;
358 
359 		const FramebufferCreateInfo framebufferCreateInfo(*m_renderPass, attachments, WIDTH, HEIGHT, 1);
360 
361 		m_framebuffer = vk::createFramebuffer(m_vk, device, &framebufferCreateInfo);
362 
363 		const vk::VkDeviceSize	dataSize	= m_data.size() * sizeof(PositionColorVertex);
364 		const auto				bufferUsage	= (m_isMesh ? vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT : vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
365 		m_vertexBuffer = Buffer::createAndAlloc(m_vk, device, BufferCreateInfo(dataSize, bufferUsage),
366 												m_context.getDefaultAllocator(), vk::MemoryRequirement::HostVisible);
367 
368 		deUint8* ptr = reinterpret_cast<unsigned char *>(m_vertexBuffer->getBoundMemory().getHostPtr());
369 		deMemcpy(ptr, &m_data[0], (size_t)dataSize);
370 
371 		vk::flushAlloc(m_vk, device, m_vertexBuffer->getBoundMemory());
372 
373 		// Update descriptor set for mesh shaders.
374 		if (m_isMesh)
375 		{
376 			vk::DescriptorSetUpdateBuilder	updateBuilder;
377 			const auto						location		= vk::DescriptorSetUpdateBuilder::Location::binding(0u);
378 			const auto						bufferInfo		= vk::makeDescriptorBufferInfo(m_vertexBuffer->object(), 0ull, dataSize);
379 
380 			updateBuilder.writeSingle(m_descriptorSet.get(), location, vertDescType, &bufferInfo);
381 			updateBuilder.update(m_vk, device);
382 		}
383 
384 		const CmdPoolCreateInfo cmdPoolCreateInfo(m_context.getUniversalQueueFamilyIndex());
385 		m_cmdPool = vk::createCommandPool(m_vk, device, &cmdPoolCreateInfo);
386 		m_cmdBuffer = vk::allocateCommandBuffer(m_vk, device, *m_cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
387 	}
388 
iterate(void)389 	virtual tcu::TestStatus iterate (void)
390 	{
391 		DE_ASSERT(false);
392 		return tcu::TestStatus::fail("Implement iterate() method!");
393 	}
394 
beginRenderPass(void)395 	void beginRenderPass (void)
396 	{
397 		const vk::VkClearColorValue clearColor = { { 0.0f, 0.0f, 0.0f, 1.0f } };
398 		beginRenderPassWithClearColor(clearColor);
399 	}
400 
beginRenderPassWithClearColor(const vk::VkClearColorValue & clearColor)401 	void beginRenderPassWithClearColor (const vk::VkClearColorValue &clearColor)
402 	{
403 		beginCommandBuffer(m_vk, *m_cmdBuffer, 0u);
404 
405 		initialTransitionColor2DImage(m_vk, *m_cmdBuffer, m_colorTargetImage->object(), vk::VK_IMAGE_LAYOUT_GENERAL,
406 									  vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT);
407 		initialTransitionDepthStencil2DImage(m_vk, *m_cmdBuffer, m_depthStencilImage->object(), vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
408 											 vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT);
409 
410 		const ImageSubresourceRange subresourceRangeImage(vk::VK_IMAGE_ASPECT_COLOR_BIT);
411 		m_vk.cmdClearColorImage(*m_cmdBuffer, m_colorTargetImage->object(),
412 			vk::VK_IMAGE_LAYOUT_GENERAL, &clearColor, 1, &subresourceRangeImage);
413 
414 		const vk::VkClearDepthStencilValue depthStencilClearValue = { 0.0f, 0 };
415 
416 		const ImageSubresourceRange subresourceRangeDepthStencil[2] = { vk::VK_IMAGE_ASPECT_DEPTH_BIT, vk::VK_IMAGE_ASPECT_STENCIL_BIT };
417 		m_vk.cmdClearDepthStencilImage(*m_cmdBuffer, m_depthStencilImage->object(),
418 			vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &depthStencilClearValue, 2, subresourceRangeDepthStencil);
419 
420 		vk::VkMemoryBarrier memBarrier;
421 		memBarrier.sType = vk::VK_STRUCTURE_TYPE_MEMORY_BARRIER;
422 		memBarrier.pNext = NULL;
423 		memBarrier.srcAccessMask = vk::VK_ACCESS_TRANSFER_WRITE_BIT;
424 		memBarrier.dstAccessMask = vk::VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
425 					   vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
426 
427 		m_vk.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
428 						      vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
429 						      vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
430 						      0, 1, &memBarrier, 0, NULL, 0, NULL);
431 
432 		transition2DImage(m_vk, *m_cmdBuffer, m_depthStencilImage->object(), vk::VK_IMAGE_ASPECT_DEPTH_BIT | vk::VK_IMAGE_ASPECT_STENCIL_BIT,
433 						  vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
434 						  vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
435 						  vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
436 
437 		vk::beginRenderPass(m_vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, vk::makeRect2D(0, 0, WIDTH, HEIGHT));
438 	}
439 
setDynamicViewportState(const deUint32 width,const deUint32 height)440 	void setDynamicViewportState (const deUint32 width, const deUint32 height)
441 	{
442 		vk::VkViewport viewport = vk::makeViewport(tcu::UVec2(width, height));
443 		m_vk.cmdSetViewport(*m_cmdBuffer, 0, 1, &viewport);
444 
445 		vk::VkRect2D scissor = vk::makeRect2D(tcu::UVec2(width, height));
446 		m_vk.cmdSetScissor(*m_cmdBuffer, 0, 1, &scissor);
447 	}
448 
setDynamicViewportState(const deUint32 viewportCount,const vk::VkViewport * pViewports,const vk::VkRect2D * pScissors)449 	void setDynamicViewportState(const deUint32 viewportCount, const vk::VkViewport* pViewports, const vk::VkRect2D* pScissors)
450 	{
451 		m_vk.cmdSetViewport(*m_cmdBuffer, 0, viewportCount, pViewports);
452 		m_vk.cmdSetScissor(*m_cmdBuffer, 0, viewportCount, pScissors);
453 	}
454 
setDynamicRasterizationState(const float lineWidth=1.0f,const float depthBiasConstantFactor=0.0f,const float depthBiasClamp=0.0f,const float depthBiasSlopeFactor=0.0f)455 	void setDynamicRasterizationState(const float lineWidth = 1.0f,
456 							   const float depthBiasConstantFactor = 0.0f,
457 							   const float depthBiasClamp = 0.0f,
458 							   const float depthBiasSlopeFactor = 0.0f)
459 	{
460 		m_vk.cmdSetLineWidth(*m_cmdBuffer, lineWidth);
461 		m_vk.cmdSetDepthBias(*m_cmdBuffer, depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor);
462 	}
463 
setDynamicBlendState(const float const1=0.0f,const float const2=0.0f,const float const3=0.0f,const float const4=0.0f)464 	void setDynamicBlendState(const float const1 = 0.0f, const float const2 = 0.0f,
465 							  const float const3 = 0.0f, const float const4 = 0.0f)
466 	{
467 		float blendConstantsants[4] = { const1, const2, const3, const4 };
468 		m_vk.cmdSetBlendConstants(*m_cmdBuffer, blendConstantsants);
469 	}
470 
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)471 	void setDynamicDepthStencilState(const float minDepthBounds = -1.0f,
472 									 const float maxDepthBounds = 1.0f,
473 									 const deUint32 stencilFrontCompareMask = 0xffffffffu,
474 									 const deUint32 stencilFrontWriteMask = 0xffffffffu,
475 									 const deUint32 stencilFrontReference = 0,
476 									 const deUint32 stencilBackCompareMask = 0xffffffffu,
477 									 const deUint32 stencilBackWriteMask = 0xffffffffu,
478 									 const deUint32 stencilBackReference = 0)
479 	{
480 		m_vk.cmdSetDepthBounds(*m_cmdBuffer, minDepthBounds, maxDepthBounds);
481 		m_vk.cmdSetStencilCompareMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontCompareMask);
482 		m_vk.cmdSetStencilWriteMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontWriteMask);
483 		m_vk.cmdSetStencilReference(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontReference);
484 		m_vk.cmdSetStencilCompareMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackCompareMask);
485 		m_vk.cmdSetStencilWriteMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackWriteMask);
486 		m_vk.cmdSetStencilReference(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackReference);
487 	}
488 
489 #ifndef CTS_USES_VULKANSC
pushVertexOffset(const uint32_t vertexOffset,const vk::VkShaderStageFlags stageFlags=vk::VK_SHADER_STAGE_MESH_BIT_EXT)490 	void pushVertexOffset (const uint32_t				vertexOffset,
491 						   const vk::VkShaderStageFlags	stageFlags = vk::VK_SHADER_STAGE_MESH_BIT_EXT)
492 	{
493 		m_vk.cmdPushConstants(*m_cmdBuffer, *m_pipelineLayout, stageFlags, 0u, static_cast<uint32_t>(sizeof(uint32_t)), &vertexOffset);
494 	}
495 #endif // CTS_USES_VULKANSC
496 };
497 
498 class DepthBoundsParamTestInstance : public DepthStencilBaseCase
499 {
500 public:
DepthBoundsParamTestInstance(Context & context,vk::PipelineConstructionType pipelineConstructionType,const ShaderMap & shaders)501 	DepthBoundsParamTestInstance (Context &context, vk::PipelineConstructionType pipelineConstructionType, const ShaderMap& shaders)
502 		: DepthStencilBaseCase (context, pipelineConstructionType, shaders.at(glu::SHADERTYPE_VERTEX), shaders.at(glu::SHADERTYPE_FRAGMENT), shaders.at(glu::SHADERTYPE_MESH))
503 	{
504 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 0.375f, 1.0f), tcu::RGBA::green().toVec()));
505 		m_data.push_back(PositionColorVertex(tcu::Vec4(0.0f, 1.0f, 0.375f, 1.0f), tcu::RGBA::green().toVec()));
506 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 0.375f, 1.0f), tcu::RGBA::green().toVec()));
507 		m_data.push_back(PositionColorVertex(tcu::Vec4(0.0f, -1.0f, 0.375f, 1.0f), tcu::RGBA::green().toVec()));
508 
509 		m_data.push_back(PositionColorVertex(tcu::Vec4(0.0f, 1.0f, 0.625f, 1.0f), tcu::RGBA::green().toVec()));
510 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 0.625f, 1.0f), tcu::RGBA::green().toVec()));
511 		m_data.push_back(PositionColorVertex(tcu::Vec4(0.0f, -1.0f, 0.625f, 1.0f), tcu::RGBA::green().toVec()));
512 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 0.625f, 1.0f), tcu::RGBA::green().toVec()));
513 
514 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
515 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
516 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
517 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
518 
519 		m_depthStencilState_1 = PipelineCreateInfo::DepthStencilState(
520 			VK_TRUE, VK_TRUE, vk::VK_COMPARE_OP_ALWAYS, VK_FALSE);
521 
522 		// enable depth bounds test
523 		m_depthStencilState_2 = PipelineCreateInfo::DepthStencilState(
524 			VK_FALSE, VK_FALSE, vk::VK_COMPARE_OP_NEVER, VK_TRUE);
525 
526 		DepthStencilBaseCase::initialize();
527 	}
528 
iterate(void)529 	virtual tcu::TestStatus iterate (void)
530 	{
531 		tcu::TestLog&		log		= m_context.getTestContext().getLog();
532 		const vk::VkQueue	queue	= m_context.getUniversalQueue();
533 		const vk::VkDevice	device	= m_context.getDevice();
534 
535 		beginRenderPass();
536 
537 		// set states here
538 		setDynamicViewportState(WIDTH, HEIGHT);
539 		setDynamicRasterizationState();
540 		setDynamicBlendState();
541 		setDynamicDepthStencilState(0.5f, 0.75f);
542 
543 #ifndef CTS_USES_VULKANSC
544 		if (m_isMesh)
545 		{
546 			m_vk.cmdBindDescriptorSets(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout.get(), 0u, 1u, &m_descriptorSet.get(), 0u, nullptr);
547 
548 			m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_1.getPipeline());
549 			pushVertexOffset(0u); m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, 2u, 1u, 1u);
550 			pushVertexOffset(4u); m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, 2u, 1u, 1u);
551 
552 			m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_2.getPipeline());
553 			pushVertexOffset(8u); m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, 2u, 1u, 1u);
554 		}
555 		else
556 #endif // CTS_USES_VULKANSC
557 		{
558 			const vk::VkDeviceSize vertexBufferOffset = 0;
559 			const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
560 			m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
561 
562 			m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_1.getPipeline());
563 			m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
564 			m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 4, 0);
565 
566 			m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_2.getPipeline());
567 			m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 8, 0);
568 		}
569 
570 		endRenderPass(m_vk, *m_cmdBuffer);
571 		endCommandBuffer(m_vk, *m_cmdBuffer);
572 
573 		submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
574 
575 		// validation
576 		{
577 			tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5f + static_cast<float>(WIDTH)), (int)(0.5f + static_cast<float>(HEIGHT)));
578 			referenceFrame.allocLevel(0);
579 
580 			const deInt32 frameWidth = referenceFrame.getWidth();
581 			const deInt32 frameHeight = referenceFrame.getHeight();
582 
583 			tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
584 
585 			for (int y = 0; y < frameHeight; y++)
586 			{
587 				const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
588 
589 				for (int x = 0; x < frameWidth; x++)
590 				{
591 					const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
592 
593 					if (xCoord >= 0.0f && xCoord <= 1.0f && yCoord >= -1.0f && yCoord <= 1.0f)
594 						referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
595 					else
596 						referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
597 				}
598 			}
599 
600 			const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
601 			const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
602 				vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
603 
604 			if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
605 				referenceFrame.getLevel(0), renderedFrame, 0.05f,
606 				tcu::COMPARE_LOG_RESULT))
607 			{
608 				return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
609 			}
610 
611 			return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
612 		}
613 	}
614 };
615 
616 class DepthBoundsTestInstance : public DynamicStateBaseClass
617 {
618 public:
619 	enum
620 	{
621 		DEPTH_BOUNDS_MIN	= 0,
622 		DEPTH_BOUNDS_MAX	= 1,
623 		DEPTH_BOUNDS_COUNT	= 2
624 	};
625 	static const float					depthBounds[DEPTH_BOUNDS_COUNT];
626 
627 								DepthBoundsTestInstance		(Context&						context,
628 															 vk::PipelineConstructionType	pipelineConstructionType,
629 															 const ShaderMap&				shaders);
630 	virtual void				initRenderPass				(const vk::VkDevice		device);
631 	virtual void				initFramebuffer				(const vk::VkDevice		device);
632 	virtual void				initPipeline				(const vk::VkDevice		device);
633 	virtual tcu::TestStatus		iterate						(void);
634 private:
635 	const vk::VkFormat			m_depthAttachmentFormat;
636 
637 	de::SharedPtr<Draw::Image>	m_depthImage;
638 	vk::Move<vk::VkImageView>	m_depthView;
639 };
640 
641 const float DepthBoundsTestInstance::depthBounds[DEPTH_BOUNDS_COUNT] =
642 {
643 	0.3f,
644 	0.9f
645 };
646 
DepthBoundsTestInstance(Context & context,vk::PipelineConstructionType pipelineConstructionType,const ShaderMap & shaders)647 DepthBoundsTestInstance::DepthBoundsTestInstance(Context& context, vk::PipelineConstructionType pipelineConstructionType, const ShaderMap& shaders)
648 	: DynamicStateBaseClass		(context, pipelineConstructionType, shaders.at(glu::SHADERTYPE_VERTEX), shaders.at(glu::SHADERTYPE_FRAGMENT), shaders.at(glu::SHADERTYPE_MESH))
649 	, m_depthAttachmentFormat	(vk::VK_FORMAT_D16_UNORM)
650 {
651 	const vk::VkDevice device = m_context.getDevice();
652 	const vk::VkExtent3D depthImageExtent = { WIDTH, HEIGHT, 1 };
653 	const ImageCreateInfo depthImageCreateInfo(vk::VK_IMAGE_TYPE_2D, m_depthAttachmentFormat, depthImageExtent, 1, 1, vk::VK_SAMPLE_COUNT_1_BIT,
654 												vk::VK_IMAGE_TILING_OPTIMAL, vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
655 
656 	m_depthImage = Image::createAndAlloc(m_vk, device, depthImageCreateInfo, m_context.getDefaultAllocator(), m_context.getUniversalQueueFamilyIndex());
657 
658 	const ImageViewCreateInfo depthViewInfo(m_depthImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, m_depthAttachmentFormat);
659 	m_depthView = vk::createImageView(m_vk, device, &depthViewInfo);
660 
661 	m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f,  1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
662 	m_data.push_back(PositionColorVertex(tcu::Vec4( 1.0f,  1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
663 	m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
664 	m_data.push_back(PositionColorVertex(tcu::Vec4( 1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
665 
666 	DynamicStateBaseClass::initialize();
667 }
668 
669 
initRenderPass(const vk::VkDevice device)670 void DepthBoundsTestInstance::initRenderPass (const vk::VkDevice device)
671 {
672 	RenderPassCreateInfo renderPassCreateInfo;
673 	renderPassCreateInfo.addAttachment(AttachmentDescription(m_colorAttachmentFormat,
674 		vk::VK_SAMPLE_COUNT_1_BIT,
675 		vk::VK_ATTACHMENT_LOAD_OP_LOAD,
676 		vk::VK_ATTACHMENT_STORE_OP_STORE,
677 		vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
678 		vk::VK_ATTACHMENT_STORE_OP_STORE,
679 		vk::VK_IMAGE_LAYOUT_GENERAL,
680 		vk::VK_IMAGE_LAYOUT_GENERAL));
681 	renderPassCreateInfo.addAttachment(AttachmentDescription(m_depthAttachmentFormat,
682 		vk::VK_SAMPLE_COUNT_1_BIT,
683 		vk::VK_ATTACHMENT_LOAD_OP_LOAD,
684 		vk::VK_ATTACHMENT_STORE_OP_STORE,
685 		vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
686 		vk::VK_ATTACHMENT_STORE_OP_STORE,
687 		vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
688 		vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL));
689 
690 	const vk::VkAttachmentReference colorAttachmentReference =
691 	{
692 		0,
693 		vk::VK_IMAGE_LAYOUT_GENERAL
694 	};
695 
696 	const vk::VkAttachmentReference depthAttachmentReference =
697 	{
698 		1,
699 		vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
700 	};
701 
702 	renderPassCreateInfo.addSubpass(SubpassDescription(
703 		vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
704 		0,
705 		0,
706 		DE_NULL,
707 		1,
708 		&colorAttachmentReference,
709 		DE_NULL,
710 		depthAttachmentReference,
711 		0,
712 		DE_NULL
713 	)
714 	);
715 
716 	m_renderPass = vk::createRenderPass(m_vk, device, &renderPassCreateInfo);
717 }
718 
initFramebuffer(const vk::VkDevice device)719 void DepthBoundsTestInstance::initFramebuffer (const vk::VkDevice device)
720 {
721 	std::vector<vk::VkImageView> attachments(2);
722 	attachments[0] = *m_colorTargetView;
723 	attachments[1] = *m_depthView;
724 
725 	const FramebufferCreateInfo framebufferCreateInfo(*m_renderPass, attachments, WIDTH, HEIGHT, 1);
726 
727 	m_framebuffer = vk::createFramebuffer(m_vk, device, &framebufferCreateInfo);
728 }
729 
initPipeline(const vk::VkDevice device)730 void DepthBoundsTestInstance::initPipeline (const vk::VkDevice device)
731 {
732 	// Shaders.
733 	const auto&							binaries	= m_context.getBinaryCollection();
734 	const vk::Move<vk::VkShaderModule>	fs			= createShaderModule(m_vk, device, binaries.get(m_fragmentShaderName));
735 	const vk::Move<vk::VkShaderModule>	vs			= (m_isMesh ? vk::Move<vk::VkShaderModule>() : createShaderModule(m_vk, device, binaries.get(m_vertexShaderName)));
736 	const vk::Move<vk::VkShaderModule>	ms			= (m_isMesh ? createShaderModule(m_vk, device, binaries.get(m_meshShaderName)) : vk::Move<vk::VkShaderModule>());
737 	std::vector<vk::VkViewport>			viewports	{ { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } };
738 	std::vector<vk::VkRect2D>			scissors	{ { { 0u, 0u }, { 0u, 0u } } };
739 
740 	const PipelineCreateInfo::ColorBlendState::Attachment		attachmentState;
741 	const PipelineCreateInfo::ColorBlendState					colorBlendState(1u, static_cast<const vk::VkPipelineColorBlendAttachmentState*>(&attachmentState));
742 	const PipelineCreateInfo::RasterizerState					rasterizerState;
743 	const PipelineCreateInfo::DepthStencilState::StencilOpState stencilOpState(vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP);
744 	const PipelineCreateInfo::DepthStencilState					depthStencilState(false, false, vk::VK_COMPARE_OP_NEVER, true, 0u, stencilOpState, stencilOpState);
745 	const PipelineCreateInfo::DynamicState						dynamicState;
746 
747 	m_pipeline.setDefaultTopology(m_topology)
748 			  .setDynamicState(static_cast<const vk::VkPipelineDynamicStateCreateInfo*>(&dynamicState))
749 			  .setDefaultMultisampleState();
750 
751 #ifndef CTS_USES_VULKANSC
752 	if (m_isMesh)
753 	{
754 		m_pipeline
755 			  .setupPreRasterizationMeshShaderState(viewports,
756 													scissors,
757 													*m_pipelineLayout,
758 													*m_renderPass,
759 													0u,
760 													DE_NULL,
761 													*ms,
762 													static_cast<const vk::VkPipelineRasterizationStateCreateInfo*>(&rasterizerState));
763 	}
764 	else
765 #endif // CTS_USES_VULKANSC
766 	{
767 		m_pipeline
768 			  .setupVertexInputState(&m_vertexInputState)
769 			  .setupPreRasterizationShaderState(viewports,
770 												scissors,
771 												*m_pipelineLayout,
772 												*m_renderPass,
773 												0u,
774 												*vs,
775 												static_cast<const vk::VkPipelineRasterizationStateCreateInfo*>(&rasterizerState));
776 	}
777 
778 	m_pipeline.setupFragmentShaderState(*m_pipelineLayout, *m_renderPass, 0u, *fs, static_cast<const vk::VkPipelineDepthStencilStateCreateInfo*>(&depthStencilState))
779 			  .setupFragmentOutputState(*m_renderPass, 0u, static_cast<const vk::VkPipelineColorBlendStateCreateInfo*>(&colorBlendState))
780 			  .setMonolithicPipelineLayout(*m_pipelineLayout)
781 			  .buildPipeline();
782 }
783 
iterate(void)784 tcu::TestStatus DepthBoundsTestInstance::iterate (void)
785 {
786 	tcu::TestLog		&log		= m_context.getTestContext().getLog();
787 	const vk::VkQueue	queue		= m_context.getUniversalQueue();
788 	const vk::VkDevice	device		= m_context.getDevice();
789 
790 	// Prepare depth image
791 	tcu::Texture2D depthData(vk::mapVkFormat(m_depthAttachmentFormat), (int)(0.5f + static_cast<float>(WIDTH)), (int)(0.5f + static_cast<float>(HEIGHT)));
792 	depthData.allocLevel(0);
793 
794 	const deInt32 depthDataWidth	= depthData.getWidth();
795 	const deInt32 depthDataHeight	= depthData.getHeight();
796 
797 	for (int y = 0; y < depthDataHeight; ++y)
798 		for (int x = 0; x < depthDataWidth; ++x)
799 			depthData.getLevel(0).setPixDepth((float)(y * depthDataWidth + x % 11) / 10, x, y);
800 
801 	const vk::VkDeviceSize dataSize = depthData.getLevel(0).getWidth() * depthData.getLevel(0).getHeight()
802 		* tcu::getPixelSize(mapVkFormat(m_depthAttachmentFormat));
803 	de::SharedPtr<Draw::Buffer> stageBuffer = Buffer::createAndAlloc(m_vk, device, BufferCreateInfo(dataSize, vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT),
804 		m_context.getDefaultAllocator(), vk::MemoryRequirement::HostVisible);
805 
806 	deUint8* ptr = reinterpret_cast<unsigned char *>(stageBuffer->getBoundMemory().getHostPtr());
807 	deMemcpy(ptr, depthData.getLevel(0).getDataPtr(), (size_t)dataSize);
808 
809 	vk::flushAlloc(m_vk, device, stageBuffer->getBoundMemory());
810 
811 	beginCommandBuffer(m_vk, *m_cmdBuffer, 0u);
812 
813 	initialTransitionDepth2DImage(m_vk, *m_cmdBuffer, m_depthImage->object(), vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
814 								  vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT);
815 
816 	const vk::VkBufferImageCopy bufferImageCopy =
817 	{
818 		(vk::VkDeviceSize)0,														// VkDeviceSize					bufferOffset;
819 		0u,																			// deUint32						bufferRowLength;
820 		0u,																			// deUint32						bufferImageHeight;
821 		vk::makeImageSubresourceLayers(vk::VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u),	// VkImageSubresourceLayers		imageSubresource;
822 		vk::makeOffset3D(0, 0, 0),													// VkOffset3D					imageOffset;
823 		vk::makeExtent3D(WIDTH, HEIGHT, 1u)											// VkExtent3D					imageExtent;
824 	};
825 	m_vk.cmdCopyBufferToImage(*m_cmdBuffer, stageBuffer->object(), m_depthImage->object(), vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &bufferImageCopy);
826 
827 	transition2DImage(m_vk, *m_cmdBuffer, m_depthImage->object(), vk::VK_IMAGE_ASPECT_DEPTH_BIT, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
828 					  vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
829 					  vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
830 
831 	const vk::VkClearColorValue clearColor = { { 1.0f, 1.0f, 1.0f, 1.0f } };
832 	beginRenderPassWithClearColor(clearColor, true);
833 
834 	// Bind states
835 	setDynamicViewportState(WIDTH, HEIGHT);
836 	setDynamicRasterizationState();
837 	setDynamicBlendState();
838 	setDynamicDepthStencilState(depthBounds[DEPTH_BOUNDS_MIN], depthBounds[DEPTH_BOUNDS_MAX]);
839 
840 	m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline.getPipeline());
841 
842 #ifndef CTS_USES_VULKANSC
843 	if (m_isMesh)
844 	{
845 		const auto numVert = static_cast<uint32_t>(m_data.size());
846 		DE_ASSERT(numVert >= 2u);
847 
848 		m_vk.cmdBindDescriptorSets(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout.get(), 0u, 1u, &m_descriptorSet.get(), 0u, nullptr);
849 		pushVertexOffset(0u, *m_pipelineLayout);
850 		m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, numVert - 2u, 1u, 1u);
851 	}
852 	else
853 #endif // CTS_USES_VULKANSC
854 	{
855 
856 		const vk::VkDeviceSize	vertexBufferOffset	= 0;
857 		const vk::VkBuffer		vertexBuffer		= m_vertexBuffer->object();
858 		m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
859 
860 		m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
861 	}
862 
863 	endRenderPass(m_vk, *m_cmdBuffer);
864 	endCommandBuffer(m_vk, *m_cmdBuffer);
865 
866 	submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
867 
868 	// Validation
869 	{
870 		tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5f + static_cast<float>(WIDTH)), (int)(0.5f + static_cast<float>(HEIGHT)));
871 		referenceFrame.allocLevel(0);
872 
873 		const deInt32 frameWidth	= referenceFrame.getWidth();
874 		const deInt32 frameHeight	= referenceFrame.getHeight();
875 
876 		tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
877 
878 		for (int y = 0; y < frameHeight; ++y)
879 			for (int x = 0; x < frameWidth; ++x)
880 				if (depthData.getLevel(0).getPixDepth(x, y) >= depthBounds[DEPTH_BOUNDS_MIN]
881 					&& depthData.getLevel(0).getPixDepth(x, y) <= depthBounds[DEPTH_BOUNDS_MAX])
882 					referenceFrame.getLevel(0).setPixel(tcu::RGBA::green().toVec(), x, y);
883 
884 		const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
885 		const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
886 			vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
887 
888 		if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
889 			referenceFrame.getLevel(0), renderedFrame, 0.05f,
890 			tcu::COMPARE_LOG_RESULT))
891 		{
892 			return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
893 		}
894 
895 		return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
896 	}
897 }
898 
899 class StencilParamsBasicTestInstance : public DepthStencilBaseCase
900 {
901 protected:
902 	deUint32 m_writeMask;
903 	deUint32 m_readMask;
904 	deUint32 m_expectedValue;
905 	tcu::Vec4 m_expectedColor;
906 
907 public:
StencilParamsBasicTestInstance(Context & context,vk::PipelineConstructionType pipelineConstructionType,const char * vertexShaderName,const char * fragmentShaderName,const char * meshShaderName,const deUint32 writeMask,const deUint32 readMask,const deUint32 expectedValue,const tcu::Vec4 expectedColor)908 	StencilParamsBasicTestInstance (Context& context, vk::PipelineConstructionType pipelineConstructionType,
909 									const char* vertexShaderName, const char* fragmentShaderName, const char* meshShaderName,
910 									const deUint32 writeMask, const deUint32 readMask,
911 									const deUint32 expectedValue, const tcu::Vec4 expectedColor)
912 		: DepthStencilBaseCase  (context, pipelineConstructionType, vertexShaderName, fragmentShaderName, meshShaderName)
913 		, m_expectedColor		(1.0f, 1.0f, 1.0f, 1.0f)
914 	{
915 		m_writeMask = writeMask;
916 		m_readMask = readMask;
917 		m_expectedValue = expectedValue;
918 		m_expectedColor = expectedColor;
919 
920 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
921 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
922 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
923 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
924 
925 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
926 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
927 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
928 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
929 
930 		const PipelineCreateInfo::DepthStencilState::StencilOpState frontState_1 =
931 			PipelineCreateInfo::DepthStencilState::StencilOpState(
932 			vk::VK_STENCIL_OP_REPLACE,
933 			vk::VK_STENCIL_OP_REPLACE,
934 			vk::VK_STENCIL_OP_REPLACE,
935 			vk::VK_COMPARE_OP_ALWAYS);
936 
937 		const PipelineCreateInfo::DepthStencilState::StencilOpState backState_1 =
938 			PipelineCreateInfo::DepthStencilState::StencilOpState(
939 			vk::VK_STENCIL_OP_REPLACE,
940 			vk::VK_STENCIL_OP_REPLACE,
941 			vk::VK_STENCIL_OP_REPLACE,
942 			vk::VK_COMPARE_OP_ALWAYS);
943 
944 		const PipelineCreateInfo::DepthStencilState::StencilOpState frontState_2 =
945 			PipelineCreateInfo::DepthStencilState::StencilOpState(
946 			vk::VK_STENCIL_OP_REPLACE,
947 			vk::VK_STENCIL_OP_REPLACE,
948 			vk::VK_STENCIL_OP_REPLACE,
949 			vk::VK_COMPARE_OP_EQUAL);
950 
951 		const PipelineCreateInfo::DepthStencilState::StencilOpState backState_2 =
952 			PipelineCreateInfo::DepthStencilState::StencilOpState(
953 			vk::VK_STENCIL_OP_REPLACE,
954 			vk::VK_STENCIL_OP_REPLACE,
955 			vk::VK_STENCIL_OP_REPLACE,
956 			vk::VK_COMPARE_OP_EQUAL);
957 
958 		// enable stencil test
959 		m_depthStencilState_1 = PipelineCreateInfo::DepthStencilState(
960 			VK_FALSE, VK_FALSE, vk::VK_COMPARE_OP_NEVER, VK_FALSE, VK_TRUE, frontState_1, backState_1);
961 
962 		m_depthStencilState_2 = PipelineCreateInfo::DepthStencilState(
963 			VK_FALSE, VK_FALSE, vk::VK_COMPARE_OP_NEVER, VK_FALSE, VK_TRUE, frontState_2, backState_2);
964 
965 		DepthStencilBaseCase::initialize();
966 	}
967 
iterate(void)968 	virtual tcu::TestStatus iterate (void)
969 	{
970 		tcu::TestLog&		log		= m_context.getTestContext().getLog();
971 		const vk::VkQueue	queue	= m_context.getUniversalQueue();
972 		const vk::VkDevice	device	= m_context.getDevice();
973 
974 		beginRenderPass();
975 
976 		// set states here
977 		setDynamicViewportState(WIDTH, HEIGHT);
978 		setDynamicRasterizationState();
979 		setDynamicBlendState();
980 
981 #ifndef CTS_USES_VULKANSC
982 		if (m_isMesh)
983 		{
984 			m_vk.cmdBindDescriptorSets(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout.get(), 0u, 1u, &m_descriptorSet.get(), 0u, nullptr);
985 
986 			m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_1.getPipeline());
987 			setDynamicDepthStencilState(-1.0f, 1.0f, 0xFF, m_writeMask, 0x0F, 0xFF, m_writeMask, 0x0F);
988 			pushVertexOffset(0u); m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, 2u, 1u, 1u);
989 
990 			m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_2.getPipeline());
991 			setDynamicDepthStencilState(-1.0f, 1.0f, m_readMask, 0xFF, m_expectedValue, m_readMask, 0xFF, m_expectedValue);
992 			pushVertexOffset(4u); m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, 2u, 1u, 1u);
993 		}
994 		else
995 #endif // CTS_USES_VULKANSC
996 		{
997 			const vk::VkDeviceSize vertexBufferOffset = 0;
998 			const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
999 			m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
1000 
1001 			m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_1.getPipeline());
1002 			setDynamicDepthStencilState(-1.0f, 1.0f, 0xFF, m_writeMask, 0x0F, 0xFF, m_writeMask, 0x0F);
1003 			m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
1004 
1005 			m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_2.getPipeline());
1006 			setDynamicDepthStencilState(-1.0f, 1.0f, m_readMask, 0xFF, m_expectedValue, m_readMask, 0xFF, m_expectedValue);
1007 			m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 4, 0);
1008 		}
1009 
1010 		endRenderPass(m_vk, *m_cmdBuffer);
1011 		endCommandBuffer(m_vk, *m_cmdBuffer);
1012 
1013 		submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
1014 
1015 		// validation
1016 		{
1017 			tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5f + static_cast<float>(WIDTH)), (int)(0.5f + static_cast<float>(HEIGHT)));
1018 			referenceFrame.allocLevel(0);
1019 
1020 			const deInt32 frameWidth = referenceFrame.getWidth();
1021 			const deInt32 frameHeight = referenceFrame.getHeight();
1022 
1023 			for (int y = 0; y < frameHeight; y++)
1024 			{
1025 				const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
1026 
1027 				for (int x = 0; x < frameWidth; x++)
1028 				{
1029 					const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
1030 
1031 					if (xCoord >= -1.0f && xCoord <= 1.0f && yCoord >= -1.0f && yCoord <= 1.0f)
1032 						referenceFrame.getLevel(0).setPixel(m_expectedColor, x, y);
1033 				}
1034 			}
1035 
1036 			const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
1037 			const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
1038 				vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
1039 
1040 			if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
1041 				referenceFrame.getLevel(0), renderedFrame, 0.05f,
1042 				tcu::COMPARE_LOG_RESULT))
1043 			{
1044 				return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
1045 			}
1046 
1047 			return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
1048 		}
1049 	}
1050 };
1051 
checkNothing(Context &)1052 void checkNothing (Context&)
1053 {}
1054 
checkMeshShaderSupport(Context & context)1055 void checkMeshShaderSupport (Context& context)
1056 {
1057 	context.requireDeviceFunctionality("VK_EXT_mesh_shader");
1058 }
1059 
1060 class StencilParamsBasicTestCase : public TestCase
1061 {
1062 protected:
createInstance(Context & context) const1063 	TestInstance* createInstance(Context& context) const
1064 	{
1065 		return new StencilParamsBasicTestInstance(context, m_pipelineConstructionType,
1066 			(m_isMesh ? nullptr : "VertexFetch.vert"),
1067 			"VertexFetch.frag",
1068 			(m_isMesh ? "VertexFetch.mesh" : nullptr),
1069 			m_writeMask, m_readMask, m_expectedValue, m_expectedColor);
1070 	}
1071 
initPrograms(vk::SourceCollections & programCollection) const1072 	virtual void initPrograms(vk::SourceCollections& programCollection) const
1073 	{
1074 		programCollection.glslSources.add("VertexFetch.frag") <<
1075 			glu::FragmentSource(ShaderSourceProvider::getSource(m_testCtx.getArchive(), "vulkan/dynamic_state/VertexFetch.frag"));
1076 
1077 		if (m_isMesh)
1078 		{
1079 			programCollection.glslSources.add("VertexFetch.mesh")
1080 				<< glu::MeshSource(ShaderSourceProvider::getSource(m_testCtx.getArchive(), "vulkan/dynamic_state/VertexFetch.mesh"))
1081 				<< vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
1082 		}
1083 		else
1084 		{
1085 			programCollection.glslSources.add("VertexFetch.vert") <<
1086 				glu::VertexSource(ShaderSourceProvider::getSource(m_testCtx.getArchive(), "vulkan/dynamic_state/VertexFetch.vert"));
1087 		}
1088 	}
1089 
checkSupport(Context & context) const1090 	virtual void checkSupport(Context& context) const
1091 	{
1092 		checkMeshShaderSupport(context);
1093 		checkPipelineLibraryRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_pipelineConstructionType);
1094 	}
1095 
1096 	vk::PipelineConstructionType	m_pipelineConstructionType;
1097 	deUint32						m_writeMask;
1098 	deUint32						m_readMask;
1099 	deUint32						m_expectedValue;
1100 	tcu::Vec4						m_expectedColor;
1101 	const bool						m_isMesh;
1102 
1103 public:
StencilParamsBasicTestCase(tcu::TestContext & context,const std::string & name,const std::string & description,const vk::PipelineConstructionType pipelineConstructionType,const deUint32 writeMask,const deUint32 readMask,const deUint32 expectedValue,const tcu::Vec4 expectedColor,const bool isMesh)1104 	StencilParamsBasicTestCase (tcu::TestContext& context, const std::string& name, const std::string& description,
1105 								const vk::PipelineConstructionType pipelineConstructionType,
1106 								const deUint32 writeMask, const deUint32 readMask,
1107 								const deUint32 expectedValue, const tcu::Vec4 expectedColor,
1108 								const bool isMesh)
1109 		: TestCase						(context, name, description)
1110 		, m_pipelineConstructionType	(pipelineConstructionType)
1111 		, m_writeMask					(writeMask)
1112 		, m_readMask					(readMask)
1113 		, m_expectedValue				(expectedValue)
1114 		, m_expectedColor				(expectedColor)
1115 		, m_isMesh						(isMesh)
1116 	{
1117 	}
1118 };
1119 
1120 class StencilParamsAdvancedTestInstance : public DepthStencilBaseCase
1121 {
1122 public:
StencilParamsAdvancedTestInstance(Context & context,vk::PipelineConstructionType pipelineConstructionType,const ShaderMap & shaders)1123 	StencilParamsAdvancedTestInstance (Context& context, vk::PipelineConstructionType pipelineConstructionType, const ShaderMap& shaders)
1124 		: DepthStencilBaseCase (context, pipelineConstructionType, shaders.at(glu::SHADERTYPE_VERTEX), shaders.at(glu::SHADERTYPE_FRAGMENT), shaders.at(glu::SHADERTYPE_MESH))
1125 	{
1126 		m_data.push_back(PositionColorVertex(tcu::Vec4(-0.5f, 0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
1127 		m_data.push_back(PositionColorVertex(tcu::Vec4(0.5f, 0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
1128 		m_data.push_back(PositionColorVertex(tcu::Vec4(-0.5f, -0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
1129 		m_data.push_back(PositionColorVertex(tcu::Vec4(0.5f, -0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
1130 
1131 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
1132 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
1133 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
1134 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
1135 
1136 		const PipelineCreateInfo::DepthStencilState::StencilOpState frontState_1 =
1137 			PipelineCreateInfo::DepthStencilState::StencilOpState(
1138 			vk::VK_STENCIL_OP_REPLACE,
1139 			vk::VK_STENCIL_OP_REPLACE,
1140 			vk::VK_STENCIL_OP_REPLACE,
1141 			vk::VK_COMPARE_OP_ALWAYS);
1142 
1143 		const PipelineCreateInfo::DepthStencilState::StencilOpState backState_1 =
1144 			PipelineCreateInfo::DepthStencilState::StencilOpState(
1145 			vk::VK_STENCIL_OP_REPLACE,
1146 			vk::VK_STENCIL_OP_REPLACE,
1147 			vk::VK_STENCIL_OP_REPLACE,
1148 			vk::VK_COMPARE_OP_ALWAYS);
1149 
1150 		const PipelineCreateInfo::DepthStencilState::StencilOpState frontState_2 =
1151 			PipelineCreateInfo::DepthStencilState::StencilOpState(
1152 			vk::VK_STENCIL_OP_REPLACE,
1153 			vk::VK_STENCIL_OP_REPLACE,
1154 			vk::VK_STENCIL_OP_REPLACE,
1155 			vk::VK_COMPARE_OP_NOT_EQUAL);
1156 
1157 		const PipelineCreateInfo::DepthStencilState::StencilOpState backState_2 =
1158 			PipelineCreateInfo::DepthStencilState::StencilOpState(
1159 			vk::VK_STENCIL_OP_REPLACE,
1160 			vk::VK_STENCIL_OP_REPLACE,
1161 			vk::VK_STENCIL_OP_REPLACE,
1162 			vk::VK_COMPARE_OP_NOT_EQUAL);
1163 
1164 		// enable stencil test
1165 		m_depthStencilState_1 = PipelineCreateInfo::DepthStencilState(
1166 			VK_FALSE, VK_FALSE, vk::VK_COMPARE_OP_NEVER, VK_FALSE, VK_TRUE, frontState_1, backState_1);
1167 
1168 		m_depthStencilState_2 = PipelineCreateInfo::DepthStencilState(
1169 			VK_FALSE, VK_FALSE, vk::VK_COMPARE_OP_NEVER, VK_FALSE, VK_TRUE, frontState_2, backState_2);
1170 
1171 		DepthStencilBaseCase::initialize();
1172 	}
1173 
iterate(void)1174 	virtual tcu::TestStatus iterate (void)
1175 	{
1176 		tcu::TestLog&		log		= m_context.getTestContext().getLog();
1177 		const vk::VkQueue	queue	= m_context.getUniversalQueue();
1178 		const vk::VkDevice	device	= m_context.getDevice();
1179 
1180 		beginRenderPass();
1181 
1182 		// set states here
1183 		setDynamicViewportState(WIDTH, HEIGHT);
1184 		setDynamicRasterizationState();
1185 		setDynamicBlendState();
1186 
1187 #ifndef CTS_USES_VULKANSC
1188 		if (m_isMesh)
1189 		{
1190 			m_vk.cmdBindDescriptorSets(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout.get(), 0u, 1u, &m_descriptorSet.get(), 0u, nullptr);
1191 
1192 			m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_1.getPipeline());
1193 			setDynamicDepthStencilState(-1.0f, 1.0f, 0xFF, 0x0E, 0x0F, 0xFF, 0x0E, 0x0F);
1194 			pushVertexOffset(0u); m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, 2u, 1u, 1u);
1195 
1196 			m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_2.getPipeline());
1197 			setDynamicDepthStencilState(-1.0f, 1.0f, 0xFF, 0xFF, 0x0E, 0xFF, 0xFF, 0x0E);
1198 			pushVertexOffset(4u); m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, 2u, 1u, 1u);
1199 		}
1200 		else
1201 #endif // CTS_USES_VULKANSC
1202 		{
1203 			const vk::VkDeviceSize vertexBufferOffset = 0;
1204 			const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
1205 			m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
1206 
1207 			m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_1.getPipeline());
1208 			setDynamicDepthStencilState(-1.0f, 1.0f, 0xFF, 0x0E, 0x0F, 0xFF, 0x0E, 0x0F);
1209 			m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
1210 
1211 			m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_2.getPipeline());
1212 			setDynamicDepthStencilState(-1.0f, 1.0f, 0xFF, 0xFF, 0x0E, 0xFF, 0xFF, 0x0E);
1213 			m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 4, 0);
1214 		}
1215 
1216 		endRenderPass(m_vk, *m_cmdBuffer);
1217 		endCommandBuffer(m_vk, *m_cmdBuffer);
1218 
1219 		submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
1220 
1221 		// validation
1222 		{
1223 			tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5f + static_cast<float>(WIDTH)), (int)(0.5f + static_cast<float>(HEIGHT)));
1224 			referenceFrame.allocLevel(0);
1225 
1226 			const deInt32 frameWidth = referenceFrame.getWidth();
1227 			const deInt32 frameHeight = referenceFrame.getHeight();
1228 
1229 			for (int y = 0; y < frameHeight; y++)
1230 			{
1231 				const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
1232 
1233 				for (int x = 0; x < frameWidth; x++)
1234 				{
1235 					const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
1236 
1237 					if (xCoord >= -0.5f && xCoord <= 0.5f && yCoord >= -0.5f && yCoord <= 0.5f)
1238 						referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
1239 					else
1240 						referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
1241 				}
1242 			}
1243 
1244 			const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
1245 			const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
1246 				vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
1247 
1248 			if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
1249 				referenceFrame.getLevel(0), renderedFrame, 0.05f,
1250 				tcu::COMPARE_LOG_RESULT))
1251 			{
1252 				return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
1253 			}
1254 
1255 			return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
1256 		}
1257 	}
1258 };
1259 
checkDepthBoundsSupport(Context & context)1260 void checkDepthBoundsSupport (Context& context)
1261 {
1262 	context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_DEPTH_BOUNDS);
1263 }
1264 
1265 #ifndef CTS_USES_VULKANSC
checkDepthBoundsAndMeshShaderSupport(Context & context)1266 void checkDepthBoundsAndMeshShaderSupport (Context& context)
1267 {
1268 	checkDepthBoundsSupport(context);
1269 	checkMeshShaderSupport(context);
1270 }
1271 #endif // CTS_USES_VULKANSC
1272 
1273 } //anonymous
1274 
DynamicStateDSTests(tcu::TestContext & testCtx,vk::PipelineConstructionType pipelineConstructionType)1275 DynamicStateDSTests::DynamicStateDSTests (tcu::TestContext& testCtx, vk::PipelineConstructionType pipelineConstructionType)
1276 	: TestCaseGroup					(testCtx, "ds_state", "Tests for depth stencil state")
1277 	, m_pipelineConstructionType	(pipelineConstructionType)
1278 {
1279 	/* Left blank on purpose */
1280 }
1281 
~DynamicStateDSTests()1282 DynamicStateDSTests::~DynamicStateDSTests ()
1283 {
1284 }
1285 
init(void)1286 void DynamicStateDSTests::init (void)
1287 {
1288 	ShaderMap basePaths;
1289 	basePaths[glu::SHADERTYPE_FRAGMENT]	= "vulkan/dynamic_state/VertexFetch.frag";
1290 	basePaths[glu::SHADERTYPE_MESH]		= nullptr;
1291 	basePaths[glu::SHADERTYPE_VERTEX]	= nullptr;
1292 
1293 	for (int useMeshIdx = 0; useMeshIdx < 2; ++useMeshIdx)
1294 	{
1295 		const bool					useMesh				= (useMeshIdx > 0);
1296 		ShaderMap					shaderPaths			(basePaths);
1297 		FunctionSupport0::Function	depthBoundsCheck	= nullptr;
1298 		FunctionSupport0::Function	meshSupportCheck	= (useMesh ? checkMeshShaderSupport : checkNothing);
1299 		std::string					nameSuffix;
1300 		std::string					descSuffix;
1301 
1302 		if (useMesh)
1303 		{
1304 #ifndef CTS_USES_VULKANSC
1305 			shaderPaths[glu::SHADERTYPE_MESH] = "vulkan/dynamic_state/VertexFetch.mesh";
1306 			depthBoundsCheck = checkDepthBoundsAndMeshShaderSupport;
1307 			nameSuffix = "_mesh";
1308 			descSuffix = " using mesh shaders";
1309 #else
1310 			continue;
1311 #endif // CTS_USES_VULKANSC
1312 		}
1313 		else
1314 		{
1315 			shaderPaths[glu::SHADERTYPE_VERTEX] = "vulkan/dynamic_state/VertexFetch.vert";
1316 			depthBoundsCheck = checkDepthBoundsSupport;
1317 		}
1318 
1319 		addChild(new InstanceFactory<DepthBoundsParamTestInstance, FunctionSupport0>(m_testCtx, "depth_bounds_1" + nameSuffix, "Perform depth bounds test 1" + descSuffix, m_pipelineConstructionType, shaderPaths, depthBoundsCheck));
1320 		addChild(new InstanceFactory<DepthBoundsTestInstance, FunctionSupport0>(m_testCtx, "depth_bounds_2" + nameSuffix, "Perform depth bounds test 1" + descSuffix, m_pipelineConstructionType, shaderPaths, depthBoundsCheck));
1321 #ifndef CTS_USES_VULKANSC
1322 		addChild(new StencilParamsBasicTestCase(m_testCtx, "stencil_params_basic_1" + nameSuffix, "Perform basic stencil test 1" + descSuffix, m_pipelineConstructionType, 0x0D, 0x06, 0x05, tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), useMesh));
1323 		addChild(new StencilParamsBasicTestCase(m_testCtx, "stencil_params_basic_2" + nameSuffix, "Perform basic stencil test 2" + descSuffix, m_pipelineConstructionType, 0x06, 0x02, 0x05, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), useMesh));
1324 #endif // CTS_USES_VULKANSC
1325 		addChild(new InstanceFactory<StencilParamsAdvancedTestInstance, FunctionSupport0>(m_testCtx, "stencil_params_advanced" + nameSuffix, "Perform advanced stencil test" + descSuffix, m_pipelineConstructionType, shaderPaths, meshSupportCheck));
1326 	}
1327 }
1328 
1329 } // DynamicState
1330 } // vkt
1331