• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2022 LunarG, Inc.
6  * Copyright (c) 2022 The Khronos Group Inc.
7  * Copyright (c) 2022 Google LLC
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Dynamic State Clear Tests
24  *//*--------------------------------------------------------------------*/
25 
26 #include "vktDynamicStateClearTests.hpp"
27 
28 #include "vktDynamicStateBaseClass.hpp"
29 #include "vktDynamicStateTestCaseUtil.hpp"
30 
31 #include "vkImageUtil.hpp"
32 #include "vkCmdUtil.hpp"
33 
34 #include "tcuImageCompare.hpp"
35 #include "tcuTextureUtil.hpp"
36 #include "tcuRGBA.hpp"
37 #include "vkQueryUtil.hpp"
38 
39 
40 namespace vkt
41 {
42 namespace DynamicState
43 {
44 
45 using namespace Draw;
46 
47 namespace
48 {
49 
50 class CmdBaseCase : public DynamicStateBaseClass
51 {
52 public:
CmdBaseCase(Context & context,vk::PipelineConstructionType pipelineConstructionType,const char * vertexShaderName,const char * fragmentShaderName)53 	CmdBaseCase (Context& context, vk::PipelineConstructionType pipelineConstructionType, const char* vertexShaderName, const char* fragmentShaderName)
54 		: DynamicStateBaseClass	(context, pipelineConstructionType, vertexShaderName, fragmentShaderName)
55 	{
56 		m_topology = vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
57 
58 		m_data.push_back(PositionColorVertex(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
59 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
60 
61 		m_attachmentState.blendEnable = VK_TRUE;
62 		m_attachmentState.srcColorBlendFactor = vk::VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR;
63 		m_attachmentState.dstColorBlendFactor = vk::VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR;
64 		m_attachmentState.colorBlendOp = vk::VK_BLEND_OP_ADD;
65 		m_attachmentState.srcAlphaBlendFactor = vk::VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA;
66 		m_attachmentState.dstAlphaBlendFactor = vk::VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA;
67 		m_attachmentState.alphaBlendOp = vk::VK_BLEND_OP_ADD;
68 	}
69 
buildReferenceFrame(int lineWidth)70 	virtual tcu::Texture2D buildReferenceFrame (int lineWidth)
71 	{
72 		(void)lineWidth;
73 		DE_ASSERT(false);
74 		return tcu::Texture2D(tcu::TextureFormat(), 0, 0);
75 	}
76 
command(bool)77 	virtual void command (bool)
78 	{
79 		DE_ASSERT(false);
80 	}
81 
iterate(void)82 	virtual tcu::TestStatus iterate (void)
83 	{
84 		tcu::TestLog&					log					= m_context.getTestContext().getLog();
85 		const vk::InstanceInterface&	vkInstance			= m_context.getInstanceInterface();
86 		const vk::VkPhysicalDevice		vkPhysicalDevice	= m_context.getPhysicalDevice();
87 		const vk::VkQueue				queue				= m_context.getUniversalQueue();
88 		const vk::VkDevice				device				= m_context.getDevice();
89 
90 		const float						lineWidth			= getPhysicalDeviceProperties(vkInstance, vkPhysicalDevice).limits.lineWidthRange[1];
91 
92 		vk::beginCommandBuffer(m_vk, *m_cmdBuffer, 0u);
93 
94 		// set dynamic states
95 		const vk::VkViewport			viewport	= { 0.0f, 0.0f, static_cast<float>(WIDTH / 2), static_cast<float>(HEIGHT / 2), 0.0f, 0.0f };
96 		const vk::VkRect2D				scissor		= { { 0, 0 }, { WIDTH, HEIGHT } };
97 
98 		setDynamicViewportState(1, &viewport, &scissor);
99 		setDynamicRasterizationState(lineWidth);
100 		setDynamicBlendState(0.75f, 0.75f, 0.75f, 0.75f);
101 		setDynamicDepthStencilState(0.0f, 1.0f);
102 
103 		const vk::VkExtent3D			imageExtent		= { WIDTH, HEIGHT, 1 };
104 
105 		vk::VkImageFormatProperties		imageFormatProperties(getPhysicalDeviceImageFormatProperties(vkInstance, vkPhysicalDevice, m_colorAttachmentFormat, vk::VK_IMAGE_TYPE_2D, vk::VK_IMAGE_TILING_OPTIMAL, vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0));
106 		if ((imageFormatProperties.sampleCounts & m_samples) == 0)
107 			TCU_THROW(NotSupportedError, "Color image type not supported");
108 
109 		const ImageCreateInfo			imageCreateInfo	  (vk::VK_IMAGE_TYPE_2D, m_colorAttachmentFormat, imageExtent, 1, 1, m_samples, vk::VK_IMAGE_TILING_OPTIMAL, vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
110 		m_image = Image::createAndAlloc(m_vk, device, imageCreateInfo, m_context.getDefaultAllocator(), m_context.getUniversalQueueFamilyIndex());
111 
112 		transition2DImage(m_vk, *m_cmdBuffer, m_colorTargetImage->object(), vk::VK_IMAGE_ASPECT_COLOR_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, vk::VK_IMAGE_LAYOUT_GENERAL, 0u, vk::VK_ACCESS_TRANSFER_READ_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT);
113 		transition2DImage(m_vk, *m_cmdBuffer, m_image->object(), vk::VK_IMAGE_ASPECT_COLOR_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, vk::VK_IMAGE_LAYOUT_GENERAL, 0u, vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT);
114 
115 		// should not interfere with dynamic state
116 		command(false);
117 
118 		const vk::VkClearColorValue clearColor = { { 0.0f, 0.0f, 0.0f, 1.0f } };
119 		beginRenderPassWithClearColor(clearColor, true);
120 
121 		command(true);
122 
123 		m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline.getPipeline());
124 
125 		const vk::VkDeviceSize vertexBufferOffset	= 0;
126 		const vk::VkBuffer		vertexBuffer		= m_vertexBuffer->object();
127 		m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
128 
129 		m_vk.cmdDraw(*m_cmdBuffer, 2, 1, 0, 0);
130 
131 		endRenderPass(m_vk, *m_cmdBuffer);
132 		endCommandBuffer(m_vk, *m_cmdBuffer);
133 
134 		submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
135 
136 		// validation
137 		{
138 			tcu::Texture2D referenceFrame = buildReferenceFrame(static_cast<int>(lineWidth));
139 
140 			const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
141 			const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
142 				vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
143 
144 			if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
145 				referenceFrame.getLevel(0), renderedFrame, 0.05f,
146 				tcu::COMPARE_LOG_RESULT))
147 			{
148 				return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
149 			}
150 
151 			return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
152 		}
153 	}
154 
155 	de::SharedPtr<Draw::Image> m_image;
156 	vk::VkSampleCountFlagBits m_samples = vk::VK_SAMPLE_COUNT_1_BIT;
157 };
158 
159 class ClearTestInstance : public CmdBaseCase
160 {
161 public:
ClearTestInstance(Context & context,vk::PipelineConstructionType pipelineConstructionType,ShaderMap shaders)162 	ClearTestInstance (Context& context, vk::PipelineConstructionType pipelineConstructionType, ShaderMap shaders)
163 		: CmdBaseCase	(context, pipelineConstructionType, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
164 	{
165 		DynamicStateBaseClass::initialize();
166 	}
167 
command(bool renderPassActive)168 	virtual void command (bool renderPassActive)
169 	{
170 		if (renderPassActive) {
171 			// Clear attachment
172 			vk::VkClearValue clearValue;
173 			clearValue.color.float32[0] = 1.0f;
174 			clearValue.color.float32[1] = 1.0f;
175 			clearValue.color.float32[2] = 1.0f;
176 			clearValue.color.float32[3] = 1.0f;
177 			const vk::VkClearAttachment clearAttachment =
178 			{
179 				vk::VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask
180 				0u,									// uint32_t				colorAttachment
181 				clearValue						// VkClearValue			clearValue
182 			};
183 			const vk::VkClearRect rect = { { { 0, 0 }, { WIDTH, HEIGHT } }, 0, 1 };
184 			m_vk.cmdClearAttachments(*m_cmdBuffer, 1, &clearAttachment, 1, &rect);
185 		}
186 	}
187 
buildReferenceFrame(int lineWidth)188 	virtual tcu::Texture2D buildReferenceFrame (int lineWidth)
189 	{
190 		tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), WIDTH, HEIGHT);
191 		referenceFrame.allocLevel(0);
192 
193 		const deInt32 frameWidth	= referenceFrame.getWidth();
194 		const deInt32 frameHeight	= referenceFrame.getHeight();
195 
196 		tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
197 
198 		for (int y = 0; y < frameHeight; y++)
199 		{
200 			for (int x = 0; x < frameWidth; x++)
201 			{
202 				if (y < frameHeight / 2 && y >= 32 - lineWidth / 2 && y < 32 + lineWidth / 2 && x >= frameWidth / 4 && x < frameWidth / 2)
203 					referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.25f, 0.5f, 0.25f, 0.5f), x, y);
204 				else
205 					referenceFrame.getLevel(0).setPixel(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), x, y);
206 			}
207 		}
208 
209 		return referenceFrame;
210 	}
211 };
212 
213 class BlitTestInstance : public CmdBaseCase
214 {
215 public:
BlitTestInstance(Context & context,vk::PipelineConstructionType pipelineConstructionType,ShaderMap shaders)216 	BlitTestInstance (Context& context, vk::PipelineConstructionType pipelineConstructionType, ShaderMap shaders)
217 		: CmdBaseCase	(context, pipelineConstructionType, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
218 	{
219 		DynamicStateBaseClass::initialize();
220 	}
221 
command(bool renderPassActive)222 	virtual void command (bool renderPassActive)
223 	{
224 		if (!renderPassActive) {
225 			const vk::VkImageBlit		blitRegion =
226 			{
227 				// Src
228 				{
229 					vk::VK_IMAGE_ASPECT_COLOR_BIT,
230 					0,	// mipLevel
231 					0,	// arrayLayer
232 					1	// layerCount
233 				},
234 				{
235 					{ 0, 0, 0 },
236 					{
237 						WIDTH,
238 						HEIGHT,
239 						1
240 					},
241 				},
242 
243 				// Dst
244 				{
245 					vk::VK_IMAGE_ASPECT_COLOR_BIT,
246 					0,	// mipLevel
247 					0,	// arrayLayer
248 					1	// layerCount
249 				},
250 				{
251 					{ 0, 0, 0 },
252 					{
253 						WIDTH,
254 						HEIGHT,
255 						1u
256 					}
257 				}
258 			};
259 			m_vk.cmdBlitImage(*m_cmdBuffer, m_colorTargetImage->object(), vk::VK_IMAGE_LAYOUT_GENERAL, m_image->object(), vk::VK_IMAGE_LAYOUT_GENERAL, 1, &blitRegion, vk::VK_FILTER_NEAREST);
260 		}
261 	}
262 
buildReferenceFrame(int lineWidth)263 	virtual tcu::Texture2D buildReferenceFrame (int lineWidth)
264 	{
265 		tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), WIDTH, HEIGHT);
266 		referenceFrame.allocLevel(0);
267 
268 		const deInt32 frameWidth	= referenceFrame.getWidth();
269 		const deInt32 frameHeight	= referenceFrame.getHeight();
270 
271 		tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
272 
273 		for (int y = 0; y < frameHeight; y++)
274 		{
275 			for (int x = 0; x < frameWidth; x++)
276 			{
277 				if (y < frameHeight / 2 && y >= 32 - lineWidth / 2 && y < 32 + lineWidth / 2 && x >= frameWidth / 4 && x < frameWidth / 2)
278 					referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.25f, 0.0f, 0.5f), x, y);
279 			}
280 		}
281 
282 		return referenceFrame;
283 	}
284 };
285 
286 class CopyTestInstance : public CmdBaseCase
287 {
288 public:
CopyTestInstance(Context & context,vk::PipelineConstructionType pipelineConstructionType,ShaderMap shaders)289 	CopyTestInstance	(Context& context, vk::PipelineConstructionType pipelineConstructionType, ShaderMap shaders)
290 		: CmdBaseCase (context, pipelineConstructionType, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
291 	{
292 		DynamicStateBaseClass::initialize();
293 	}
294 
command(bool renderPassActive)295 	virtual void command (bool renderPassActive)
296 	{
297 		if (!renderPassActive) {
298 			const vk::VkImageSubresourceLayers imgSubResLayers =
299 			{
300 				vk::VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags  aspectMask;
301 				0u,								// deUint32            mipLevel;
302 				0u,								// deUint32            baseArrayLayer;
303 				1u,								// deUint32            layerCount;
304 			};
305 			const vk::VkOffset3D offset = { 0, 0, 0 };
306 			const vk::VkExtent3D extent = { WIDTH, HEIGHT, 1 };
307 
308 			const vk::VkImageCopy copyRegion =
309 			{
310 				imgSubResLayers,	// VkImageSubresourceCopy  srcSubresource;
311 				offset,				// VkOffset3D              srcOffset;
312 				imgSubResLayers,	// VkImageSubresourceCopy  destSubresource;
313 				offset,				// VkOffset3D              destOffset;
314 				extent,				// VkExtent3D              extent;
315 			};
316 
317 			m_vk.cmdCopyImage(*m_cmdBuffer, m_colorTargetImage->object(), vk::VK_IMAGE_LAYOUT_GENERAL, m_image->object(), vk::VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
318 		}
319 	}
320 
buildReferenceFrame(int lineWidth)321 	virtual tcu::Texture2D buildReferenceFrame (int lineWidth)
322 	{
323 		tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), WIDTH, HEIGHT);
324 		referenceFrame.allocLevel(0);
325 
326 		const deInt32 frameWidth	= referenceFrame.getWidth();
327 		const deInt32 frameHeight	= referenceFrame.getHeight();
328 
329 		tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
330 
331 		for (int y = 0; y < frameHeight; y++)
332 		{
333 			for (int x = 0; x < frameWidth; x++)
334 			{
335 				if (y < frameHeight / 2 && y >= 32 - lineWidth / 2 && y < 32 + lineWidth / 2 && x >= frameWidth / 4 && x < frameWidth / 2)
336 					referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.25f, 0.0f, 0.5f), x, y);
337 			}
338 		}
339 
340 		return referenceFrame;
341 	}
342 };
343 
344 class ResolveTestInstance : public CmdBaseCase
345 {
346 public:
ResolveTestInstance(Context & context,vk::PipelineConstructionType pipelineConstructionType,ShaderMap shaders)347 	ResolveTestInstance (Context& context, vk::PipelineConstructionType pipelineConstructionType, ShaderMap shaders)
348 		: CmdBaseCase	(context, pipelineConstructionType, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
349 	{
350 		DynamicStateBaseClass::initialize();
351 
352 		m_samples = vk::VK_SAMPLE_COUNT_2_BIT;
353 	}
354 
command(bool renderPassActive)355 	virtual void command (bool renderPassActive)
356 	{
357 		if (!renderPassActive) {
358 			const vk::VkImageSubresourceLayers imgSubResLayers =
359 			{
360 				vk::VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags  aspectMask;
361 				0u,								// deUint32            mipLevel;
362 				0u,								// deUint32            baseArrayLayer;
363 				1u,								// deUint32            layerCount;
364 			};
365 			const vk::VkOffset3D offset = { 0, 0, 0 };
366 			const vk::VkExtent3D extent = { WIDTH, HEIGHT, 1 };
367 
368 			const vk::VkImageResolve			resolveRegion =
369 			{
370 				imgSubResLayers,	// VkImageSubresourceLayers	srcSubresource;
371 				offset,				// VkOffset3D				srcOffset;
372 				imgSubResLayers,	// VkImageSubresourceLayers	dstSubresource;
373 				offset,				// VkOffset3D				dstOffset;
374 				extent,				// VkExtent3D				extent;
375 			};
376 			m_vk.cmdResolveImage(*m_cmdBuffer, m_image->object(), vk::VK_IMAGE_LAYOUT_GENERAL, m_colorTargetImage->object(), vk::VK_IMAGE_LAYOUT_GENERAL, 1, &resolveRegion);
377 		}
378 	}
379 
buildReferenceFrame(int lineWidth)380 	virtual tcu::Texture2D buildReferenceFrame (int lineWidth)
381 	{
382 		tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), WIDTH, HEIGHT);
383 		referenceFrame.allocLevel(0);
384 
385 		const deInt32 frameWidth	= referenceFrame.getWidth();
386 		const deInt32 frameHeight	= referenceFrame.getHeight();
387 
388 		tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
389 
390 		for (int y = 0; y < frameHeight; y++)
391 		{
392 			for (int x = 0; x < frameWidth; x++)
393 			{
394 				if (y < frameHeight / 2 && y >= 32 - lineWidth / 2 && y < 32 + lineWidth / 2 && x >= frameWidth / 4 && x < frameWidth / 2)
395 					referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.25f, 0.0f, 0.5f), x, y);
396 			}
397 		}
398 
399 		return referenceFrame;
400 	}
401 };
402 
403 } //anonymous
404 
DynamicStateClearTests(tcu::TestContext & testCtx,vk::PipelineConstructionType pipelineConstructionType)405 DynamicStateClearTests::DynamicStateClearTests (tcu::TestContext& testCtx, vk::PipelineConstructionType pipelineConstructionType)
406 	: TestCaseGroup					(testCtx, "image", "Tests for dynamic state")
407 	, m_pipelineConstructionType	(pipelineConstructionType)
408 {
409 	/* Left blank on purpose */
410 }
411 
~DynamicStateClearTests()412 DynamicStateClearTests::~DynamicStateClearTests()
413 {
414 }
415 
init(void)416 void DynamicStateClearTests::init (void)
417 {
418 	ShaderMap shaderPaths;
419 	shaderPaths[glu::SHADERTYPE_VERTEX] = "vulkan/dynamic_state/VertexFetch.vert";
420 	shaderPaths[glu::SHADERTYPE_FRAGMENT] = "vulkan/dynamic_state/VertexFetch.frag";
421 
422 	addChild(new InstanceFactory<ClearTestInstance>(m_testCtx, "clear", "Clear attachment after setting dynamic states", m_pipelineConstructionType, shaderPaths));
423 	addChild(new InstanceFactory<BlitTestInstance>(m_testCtx, "blit", "Blit image after setting dynamic states", m_pipelineConstructionType, shaderPaths));
424 	addChild(new InstanceFactory<CopyTestInstance>(m_testCtx, "copy", "Copy image after setting dynamic states", m_pipelineConstructionType, shaderPaths));
425 	addChild(new InstanceFactory<ResolveTestInstance>(m_testCtx, "resolve", "Resolve image after setting dynamic states", m_pipelineConstructionType, shaderPaths));
426 }
427 
428 } // DynamicState
429 } // vkt
430