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 
43 #include "vktDrawCreateInfoUtil.hpp"
44 #include "vktDrawImageObjectUtil.hpp"
45 #include "vktDrawBufferObjectUtil.hpp"
46 #include "vkPrograms.hpp"
47 
48 namespace vkt
49 {
50 namespace DynamicState
51 {
52 
53 using namespace Draw;
54 
55 namespace
56 {
57 
58 class DepthStencilBaseCase : public TestInstance
59 {
60 public:
DepthStencilBaseCase(Context & context,const char * vertexShaderName,const char * fragmentShaderName)61 	DepthStencilBaseCase (Context& context, const char* vertexShaderName, const char* fragmentShaderName)
62 		: TestInstance						(context)
63 		, m_colorAttachmentFormat			(vk::VK_FORMAT_R8G8B8A8_UNORM)
64 		, m_topology						(vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
65 		, m_vk								(context.getDeviceInterface())
66 		, m_vertexShaderName				(vertexShaderName)
67 		, m_fragmentShaderName				(fragmentShaderName)
68 	{
69 	}
70 
71 protected:
72 
73 	enum
74 	{
75 		WIDTH   = 128,
76 		HEIGHT  = 128
77 	};
78 
79 	vk::VkFormat									m_colorAttachmentFormat;
80 	vk::VkFormat									m_depthStencilAttachmentFormat;
81 
82 	vk::VkPrimitiveTopology							m_topology;
83 
84 	const vk::DeviceInterface&						m_vk;
85 
86 	vk::Move<vk::VkPipeline>						m_pipeline_1;
87 	vk::Move<vk::VkPipeline>						m_pipeline_2;
88 	vk::Move<vk::VkPipelineLayout>					m_pipelineLayout;
89 
90 	de::SharedPtr<Image>							m_colorTargetImage;
91 	vk::Move<vk::VkImageView>						m_colorTargetView;
92 
93 	de::SharedPtr<Image>							m_depthStencilImage;
94 	vk::Move<vk::VkImageView>						m_attachmentView;
95 
96 	PipelineCreateInfo::VertexInputState			m_vertexInputState;
97 	de::SharedPtr<Buffer>							m_vertexBuffer;
98 
99 	vk::Move<vk::VkCommandPool>						m_cmdPool;
100 	vk::Move<vk::VkCommandBuffer>					m_cmdBuffer;
101 
102 	vk::Move<vk::VkFramebuffer>						m_framebuffer;
103 	vk::Move<vk::VkRenderPass>						m_renderPass;
104 
105 	const std::string								m_vertexShaderName;
106 	const std::string								m_fragmentShaderName;
107 
108 	std::vector<PositionColorVertex>				m_data;
109 
110 	PipelineCreateInfo::DepthStencilState			m_depthStencilState_1;
111 	PipelineCreateInfo::DepthStencilState			m_depthStencilState_2;
112 
initialize(void)113 	void initialize (void)
114 	{
115 		const vk::VkDevice device = m_context.getDevice();
116 
117 		vk::VkFormatProperties formatProperties;
118 		// check for VK_FORMAT_D24_UNORM_S8_UINT support
119 		m_context.getInstanceInterface().getPhysicalDeviceFormatProperties(m_context.getPhysicalDevice(), vk::VK_FORMAT_D24_UNORM_S8_UINT, &formatProperties);
120 		if (formatProperties.optimalTilingFeatures & vk::VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
121 		{
122 			m_depthStencilAttachmentFormat = vk::VK_FORMAT_D24_UNORM_S8_UINT;
123 		}
124 		else
125 		{
126 			// check for VK_FORMAT_D32_SFLOAT_S8_UINT support
127 			m_context.getInstanceInterface().getPhysicalDeviceFormatProperties(m_context.getPhysicalDevice(), vk::VK_FORMAT_D32_SFLOAT_S8_UINT, &formatProperties);
128 			if (formatProperties.optimalTilingFeatures & vk::VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
129 			{
130 				m_depthStencilAttachmentFormat = vk::VK_FORMAT_D32_SFLOAT_S8_UINT;
131 			}
132 			else
133 				throw tcu::NotSupportedError("No valid depth stencil attachment available");
134 		}
135 
136 		const PipelineLayoutCreateInfo pipelineLayoutCreateInfo;
137 		m_pipelineLayout = vk::createPipelineLayout(m_vk, device, &pipelineLayoutCreateInfo);
138 
139 		const vk::Unique<vk::VkShaderModule> vs(createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_vertexShaderName), 0));
140 		const vk::Unique<vk::VkShaderModule> fs(createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_fragmentShaderName), 0));
141 
142 		const vk::VkExtent3D imageExtent = { WIDTH, HEIGHT, 1 };
143 		const ImageCreateInfo targetImageCreateInfo(vk::VK_IMAGE_TYPE_2D, m_colorAttachmentFormat, imageExtent, 1, 1, vk::VK_SAMPLE_COUNT_1_BIT,
144 													vk::VK_IMAGE_TILING_OPTIMAL,
145 													vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
146 													vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
147 													vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
148 
149 		m_colorTargetImage = Image::createAndAlloc(m_vk, device, targetImageCreateInfo, m_context.getDefaultAllocator(), m_context.getUniversalQueueFamilyIndex());
150 
151 		const ImageCreateInfo depthStencilImageCreateInfo(vk::VK_IMAGE_TYPE_2D, m_depthStencilAttachmentFormat, imageExtent,
152 														  1, 1, vk::VK_SAMPLE_COUNT_1_BIT, vk::VK_IMAGE_TILING_OPTIMAL,
153 														  vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
154 														  vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
155 
156 		m_depthStencilImage = Image::createAndAlloc(m_vk, device, depthStencilImageCreateInfo, m_context.getDefaultAllocator(), m_context.getUniversalQueueFamilyIndex());
157 
158 		const ImageViewCreateInfo colorTargetViewInfo(m_colorTargetImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, m_colorAttachmentFormat);
159 		m_colorTargetView = vk::createImageView(m_vk, device, &colorTargetViewInfo);
160 
161 		const ImageViewCreateInfo attachmentViewInfo(m_depthStencilImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, m_depthStencilAttachmentFormat);
162 		m_attachmentView = vk::createImageView(m_vk, device, &attachmentViewInfo);
163 
164 		RenderPassCreateInfo renderPassCreateInfo;
165 		renderPassCreateInfo.addAttachment(AttachmentDescription(m_colorAttachmentFormat,
166 																 vk::VK_SAMPLE_COUNT_1_BIT,
167 																 vk::VK_ATTACHMENT_LOAD_OP_LOAD,
168 																 vk::VK_ATTACHMENT_STORE_OP_STORE,
169 																 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
170 																 vk::VK_ATTACHMENT_STORE_OP_STORE,
171 																 vk::VK_IMAGE_LAYOUT_GENERAL,
172 																 vk::VK_IMAGE_LAYOUT_GENERAL));
173 
174 		renderPassCreateInfo.addAttachment(AttachmentDescription(m_depthStencilAttachmentFormat,
175 																 vk::VK_SAMPLE_COUNT_1_BIT,
176 																 vk::VK_ATTACHMENT_LOAD_OP_LOAD,
177 																 vk::VK_ATTACHMENT_STORE_OP_STORE,
178 																 vk::VK_ATTACHMENT_LOAD_OP_LOAD,
179 																 vk::VK_ATTACHMENT_STORE_OP_STORE,
180 																 vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
181 																 vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
182 
183 		const vk::VkAttachmentReference colorAttachmentReference =
184 		{
185 			0,
186 			vk::VK_IMAGE_LAYOUT_GENERAL
187 		};
188 
189 		const vk::VkAttachmentReference depthAttachmentReference =
190 		{
191 			1,
192 			vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
193 		};
194 
195 		renderPassCreateInfo.addSubpass(SubpassDescription(
196 			vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
197 			0,
198 			0,
199 			DE_NULL,
200 			1,
201 			&colorAttachmentReference,
202 			DE_NULL,
203 			depthAttachmentReference,
204 			0,
205 			DE_NULL));
206 
207 		m_renderPass = vk::createRenderPass(m_vk, device, &renderPassCreateInfo);
208 
209 		const vk::VkVertexInputBindingDescription vertexInputBindingDescription =
210 		{
211 			0,
212 			(deUint32)sizeof(tcu::Vec4) * 2,
213 			vk::VK_VERTEX_INPUT_RATE_VERTEX,
214 		};
215 
216 		const vk::VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
217 		{
218 			{
219 				0u,
220 				0u,
221 				vk::VK_FORMAT_R32G32B32A32_SFLOAT,
222 				0u
223 			},
224 			{
225 				1u,
226 				0u,
227 				vk::VK_FORMAT_R32G32B32A32_SFLOAT,
228 				(deUint32)(sizeof(float)* 4),
229 			}
230 		};
231 
232 		m_vertexInputState = PipelineCreateInfo::VertexInputState(
233 			1,
234 			&vertexInputBindingDescription,
235 			2,
236 			vertexInputAttributeDescriptions);
237 
238 		const PipelineCreateInfo::ColorBlendState::Attachment vkCbAttachmentState;
239 
240 		PipelineCreateInfo pipelineCreateInfo_1(*m_pipelineLayout, *m_renderPass, 0, 0);
241 		pipelineCreateInfo_1.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", vk::VK_SHADER_STAGE_VERTEX_BIT));
242 		pipelineCreateInfo_1.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, "main", vk::VK_SHADER_STAGE_FRAGMENT_BIT));
243 		pipelineCreateInfo_1.addState(PipelineCreateInfo::VertexInputState(m_vertexInputState));
244 		pipelineCreateInfo_1.addState(PipelineCreateInfo::InputAssemblerState(m_topology));
245 		pipelineCreateInfo_1.addState(PipelineCreateInfo::ColorBlendState(1, &vkCbAttachmentState));
246 		pipelineCreateInfo_1.addState(PipelineCreateInfo::ViewportState(1));
247 		pipelineCreateInfo_1.addState(m_depthStencilState_1);
248 		pipelineCreateInfo_1.addState(PipelineCreateInfo::RasterizerState());
249 		pipelineCreateInfo_1.addState(PipelineCreateInfo::MultiSampleState());
250 		pipelineCreateInfo_1.addState(PipelineCreateInfo::DynamicState());
251 
252 		PipelineCreateInfo pipelineCreateInfo_2(*m_pipelineLayout, *m_renderPass, 0, 0);
253 		pipelineCreateInfo_2.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", vk::VK_SHADER_STAGE_VERTEX_BIT));
254 		pipelineCreateInfo_2.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, "main", vk::VK_SHADER_STAGE_FRAGMENT_BIT));
255 		pipelineCreateInfo_2.addState(PipelineCreateInfo::VertexInputState(m_vertexInputState));
256 		pipelineCreateInfo_2.addState(PipelineCreateInfo::InputAssemblerState(m_topology));
257 		pipelineCreateInfo_2.addState(PipelineCreateInfo::ColorBlendState(1, &vkCbAttachmentState));
258 		pipelineCreateInfo_2.addState(PipelineCreateInfo::ViewportState(1));
259 		pipelineCreateInfo_2.addState(m_depthStencilState_2);
260 		pipelineCreateInfo_2.addState(PipelineCreateInfo::RasterizerState());
261 		pipelineCreateInfo_2.addState(PipelineCreateInfo::MultiSampleState());
262 		pipelineCreateInfo_2.addState(PipelineCreateInfo::DynamicState());
263 
264 		m_pipeline_1 = vk::createGraphicsPipeline(m_vk, device, DE_NULL, &pipelineCreateInfo_1);
265 		m_pipeline_2 = vk::createGraphicsPipeline(m_vk, device, DE_NULL, &pipelineCreateInfo_2);
266 
267 		std::vector<vk::VkImageView> attachments(2);
268 		attachments[0] = *m_colorTargetView;
269 		attachments[1] = *m_attachmentView;
270 
271 		const FramebufferCreateInfo framebufferCreateInfo(*m_renderPass, attachments, WIDTH, HEIGHT, 1);
272 
273 		m_framebuffer = vk::createFramebuffer(m_vk, device, &framebufferCreateInfo);
274 
275 		const vk::VkDeviceSize dataSize = m_data.size() * sizeof(PositionColorVertex);
276 		m_vertexBuffer = Buffer::createAndAlloc(m_vk, device, BufferCreateInfo(dataSize, vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT),
277 												m_context.getDefaultAllocator(), vk::MemoryRequirement::HostVisible);
278 
279 		deUint8* ptr = reinterpret_cast<unsigned char *>(m_vertexBuffer->getBoundMemory().getHostPtr());
280 		deMemcpy(ptr, &m_data[0], (size_t)dataSize);
281 
282 		vk::flushAlloc(m_vk, device, m_vertexBuffer->getBoundMemory());
283 
284 		const CmdPoolCreateInfo cmdPoolCreateInfo(m_context.getUniversalQueueFamilyIndex());
285 		m_cmdPool = vk::createCommandPool(m_vk, device, &cmdPoolCreateInfo);
286 		m_cmdBuffer = vk::allocateCommandBuffer(m_vk, device, *m_cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
287 	}
288 
iterate(void)289 	virtual tcu::TestStatus iterate (void)
290 	{
291 		DE_ASSERT(false);
292 		return tcu::TestStatus::fail("Implement iterate() method!");
293 	}
294 
beginRenderPass(void)295 	void beginRenderPass (void)
296 	{
297 		const vk::VkClearColorValue clearColor = { { 0.0f, 0.0f, 0.0f, 1.0f } };
298 		beginRenderPassWithClearColor(clearColor);
299 	}
300 
beginRenderPassWithClearColor(const vk::VkClearColorValue & clearColor)301 	void beginRenderPassWithClearColor (const vk::VkClearColorValue &clearColor)
302 	{
303 		beginCommandBuffer(m_vk, *m_cmdBuffer, 0u);
304 
305 		initialTransitionColor2DImage(m_vk, *m_cmdBuffer, m_colorTargetImage->object(), vk::VK_IMAGE_LAYOUT_GENERAL,
306 									  vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT);
307 		initialTransitionDepthStencil2DImage(m_vk, *m_cmdBuffer, m_depthStencilImage->object(), vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
308 											 vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT);
309 
310 		const ImageSubresourceRange subresourceRangeImage(vk::VK_IMAGE_ASPECT_COLOR_BIT);
311 		m_vk.cmdClearColorImage(*m_cmdBuffer, m_colorTargetImage->object(),
312 			vk::VK_IMAGE_LAYOUT_GENERAL, &clearColor, 1, &subresourceRangeImage);
313 
314 		const vk::VkClearDepthStencilValue depthStencilClearValue = { 0.0f, 0 };
315 
316 		const ImageSubresourceRange subresourceRangeDepthStencil[2] = { vk::VK_IMAGE_ASPECT_DEPTH_BIT, vk::VK_IMAGE_ASPECT_STENCIL_BIT };
317 		m_vk.cmdClearDepthStencilImage(*m_cmdBuffer, m_depthStencilImage->object(),
318 			vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &depthStencilClearValue, 2, subresourceRangeDepthStencil);
319 
320 		vk::VkMemoryBarrier memBarrier;
321 		memBarrier.sType = vk::VK_STRUCTURE_TYPE_MEMORY_BARRIER;
322 		memBarrier.pNext = NULL;
323 		memBarrier.srcAccessMask = vk::VK_ACCESS_TRANSFER_WRITE_BIT;
324 		memBarrier.dstAccessMask = vk::VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
325 					   vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
326 
327 		m_vk.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
328 						      vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
329 						      vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
330 						      0, 1, &memBarrier, 0, NULL, 0, NULL);
331 
332 		transition2DImage(m_vk, *m_cmdBuffer, m_depthStencilImage->object(), vk::VK_IMAGE_ASPECT_DEPTH_BIT | vk::VK_IMAGE_ASPECT_STENCIL_BIT,
333 						  vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
334 						  vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
335 						  vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
336 
337 		vk::beginRenderPass(m_vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, vk::makeRect2D(0, 0, WIDTH, HEIGHT));
338 	}
339 
setDynamicViewportState(const deUint32 width,const deUint32 height)340 	void setDynamicViewportState (const deUint32 width, const deUint32 height)
341 	{
342 		vk::VkViewport viewport = vk::makeViewport(tcu::UVec2(width, height));
343 		m_vk.cmdSetViewport(*m_cmdBuffer, 0, 1, &viewport);
344 
345 		vk::VkRect2D scissor = vk::makeRect2D(tcu::UVec2(width, height));
346 		m_vk.cmdSetScissor(*m_cmdBuffer, 0, 1, &scissor);
347 	}
348 
setDynamicViewportState(const deUint32 viewportCount,const vk::VkViewport * pViewports,const vk::VkRect2D * pScissors)349 	void setDynamicViewportState(const deUint32 viewportCount, const vk::VkViewport* pViewports, const vk::VkRect2D* pScissors)
350 	{
351 		m_vk.cmdSetViewport(*m_cmdBuffer, 0, viewportCount, pViewports);
352 		m_vk.cmdSetScissor(*m_cmdBuffer, 0, viewportCount, pScissors);
353 	}
354 
setDynamicRasterizationState(const float lineWidth=1.0f,const float depthBiasConstantFactor=0.0f,const float depthBiasClamp=0.0f,const float depthBiasSlopeFactor=0.0f)355 	void setDynamicRasterizationState(const float lineWidth = 1.0f,
356 							   const float depthBiasConstantFactor = 0.0f,
357 							   const float depthBiasClamp = 0.0f,
358 							   const float depthBiasSlopeFactor = 0.0f)
359 	{
360 		m_vk.cmdSetLineWidth(*m_cmdBuffer, lineWidth);
361 		m_vk.cmdSetDepthBias(*m_cmdBuffer, depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor);
362 	}
363 
setDynamicBlendState(const float const1=0.0f,const float const2=0.0f,const float const3=0.0f,const float const4=0.0f)364 	void setDynamicBlendState(const float const1 = 0.0f, const float const2 = 0.0f,
365 							  const float const3 = 0.0f, const float const4 = 0.0f)
366 	{
367 		float blendConstantsants[4] = { const1, const2, const3, const4 };
368 		m_vk.cmdSetBlendConstants(*m_cmdBuffer, blendConstantsants);
369 	}
370 
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)371 	void setDynamicDepthStencilState(const float minDepthBounds = -1.0f,
372 									 const float maxDepthBounds = 1.0f,
373 									 const deUint32 stencilFrontCompareMask = 0xffffffffu,
374 									 const deUint32 stencilFrontWriteMask = 0xffffffffu,
375 									 const deUint32 stencilFrontReference = 0,
376 									 const deUint32 stencilBackCompareMask = 0xffffffffu,
377 									 const deUint32 stencilBackWriteMask = 0xffffffffu,
378 									 const deUint32 stencilBackReference = 0)
379 	{
380 		m_vk.cmdSetDepthBounds(*m_cmdBuffer, minDepthBounds, maxDepthBounds);
381 		m_vk.cmdSetStencilCompareMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontCompareMask);
382 		m_vk.cmdSetStencilWriteMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontWriteMask);
383 		m_vk.cmdSetStencilReference(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontReference);
384 		m_vk.cmdSetStencilCompareMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackCompareMask);
385 		m_vk.cmdSetStencilWriteMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackWriteMask);
386 		m_vk.cmdSetStencilReference(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackReference);
387 	}
388 };
389 
390 class DepthBoundsParamTestInstance : public DepthStencilBaseCase
391 {
392 public:
DepthBoundsParamTestInstance(Context & context,ShaderMap shaders)393 	DepthBoundsParamTestInstance (Context &context, ShaderMap shaders)
394 		: DepthStencilBaseCase (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
395 	{
396 		// Check if depth bounds test is supported
397 		{
398 			const vk::VkPhysicalDeviceFeatures& deviceFeatures = m_context.getDeviceFeatures();
399 
400 			if (!deviceFeatures.depthBounds)
401 				throw tcu::NotSupportedError("Depth bounds test is unsupported");
402 		}
403 
404 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 0.375f, 1.0f), tcu::RGBA::green().toVec()));
405 		m_data.push_back(PositionColorVertex(tcu::Vec4(0.0f, 1.0f, 0.375f, 1.0f), tcu::RGBA::green().toVec()));
406 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 0.375f, 1.0f), tcu::RGBA::green().toVec()));
407 		m_data.push_back(PositionColorVertex(tcu::Vec4(0.0f, -1.0f, 0.375f, 1.0f), tcu::RGBA::green().toVec()));
408 
409 		m_data.push_back(PositionColorVertex(tcu::Vec4(0.0f, 1.0f, 0.625f, 1.0f), tcu::RGBA::green().toVec()));
410 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 0.625f, 1.0f), tcu::RGBA::green().toVec()));
411 		m_data.push_back(PositionColorVertex(tcu::Vec4(0.0f, -1.0f, 0.625f, 1.0f), tcu::RGBA::green().toVec()));
412 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 0.625f, 1.0f), tcu::RGBA::green().toVec()));
413 
414 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
415 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
416 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
417 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
418 
419 		m_depthStencilState_1 = PipelineCreateInfo::DepthStencilState(
420 			VK_TRUE, VK_TRUE, vk::VK_COMPARE_OP_ALWAYS, VK_FALSE);
421 
422 		// enable depth bounds test
423 		m_depthStencilState_2 = PipelineCreateInfo::DepthStencilState(
424 			VK_FALSE, VK_FALSE, vk::VK_COMPARE_OP_NEVER, VK_TRUE);
425 
426 		DepthStencilBaseCase::initialize();
427 	}
428 
iterate(void)429 	virtual tcu::TestStatus iterate (void)
430 	{
431 		tcu::TestLog&		log		= m_context.getTestContext().getLog();
432 		const vk::VkQueue	queue	= m_context.getUniversalQueue();
433 		const vk::VkDevice	device	= m_context.getDevice();
434 
435 		beginRenderPass();
436 
437 		// set states here
438 		setDynamicViewportState(WIDTH, HEIGHT);
439 		setDynamicRasterizationState();
440 		setDynamicBlendState();
441 		setDynamicDepthStencilState(0.5f, 0.75f);
442 
443 		const vk::VkDeviceSize vertexBufferOffset = 0;
444 		const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
445 		m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
446 
447 		m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline_1);
448 		m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
449 		m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 4, 0);
450 
451 		m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline_2);
452 		m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 8, 0);
453 
454 		endRenderPass(m_vk, *m_cmdBuffer);
455 		endCommandBuffer(m_vk, *m_cmdBuffer);
456 
457 		submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
458 
459 		// validation
460 		{
461 			tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
462 			referenceFrame.allocLevel(0);
463 
464 			const deInt32 frameWidth = referenceFrame.getWidth();
465 			const deInt32 frameHeight = referenceFrame.getHeight();
466 
467 			tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
468 
469 			for (int y = 0; y < frameHeight; y++)
470 			{
471 				const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
472 
473 				for (int x = 0; x < frameWidth; x++)
474 				{
475 					const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
476 
477 					if (xCoord >= 0.0f && xCoord <= 1.0f && yCoord >= -1.0f && yCoord <= 1.0f)
478 						referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
479 					else
480 						referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
481 				}
482 			}
483 
484 			const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
485 			const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
486 				vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
487 
488 			if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
489 				referenceFrame.getLevel(0), renderedFrame, 0.05f,
490 				tcu::COMPARE_LOG_RESULT))
491 			{
492 				return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
493 			}
494 
495 			return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
496 		}
497 	}
498 };
499 
500 class DepthBoundsTestInstance : public DynamicStateBaseClass
501 {
502 public:
503 	enum
504 	{
505 		DEPTH_BOUNDS_MIN	= 0,
506 		DEPTH_BOUNDS_MAX	= 1,
507 		DEPTH_BOUNDS_COUNT	= 2
508 	};
509 	static const float					depthBounds[DEPTH_BOUNDS_COUNT];
510 
511 								DepthBoundsTestInstance		(Context&				context,
512 															 ShaderMap				shaders);
513 	virtual void				initRenderPass				(const vk::VkDevice		device);
514 	virtual void				initFramebuffer				(const vk::VkDevice		device);
515 	virtual void				initPipeline				(const vk::VkDevice		device);
516 	virtual tcu::TestStatus		iterate						(void);
517 private:
518 	const vk::VkFormat			m_depthAttachmentFormat;
519 
520 	de::SharedPtr<Draw::Image>	m_depthImage;
521 	vk::Move<vk::VkImageView>	m_depthView;
522 };
523 
524 const float DepthBoundsTestInstance::depthBounds[DEPTH_BOUNDS_COUNT] =
525 {
526 	0.3f,
527 	0.9f
528 };
529 
DepthBoundsTestInstance(Context & context,ShaderMap shaders)530 DepthBoundsTestInstance::DepthBoundsTestInstance(Context& context, ShaderMap shaders)
531 	: DynamicStateBaseClass		(context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
532 	, m_depthAttachmentFormat	(vk::VK_FORMAT_D16_UNORM)
533 {
534 	// Check depthBounds support
535 	if (!context.getDeviceFeatures().depthBounds)
536 		TCU_THROW(NotSupportedError, "depthBounds feature is not supported");
537 
538 	const vk::VkDevice device = m_context.getDevice();
539 
540 	const vk::VkExtent3D depthImageExtent = { WIDTH, HEIGHT, 1 };
541 	const ImageCreateInfo depthImageCreateInfo(vk::VK_IMAGE_TYPE_2D, m_depthAttachmentFormat, depthImageExtent, 1, 1, vk::VK_SAMPLE_COUNT_1_BIT,
542 												vk::VK_IMAGE_TILING_OPTIMAL, vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
543 
544 	m_depthImage = Image::createAndAlloc(m_vk, device, depthImageCreateInfo, m_context.getDefaultAllocator(), m_context.getUniversalQueueFamilyIndex());
545 
546 	const ImageViewCreateInfo depthViewInfo(m_depthImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, m_depthAttachmentFormat);
547 	m_depthView = vk::createImageView(m_vk, device, &depthViewInfo);
548 
549 	m_topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
550 
551 	m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f,  1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
552 	m_data.push_back(PositionColorVertex(tcu::Vec4( 1.0f,  1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
553 	m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
554 	m_data.push_back(PositionColorVertex(tcu::Vec4( 1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
555 
556 	DynamicStateBaseClass::initialize();
557 }
558 
559 
initRenderPass(const vk::VkDevice device)560 void DepthBoundsTestInstance::initRenderPass (const vk::VkDevice device)
561 {
562 	RenderPassCreateInfo renderPassCreateInfo;
563 	renderPassCreateInfo.addAttachment(AttachmentDescription(m_colorAttachmentFormat,
564 		vk::VK_SAMPLE_COUNT_1_BIT,
565 		vk::VK_ATTACHMENT_LOAD_OP_LOAD,
566 		vk::VK_ATTACHMENT_STORE_OP_STORE,
567 		vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
568 		vk::VK_ATTACHMENT_STORE_OP_STORE,
569 		vk::VK_IMAGE_LAYOUT_GENERAL,
570 		vk::VK_IMAGE_LAYOUT_GENERAL));
571 	renderPassCreateInfo.addAttachment(AttachmentDescription(m_depthAttachmentFormat,
572 		vk::VK_SAMPLE_COUNT_1_BIT,
573 		vk::VK_ATTACHMENT_LOAD_OP_LOAD,
574 		vk::VK_ATTACHMENT_STORE_OP_STORE,
575 		vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
576 		vk::VK_ATTACHMENT_STORE_OP_STORE,
577 		vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
578 		vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL));
579 
580 	const vk::VkAttachmentReference colorAttachmentReference =
581 	{
582 		0,
583 		vk::VK_IMAGE_LAYOUT_GENERAL
584 	};
585 
586 	const vk::VkAttachmentReference depthAttachmentReference =
587 	{
588 		1,
589 		vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
590 	};
591 
592 	renderPassCreateInfo.addSubpass(SubpassDescription(
593 		vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
594 		0,
595 		0,
596 		DE_NULL,
597 		1,
598 		&colorAttachmentReference,
599 		DE_NULL,
600 		depthAttachmentReference,
601 		0,
602 		DE_NULL
603 	)
604 	);
605 
606 	m_renderPass = vk::createRenderPass(m_vk, device, &renderPassCreateInfo);
607 }
608 
initFramebuffer(const vk::VkDevice device)609 void DepthBoundsTestInstance::initFramebuffer (const vk::VkDevice device)
610 {
611 	std::vector<vk::VkImageView> attachments(2);
612 	attachments[0] = *m_colorTargetView;
613 	attachments[1] = *m_depthView;
614 
615 	const FramebufferCreateInfo framebufferCreateInfo(*m_renderPass, attachments, WIDTH, HEIGHT, 1);
616 
617 	m_framebuffer = vk::createFramebuffer(m_vk, device, &framebufferCreateInfo);
618 }
619 
initPipeline(const vk::VkDevice device)620 void DepthBoundsTestInstance::initPipeline (const vk::VkDevice device)
621 {
622 	const vk::Unique<vk::VkShaderModule> vs(createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_vertexShaderName), 0));
623 	const vk::Unique<vk::VkShaderModule> fs(createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_fragmentShaderName), 0));
624 
625 	const PipelineCreateInfo::ColorBlendState::Attachment vkCbAttachmentState;
626 
627 	PipelineCreateInfo pipelineCreateInfo(*m_pipelineLayout, *m_renderPass, 0, 0);
628 	pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", vk::VK_SHADER_STAGE_VERTEX_BIT));
629 	pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, "main", vk::VK_SHADER_STAGE_FRAGMENT_BIT));
630 	pipelineCreateInfo.addState(PipelineCreateInfo::VertexInputState(m_vertexInputState));
631 	pipelineCreateInfo.addState(PipelineCreateInfo::InputAssemblerState(m_topology));
632 	pipelineCreateInfo.addState(PipelineCreateInfo::ColorBlendState(1, &vkCbAttachmentState));
633 	pipelineCreateInfo.addState(PipelineCreateInfo::ViewportState(1));
634 	pipelineCreateInfo.addState(PipelineCreateInfo::DepthStencilState(false, false, vk::VK_COMPARE_OP_NEVER, true));
635 	pipelineCreateInfo.addState(PipelineCreateInfo::RasterizerState());
636 	pipelineCreateInfo.addState(PipelineCreateInfo::MultiSampleState());
637 	pipelineCreateInfo.addState(PipelineCreateInfo::DynamicState());
638 
639 	m_pipeline = vk::createGraphicsPipeline(m_vk, device, DE_NULL, &pipelineCreateInfo);
640 }
641 
642 
iterate(void)643 tcu::TestStatus DepthBoundsTestInstance::iterate (void)
644 {
645 	tcu::TestLog		&log		= m_context.getTestContext().getLog();
646 	const vk::VkQueue	queue		= m_context.getUniversalQueue();
647 	const vk::VkDevice	device		= m_context.getDevice();
648 
649 	// Prepare depth image
650 	tcu::Texture2D depthData(vk::mapVkFormat(m_depthAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
651 	depthData.allocLevel(0);
652 
653 	const deInt32 depthDataWidth	= depthData.getWidth();
654 	const deInt32 depthDataHeight	= depthData.getHeight();
655 
656 	for (int y = 0; y < depthDataHeight; ++y)
657 		for (int x = 0; x < depthDataWidth; ++x)
658 			depthData.getLevel(0).setPixDepth((float)(y * depthDataWidth + x % 11) / 10, x, y);
659 
660 	const vk::VkDeviceSize dataSize = depthData.getLevel(0).getWidth() * depthData.getLevel(0).getHeight()
661 		* tcu::getPixelSize(mapVkFormat(m_depthAttachmentFormat));
662 	de::SharedPtr<Draw::Buffer> stageBuffer = Buffer::createAndAlloc(m_vk, device, BufferCreateInfo(dataSize, vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT),
663 		m_context.getDefaultAllocator(), vk::MemoryRequirement::HostVisible);
664 
665 	deUint8* ptr = reinterpret_cast<unsigned char *>(stageBuffer->getBoundMemory().getHostPtr());
666 	deMemcpy(ptr, depthData.getLevel(0).getDataPtr(), (size_t)dataSize);
667 
668 	vk::flushAlloc(m_vk, device, stageBuffer->getBoundMemory());
669 
670 	beginCommandBuffer(m_vk, *m_cmdBuffer, 0u);
671 
672 	initialTransitionDepth2DImage(m_vk, *m_cmdBuffer, m_depthImage->object(), vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
673 								  vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT);
674 
675 	const vk::VkBufferImageCopy bufferImageCopy =
676 	{
677 		(vk::VkDeviceSize)0,														// VkDeviceSize					bufferOffset;
678 		0u,																			// deUint32						bufferRowLength;
679 		0u,																			// deUint32						bufferImageHeight;
680 		vk::makeImageSubresourceLayers(vk::VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u),	// VkImageSubresourceLayers		imageSubresource;
681 		vk::makeOffset3D(0, 0, 0),													// VkOffset3D					imageOffset;
682 		vk::makeExtent3D(WIDTH, HEIGHT, 1u)											// VkExtent3D					imageExtent;
683 	};
684 	m_vk.cmdCopyBufferToImage(*m_cmdBuffer, stageBuffer->object(), m_depthImage->object(), vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &bufferImageCopy);
685 
686 	transition2DImage(m_vk, *m_cmdBuffer, m_depthImage->object(), vk::VK_IMAGE_ASPECT_DEPTH_BIT, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
687 					  vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
688 					  vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
689 
690 	const vk::VkClearColorValue clearColor = { { 1.0f, 1.0f, 1.0f, 1.0f } };
691 	beginRenderPassWithClearColor(clearColor, true);
692 
693 	// Bind states
694 	setDynamicViewportState(WIDTH, HEIGHT);
695 	setDynamicRasterizationState();
696 	setDynamicBlendState();
697 	setDynamicDepthStencilState(depthBounds[DEPTH_BOUNDS_MIN], depthBounds[DEPTH_BOUNDS_MAX]);
698 
699 	m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
700 
701 	const vk::VkDeviceSize	vertexBufferOffset	= 0;
702 	const vk::VkBuffer		vertexBuffer		= m_vertexBuffer->object();
703 	m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
704 
705 	m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
706 
707 	endRenderPass(m_vk, *m_cmdBuffer);
708 	endCommandBuffer(m_vk, *m_cmdBuffer);
709 
710 	submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
711 
712 	// Validation
713 	{
714 		tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
715 		referenceFrame.allocLevel(0);
716 
717 		const deInt32 frameWidth	= referenceFrame.getWidth();
718 		const deInt32 frameHeight	= referenceFrame.getHeight();
719 
720 		tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
721 
722 		for (int y = 0; y < frameHeight; ++y)
723 			for (int x = 0; x < frameWidth; ++x)
724 				if (depthData.getLevel(0).getPixDepth(x, y) >= depthBounds[DEPTH_BOUNDS_MIN]
725 					&& depthData.getLevel(0).getPixDepth(x, y) <= depthBounds[DEPTH_BOUNDS_MAX])
726 					referenceFrame.getLevel(0).setPixel(tcu::RGBA::green().toVec(), x, y);
727 
728 		const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
729 		const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
730 			vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
731 
732 		if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
733 			referenceFrame.getLevel(0), renderedFrame, 0.05f,
734 			tcu::COMPARE_LOG_RESULT))
735 		{
736 			return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
737 		}
738 
739 		return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
740 	}
741 }
742 
743 class StencilParamsBasicTestInstance : public DepthStencilBaseCase
744 {
745 protected:
746 	deUint32 m_writeMask;
747 	deUint32 m_readMask;
748 	deUint32 m_expectedValue;
749 	tcu::Vec4 m_expectedColor;
750 
751 public:
StencilParamsBasicTestInstance(Context & context,const char * vertexShaderName,const char * fragmentShaderName,const deUint32 writeMask,const deUint32 readMask,const deUint32 expectedValue,const tcu::Vec4 expectedColor)752 	StencilParamsBasicTestInstance (Context& context, const char* vertexShaderName, const char* fragmentShaderName,
753 									const deUint32 writeMask, const deUint32 readMask,
754 									const deUint32 expectedValue, const tcu::Vec4 expectedColor)
755 		: DepthStencilBaseCase  (context, vertexShaderName, fragmentShaderName)
756 		, m_expectedColor		(1.0f, 1.0f, 1.0f, 1.0f)
757 	{
758 		m_writeMask = writeMask;
759 		m_readMask = readMask;
760 		m_expectedValue = expectedValue;
761 		m_expectedColor = expectedColor;
762 
763 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
764 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
765 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
766 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
767 
768 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
769 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
770 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
771 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
772 
773 		const PipelineCreateInfo::DepthStencilState::StencilOpState frontState_1 =
774 			PipelineCreateInfo::DepthStencilState::StencilOpState(
775 			vk::VK_STENCIL_OP_REPLACE,
776 			vk::VK_STENCIL_OP_REPLACE,
777 			vk::VK_STENCIL_OP_REPLACE,
778 			vk::VK_COMPARE_OP_ALWAYS);
779 
780 		const PipelineCreateInfo::DepthStencilState::StencilOpState backState_1 =
781 			PipelineCreateInfo::DepthStencilState::StencilOpState(
782 			vk::VK_STENCIL_OP_REPLACE,
783 			vk::VK_STENCIL_OP_REPLACE,
784 			vk::VK_STENCIL_OP_REPLACE,
785 			vk::VK_COMPARE_OP_ALWAYS);
786 
787 		const PipelineCreateInfo::DepthStencilState::StencilOpState frontState_2 =
788 			PipelineCreateInfo::DepthStencilState::StencilOpState(
789 			vk::VK_STENCIL_OP_REPLACE,
790 			vk::VK_STENCIL_OP_REPLACE,
791 			vk::VK_STENCIL_OP_REPLACE,
792 			vk::VK_COMPARE_OP_EQUAL);
793 
794 		const PipelineCreateInfo::DepthStencilState::StencilOpState backState_2 =
795 			PipelineCreateInfo::DepthStencilState::StencilOpState(
796 			vk::VK_STENCIL_OP_REPLACE,
797 			vk::VK_STENCIL_OP_REPLACE,
798 			vk::VK_STENCIL_OP_REPLACE,
799 			vk::VK_COMPARE_OP_EQUAL);
800 
801 		// enable stencil test
802 		m_depthStencilState_1 = PipelineCreateInfo::DepthStencilState(
803 			VK_FALSE, VK_FALSE, vk::VK_COMPARE_OP_NEVER, VK_FALSE, VK_TRUE, frontState_1, backState_1);
804 
805 		m_depthStencilState_2 = PipelineCreateInfo::DepthStencilState(
806 			VK_FALSE, VK_FALSE, vk::VK_COMPARE_OP_NEVER, VK_FALSE, VK_TRUE, frontState_2, backState_2);
807 
808 		DepthStencilBaseCase::initialize();
809 	}
810 
iterate(void)811 	virtual tcu::TestStatus iterate (void)
812 	{
813 		tcu::TestLog&		log		= m_context.getTestContext().getLog();
814 		const vk::VkQueue	queue	= m_context.getUniversalQueue();
815 		const vk::VkDevice	device	= m_context.getDevice();
816 
817 		beginRenderPass();
818 
819 		// set states here
820 		setDynamicViewportState(WIDTH, HEIGHT);
821 		setDynamicRasterizationState();
822 		setDynamicBlendState();
823 
824 		const vk::VkDeviceSize vertexBufferOffset = 0;
825 		const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
826 		m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
827 
828 		m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline_1);
829 		setDynamicDepthStencilState(-1.0f, 1.0f, 0xFF, m_writeMask, 0x0F, 0xFF, m_writeMask, 0x0F);
830 		m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
831 
832 		m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline_2);
833 		setDynamicDepthStencilState(-1.0f, 1.0f, m_readMask, 0xFF, m_expectedValue, m_readMask, 0xFF, m_expectedValue);
834 		m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 4, 0);
835 
836 		endRenderPass(m_vk, *m_cmdBuffer);
837 		endCommandBuffer(m_vk, *m_cmdBuffer);
838 
839 		submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
840 
841 		// validation
842 		{
843 			tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
844 			referenceFrame.allocLevel(0);
845 
846 			const deInt32 frameWidth = referenceFrame.getWidth();
847 			const deInt32 frameHeight = referenceFrame.getHeight();
848 
849 			for (int y = 0; y < frameHeight; y++)
850 			{
851 				const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
852 
853 				for (int x = 0; x < frameWidth; x++)
854 				{
855 					const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
856 
857 					if (xCoord >= -1.0f && xCoord <= 1.0f && yCoord >= -1.0f && yCoord <= 1.0f)
858 						referenceFrame.getLevel(0).setPixel(m_expectedColor, x, y);
859 				}
860 			}
861 
862 			const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
863 			const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
864 				vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
865 
866 			if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
867 				referenceFrame.getLevel(0), renderedFrame, 0.05f,
868 				tcu::COMPARE_LOG_RESULT))
869 			{
870 				return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
871 			}
872 
873 			return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
874 		}
875 	}
876 };
877 
878 class StencilParamsBasicTestCase : public TestCase
879 {
880 protected:
createInstance(Context & context) const881 	TestInstance* createInstance(Context& context) const
882 	{
883 		return new StencilParamsBasicTestInstance(context, "VertexFetch.vert", "VertexFetch.frag",
884 			m_writeMask, m_readMask, m_expectedValue, m_expectedColor);
885 	}
886 
initPrograms(vk::SourceCollections & programCollection) const887 	virtual void initPrograms(vk::SourceCollections& programCollection) const
888 	{
889 		programCollection.glslSources.add("VertexFetch.vert") <<
890 			glu::VertexSource(ShaderSourceProvider::getSource(m_testCtx.getArchive(), "vulkan/dynamic_state/VertexFetch.vert"));
891 
892 		programCollection.glslSources.add("VertexFetch.frag") <<
893 			glu::FragmentSource(ShaderSourceProvider::getSource(m_testCtx.getArchive(), "vulkan/dynamic_state/VertexFetch.frag"));
894 	}
895 
896 	deUint32 m_writeMask;
897 	deUint32 m_readMask;
898 	deUint32 m_expectedValue;
899 	tcu::Vec4 m_expectedColor;
900 
901 public:
StencilParamsBasicTestCase(tcu::TestContext & context,const char * name,const char * description,const deUint32 writeMask,const deUint32 readMask,const deUint32 expectedValue,const tcu::Vec4 expectedColor)902 	StencilParamsBasicTestCase (tcu::TestContext& context, const char *name, const char *description,
903 								const deUint32 writeMask, const deUint32 readMask,
904 								const deUint32 expectedValue, const tcu::Vec4 expectedColor)
905 		: TestCase				(context, name, description)
906 		, m_writeMask			(writeMask)
907 		, m_readMask			(readMask)
908 		, m_expectedValue		(expectedValue)
909 		, m_expectedColor		(expectedColor)
910 	{
911 	}
912 };
913 
914 class StencilParamsAdvancedTestInstance : public DepthStencilBaseCase
915 {
916 public:
StencilParamsAdvancedTestInstance(Context & context,ShaderMap shaders)917 	StencilParamsAdvancedTestInstance (Context& context, ShaderMap shaders)
918 		: DepthStencilBaseCase (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
919 	{
920 		m_data.push_back(PositionColorVertex(tcu::Vec4(-0.5f, 0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
921 		m_data.push_back(PositionColorVertex(tcu::Vec4(0.5f, 0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
922 		m_data.push_back(PositionColorVertex(tcu::Vec4(-0.5f, -0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
923 		m_data.push_back(PositionColorVertex(tcu::Vec4(0.5f, -0.5f, 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_NOT_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_NOT_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 		const vk::VkDeviceSize vertexBufferOffset = 0;
982 		const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
983 		m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
984 
985 		m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline_1);
986 		setDynamicDepthStencilState(-1.0f, 1.0f, 0xFF, 0x0E, 0x0F, 0xFF, 0x0E, 0x0F);
987 		m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
988 
989 		m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline_2);
990 		setDynamicDepthStencilState(-1.0f, 1.0f, 0xFF, 0xFF, 0x0E, 0xFF, 0xFF, 0x0E);
991 		m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 4, 0);
992 
993 		endRenderPass(m_vk, *m_cmdBuffer);
994 		endCommandBuffer(m_vk, *m_cmdBuffer);
995 
996 		submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
997 
998 		// validation
999 		{
1000 			tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
1001 			referenceFrame.allocLevel(0);
1002 
1003 			const deInt32 frameWidth = referenceFrame.getWidth();
1004 			const deInt32 frameHeight = referenceFrame.getHeight();
1005 
1006 			for (int y = 0; y < frameHeight; y++)
1007 			{
1008 				const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
1009 
1010 				for (int x = 0; x < frameWidth; x++)
1011 				{
1012 					const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
1013 
1014 					if (xCoord >= -0.5f && xCoord <= 0.5f && yCoord >= -0.5f && yCoord <= 0.5f)
1015 						referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
1016 					else
1017 						referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
1018 				}
1019 			}
1020 
1021 			const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
1022 			const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
1023 				vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
1024 
1025 			if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
1026 				referenceFrame.getLevel(0), renderedFrame, 0.05f,
1027 				tcu::COMPARE_LOG_RESULT))
1028 			{
1029 				return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
1030 			}
1031 
1032 			return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
1033 		}
1034 	}
1035 };
1036 
1037 } //anonymous
1038 
DynamicStateDSTests(tcu::TestContext & testCtx)1039 DynamicStateDSTests::DynamicStateDSTests (tcu::TestContext& testCtx)
1040 	: TestCaseGroup (testCtx, "ds_state", "Tests for depth stencil state")
1041 {
1042 	/* Left blank on purpose */
1043 }
1044 
~DynamicStateDSTests()1045 DynamicStateDSTests::~DynamicStateDSTests ()
1046 {
1047 }
1048 
init(void)1049 void DynamicStateDSTests::init (void)
1050 {
1051 	ShaderMap shaderPaths;
1052 	shaderPaths[glu::SHADERTYPE_VERTEX] = "vulkan/dynamic_state/VertexFetch.vert";
1053 	shaderPaths[glu::SHADERTYPE_FRAGMENT] = "vulkan/dynamic_state/VertexFetch.frag";
1054 
1055 	addChild(new InstanceFactory<DepthBoundsParamTestInstance>(m_testCtx, "depth_bounds_1", "Perform depth bounds test 1", shaderPaths));
1056 	addChild(new InstanceFactory<DepthBoundsTestInstance>(m_testCtx, "depth_bounds_2", "Perform depth bounds test 1", shaderPaths));
1057 	addChild(new StencilParamsBasicTestCase(m_testCtx, "stencil_params_basic_1", "Perform basic stencil test 1", 0x0D, 0x06, 0x05, tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f)));
1058 	addChild(new StencilParamsBasicTestCase(m_testCtx, "stencil_params_basic_2", "Perform basic stencil test 2", 0x06, 0x02, 0x05, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f)));
1059 	addChild(new InstanceFactory<StencilParamsAdvancedTestInstance>(m_testCtx, "stencil_params_advanced", "Perform advanced stencil test", shaderPaths));
1060 }
1061 
1062 } // DynamicState
1063 } // vkt
1064