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