• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 The Khronos Group Inc.
6  * Copyright (c) 2015 Intel Corporation
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file
22  * \brief Dynamic State Tests - Base Class
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktDynamicStateBaseClass.hpp"
26 
27 #include "vkPrograms.hpp"
28 #include "vkTypeUtil.hpp"
29 #include "vkCmdUtil.hpp"
30 #include "vkObjUtil.hpp"
31 #include "vkBuilderUtil.hpp"
32 
33 namespace vkt
34 {
35 namespace DynamicState
36 {
37 
38 using namespace Draw;
39 
DynamicStateBaseClass(Context & context,vk::PipelineConstructionType pipelineConstructionType,const char * vertexShaderName,const char * fragmentShaderName,const char * meshShaderName)40 DynamicStateBaseClass::DynamicStateBaseClass (Context& context,
41 											  vk::PipelineConstructionType pipelineConstructionType,
42 											  const char* vertexShaderName,
43 											  const char* fragmentShaderName,
44 											  const char* meshShaderName)
45 	: TestInstance				(context)
46 	, m_colorAttachmentFormat	(vk::VK_FORMAT_R8G8B8A8_UNORM)
47 	, m_topology				(vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
48 	, m_vk						(context.getDeviceInterface())
49 	, m_pipeline				(context.getDeviceInterface(), context.getDevice(), pipelineConstructionType)
50 	, m_vertexShaderName		(vertexShaderName ? vertexShaderName : "")
51 	, m_fragmentShaderName		(fragmentShaderName)
52 	, m_meshShaderName			(meshShaderName ? meshShaderName : "")
53 	, m_isMesh					(meshShaderName != nullptr)
54 {
55 	// We must provide either the mesh shader or the vertex shader.
56 	DE_ASSERT(static_cast<bool>(vertexShaderName) != static_cast<bool>(meshShaderName));
57 }
58 
initialize(void)59 void DynamicStateBaseClass::initialize (void)
60 {
61 	const vk::VkDevice						device				= m_context.getDevice();
62 	const deUint32							queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
63 	const auto								vertDescType		= (m_isMesh ? vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER : vk::VK_DESCRIPTOR_TYPE_MAX_ENUM);
64 	std::vector<vk::VkPushConstantRange>	pcRanges;
65 
66 	// The mesh shading pipeline will contain a set with vertex data.
67 #ifndef CTS_USES_VULKANSC
68 	if (m_isMesh)
69 	{
70 		vk::DescriptorSetLayoutBuilder	setLayoutBuilder;
71 		vk::DescriptorPoolBuilder		poolBuilder;
72 
73 		setLayoutBuilder.addSingleBinding(vertDescType, vk::VK_SHADER_STAGE_MESH_BIT_EXT);
74 		m_meshSetLayout = setLayoutBuilder.build(m_vk, device);
75 
76 		poolBuilder.addType(vertDescType);
77 		m_descriptorPool = poolBuilder.build(m_vk, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
78 
79 		m_descriptorSet = vk::makeDescriptorSet(m_vk, device, m_descriptorPool.get(), m_meshSetLayout.get());
80 		pcRanges.push_back(vk::makePushConstantRange(vk::VK_SHADER_STAGE_MESH_BIT_EXT, 0u, static_cast<uint32_t>(sizeof(uint32_t))));
81 	}
82 #endif // CTS_USES_VULKANSC
83 
84 	std::vector<vk::VkDescriptorSetLayout> rawSetLayouts;
85 
86 	if (m_meshSetLayout)
87 		rawSetLayouts.push_back(m_meshSetLayout.get());
88 
89 	if (m_otherSetLayout)
90 		rawSetLayouts.push_back(m_otherSetLayout.get());
91 
92 	m_pipelineLayout = vk::makePipelineLayout(m_vk, device, de::sizeU32(rawSetLayouts), de::dataOrNull(rawSetLayouts), de::sizeU32(pcRanges), de::dataOrNull(pcRanges));
93 
94 	const vk::VkExtent3D targetImageExtent = { WIDTH, HEIGHT, 1 };
95 	const ImageCreateInfo targetImageCreateInfo(vk::VK_IMAGE_TYPE_2D, m_colorAttachmentFormat, targetImageExtent, 1, 1, vk::VK_SAMPLE_COUNT_1_BIT,
96 												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);
97 
98 	m_colorTargetImage = Image::createAndAlloc(m_vk, device, targetImageCreateInfo, m_context.getDefaultAllocator(), m_context.getUniversalQueueFamilyIndex());
99 
100 	const ImageViewCreateInfo colorTargetViewInfo(m_colorTargetImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, m_colorAttachmentFormat);
101 	m_colorTargetView = vk::createImageView(m_vk, device, &colorTargetViewInfo);
102 
103 	const vk::VkVertexInputBindingDescription vertexInputBindingDescription =
104 	{
105 		0,
106 		(deUint32)sizeof(tcu::Vec4) * 2,
107 		vk::VK_VERTEX_INPUT_RATE_VERTEX,
108 	};
109 
110 	const vk::VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
111 	{
112 		{
113 			0u,
114 			0u,
115 			vk::VK_FORMAT_R32G32B32A32_SFLOAT,
116 			0u
117 		},
118 		{
119 			1u,
120 			0u,
121 			vk::VK_FORMAT_R32G32B32A32_SFLOAT,
122 			(deUint32)(sizeof(float)* 4),
123 		}
124 	};
125 
126 	m_vertexInputState = PipelineCreateInfo::VertexInputState(
127 		1,
128 		&vertexInputBindingDescription,
129 		2,
130 		vertexInputAttributeDescriptions);
131 
132 	const vk::VkDeviceSize			dataSize	= de::dataSize(m_data);
133 	const vk::VkBufferUsageFlags	bufferUsage	= (m_isMesh ? vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT : vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
134 	m_vertexBuffer = Buffer::createAndAlloc(m_vk, device, BufferCreateInfo(dataSize, bufferUsage),
135 											m_context.getDefaultAllocator(), vk::MemoryRequirement::HostVisible);
136 
137 	deUint8* ptr = reinterpret_cast<unsigned char *>(m_vertexBuffer->getBoundMemory().getHostPtr());
138 	deMemcpy(ptr, &m_data[0], (size_t)dataSize);
139 
140 	vk::flushAlloc(m_vk, device, m_vertexBuffer->getBoundMemory());
141 
142 	// Update descriptor set for mesh shaders.
143 	if (m_isMesh)
144 	{
145 		vk::DescriptorSetUpdateBuilder	updateBuilder;
146 		const auto						location		= vk::DescriptorSetUpdateBuilder::Location::binding(0u);
147 		const auto						bufferInfo		= vk::makeDescriptorBufferInfo(m_vertexBuffer->object(), 0ull, dataSize);
148 
149 		updateBuilder.writeSingle(m_descriptorSet.get(), location, vertDescType, &bufferInfo);
150 		updateBuilder.update(m_vk, device);
151 	}
152 
153 	const CmdPoolCreateInfo cmdPoolCreateInfo(queueFamilyIndex);
154 	m_cmdPool = vk::createCommandPool(m_vk, device, &cmdPoolCreateInfo);
155 
156 	const vk::VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
157 	{
158 		vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,	// VkStructureType			sType;
159 		DE_NULL,											// const void*				pNext;
160 		*m_cmdPool,											// VkCommandPool			commandPool;
161 		vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY,				// VkCommandBufferLevel		level;
162 		1u,													// deUint32					bufferCount;
163 	};
164 	m_cmdBuffer = vk::allocateCommandBuffer(m_vk, device, &cmdBufferAllocateInfo);
165 
166 	initRenderPass(device);
167 	initFramebuffer(device);
168 	initPipeline(device);
169 }
170 
171 
initRenderPass(const vk::VkDevice device)172 void DynamicStateBaseClass::initRenderPass (const vk::VkDevice device)
173 {
174 	RenderPassCreateInfo renderPassCreateInfo;
175 	renderPassCreateInfo.addAttachment(AttachmentDescription(m_colorAttachmentFormat,
176 		vk::VK_SAMPLE_COUNT_1_BIT,
177 		vk::VK_ATTACHMENT_LOAD_OP_LOAD,
178 		vk::VK_ATTACHMENT_STORE_OP_STORE,
179 		vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
180 		vk::VK_ATTACHMENT_STORE_OP_STORE,
181 		vk::VK_IMAGE_LAYOUT_GENERAL,
182 		vk::VK_IMAGE_LAYOUT_GENERAL));
183 
184 	const vk::VkAttachmentReference colorAttachmentReference =
185 	{
186 		0,
187 		vk::VK_IMAGE_LAYOUT_GENERAL
188 	};
189 
190 	renderPassCreateInfo.addSubpass(SubpassDescription(
191 		vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
192 		0,
193 		0,
194 		DE_NULL,
195 		1,
196 		&colorAttachmentReference,
197 		DE_NULL,
198 		AttachmentReference(),
199 		0,
200 		DE_NULL
201 	)
202 	);
203 
204 	m_renderPass = vk::createRenderPass(m_vk, device, &renderPassCreateInfo);
205 }
206 
initFramebuffer(const vk::VkDevice device)207 void DynamicStateBaseClass::initFramebuffer (const vk::VkDevice device)
208 {
209 	std::vector<vk::VkImageView> colorAttachments(1);
210 	colorAttachments[0] = *m_colorTargetView;
211 
212 	const FramebufferCreateInfo framebufferCreateInfo(*m_renderPass, colorAttachments, WIDTH, HEIGHT, 1);
213 
214 	m_framebuffer = vk::createFramebuffer(m_vk, device, &framebufferCreateInfo);
215 }
216 
initPipeline(const vk::VkDevice device)217 void DynamicStateBaseClass::initPipeline (const vk::VkDevice device)
218 {
219 	const PipelineCreateInfo::ColorBlendState				colorBlendState(1, &m_attachmentState);
220 	const PipelineCreateInfo::RasterizerState				rasterizerState;
221 	const PipelineCreateInfo::DepthStencilState             depthStencilState;
222 	const PipelineCreateInfo::DynamicState					dynamicState;
223 	const PipelineCreateInfo::MultiSampleState				multisampleState;
224 
225 	const auto&							binaries	= m_context.getBinaryCollection();
226 	const vk::Move<vk::VkShaderModule>	ms			(m_isMesh ? createShaderModule(m_vk, device, binaries.get(m_meshShaderName), 0) : vk::Move<vk::VkShaderModule>());
227 	const vk::Move<vk::VkShaderModule>	vs			(m_isMesh ? vk::Move<vk::VkShaderModule>() : createShaderModule(m_vk, device, binaries.get(m_vertexShaderName), 0));
228 	const vk::Move<vk::VkShaderModule>	fs			(createShaderModule(m_vk, device, binaries.get(m_fragmentShaderName), 0));
229 	std::vector<vk::VkViewport>			viewports	{ { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } };
230 	std::vector<vk::VkRect2D>			scissors	{ { { 0u, 0u }, { 0u, 0u } }};
231 
232 	m_pipeline.setDefaultTopology(m_topology)
233 			  .setDynamicState(static_cast<const vk::VkPipelineDynamicStateCreateInfo*>(&dynamicState));
234 
235 #ifndef CTS_USES_VULKANSC
236 	if (m_isMesh)
237 	{
238 		m_pipeline
239 			  .setupPreRasterizationMeshShaderState(viewports,
240 													scissors,
241 													*m_pipelineLayout,
242 													*m_renderPass,
243 													0u,
244 													DE_NULL,
245 													*ms,
246 													static_cast<const vk::VkPipelineRasterizationStateCreateInfo*>(&rasterizerState));
247 	}
248 	else
249 #endif // CTS_USES_VULKANSC
250 	{
251 		m_pipeline
252 			  .setupVertexInputState(&m_vertexInputState)
253 			  .setupPreRasterizationShaderState(viewports,
254 												scissors,
255 												*m_pipelineLayout,
256 												*m_renderPass,
257 												0u,
258 												*vs,
259 												static_cast<const vk::VkPipelineRasterizationStateCreateInfo*>(&rasterizerState));
260 	}
261 
262 	m_pipeline.setupFragmentShaderState(*m_pipelineLayout, *m_renderPass, 0u, *fs, static_cast<const vk::VkPipelineDepthStencilStateCreateInfo*>(&depthStencilState), &multisampleState)
263 			  .setupFragmentOutputState(*m_renderPass, 0u, static_cast<const vk::VkPipelineColorBlendStateCreateInfo*>(&colorBlendState), &multisampleState)
264 			  .setMonolithicPipelineLayout(*m_pipelineLayout)
265 			  .buildPipeline();
266 }
267 
iterate(void)268 tcu::TestStatus DynamicStateBaseClass::iterate (void)
269 {
270 	DE_ASSERT(false);
271 	return tcu::TestStatus::fail("Implement iterate() method!");
272 }
273 
beginRenderPass(void)274 void DynamicStateBaseClass::beginRenderPass (void)
275 {
276 	const vk::VkClearColorValue clearColor = { { 0.0f, 0.0f, 0.0f, 1.0f } };
277 	beginRenderPassWithClearColor(clearColor);
278 }
279 
beginRenderPassWithClearColor(const vk::VkClearColorValue & clearColor,const bool skipBeginCmdBuffer)280 void DynamicStateBaseClass::beginRenderPassWithClearColor(const vk::VkClearColorValue& clearColor, const bool skipBeginCmdBuffer)
281 {
282 	if (!skipBeginCmdBuffer)
283 	{
284 		beginCommandBuffer(m_vk, *m_cmdBuffer, 0u);
285 	}
286 
287 	initialTransitionColor2DImage(m_vk, *m_cmdBuffer, m_colorTargetImage->object(), vk::VK_IMAGE_LAYOUT_GENERAL,
288 								  vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT);
289 
290 	const ImageSubresourceRange subresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT);
291 	m_vk.cmdClearColorImage(*m_cmdBuffer, m_colorTargetImage->object(),
292 		vk::VK_IMAGE_LAYOUT_GENERAL, &clearColor, 1, &subresourceRange);
293 
294 	const vk::VkMemoryBarrier memBarrier =
295 	{
296 		vk::VK_STRUCTURE_TYPE_MEMORY_BARRIER,
297 		DE_NULL,
298 		vk::VK_ACCESS_TRANSFER_WRITE_BIT,
299 		vk::VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
300 	};
301 
302 	m_vk.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
303 		vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
304 		0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
305 
306 	vk::beginRenderPass(m_vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, vk::makeRect2D(0, 0, WIDTH, HEIGHT));
307 }
308 
setDynamicViewportState(const deUint32 width,const deUint32 height)309 void DynamicStateBaseClass::setDynamicViewportState (const deUint32 width, const deUint32 height)
310 {
311 	vk::VkViewport viewport = vk::makeViewport(tcu::UVec2(width, height));
312 	m_vk.cmdSetViewport(*m_cmdBuffer, 0, 1, &viewport);
313 
314 	vk::VkRect2D scissor = vk::makeRect2D(tcu::UVec2(width, height));
315 	m_vk.cmdSetScissor(*m_cmdBuffer, 0, 1, &scissor);
316 }
317 
setDynamicViewportState(deUint32 viewportCount,const vk::VkViewport * pViewports,const vk::VkRect2D * pScissors)318 void DynamicStateBaseClass::setDynamicViewportState (deUint32 viewportCount, const vk::VkViewport* pViewports, const vk::VkRect2D* pScissors)
319 {
320 	m_vk.cmdSetViewport(*m_cmdBuffer, 0, viewportCount, pViewports);
321 	m_vk.cmdSetScissor(*m_cmdBuffer, 0, viewportCount, pScissors);
322 }
323 
setDynamicRasterizationState(const float lineWidth,const float depthBiasConstantFactor,const float depthBiasClamp,const float depthBiasSlopeFactor)324 void DynamicStateBaseClass::setDynamicRasterizationState (const float lineWidth,
325 														 const float depthBiasConstantFactor,
326 														 const float depthBiasClamp,
327 														 const float depthBiasSlopeFactor)
328 {
329 	m_vk.cmdSetLineWidth(*m_cmdBuffer, lineWidth);
330 	m_vk.cmdSetDepthBias(*m_cmdBuffer, depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor);
331 }
332 
setDynamicBlendState(const float const1,const float const2,const float const3,const float const4)333 void DynamicStateBaseClass::setDynamicBlendState (const float const1, const float const2, const float const3, const float const4)
334 {
335 	float blendConstantsants[4] = { const1, const2, const3, const4 };
336 	m_vk.cmdSetBlendConstants(*m_cmdBuffer, blendConstantsants);
337 }
338 
setDynamicDepthStencilState(const float minDepthBounds,const float maxDepthBounds,const deUint32 stencilFrontCompareMask,const deUint32 stencilFrontWriteMask,const deUint32 stencilFrontReference,const deUint32 stencilBackCompareMask,const deUint32 stencilBackWriteMask,const deUint32 stencilBackReference)339 void DynamicStateBaseClass::setDynamicDepthStencilState (const float	minDepthBounds,
340 														 const float	maxDepthBounds,
341 														 const deUint32 stencilFrontCompareMask,
342 														 const deUint32 stencilFrontWriteMask,
343 														 const deUint32 stencilFrontReference,
344 														 const deUint32 stencilBackCompareMask,
345 														 const deUint32 stencilBackWriteMask,
346 														 const deUint32 stencilBackReference)
347 {
348 	m_vk.cmdSetDepthBounds(*m_cmdBuffer, minDepthBounds, maxDepthBounds);
349 	m_vk.cmdSetStencilCompareMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontCompareMask);
350 	m_vk.cmdSetStencilWriteMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontWriteMask);
351 	m_vk.cmdSetStencilReference(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontReference);
352 	m_vk.cmdSetStencilCompareMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackCompareMask);
353 	m_vk.cmdSetStencilWriteMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackWriteMask);
354 	m_vk.cmdSetStencilReference(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackReference);
355 }
356 
357 #ifndef CTS_USES_VULKANSC
pushVertexOffset(const uint32_t vertexOffset,const vk::VkPipelineLayout pipelineLayout,const vk::VkShaderStageFlags stageFlags)358 void DynamicStateBaseClass::pushVertexOffset (const uint32_t				vertexOffset,
359 											  const vk::VkPipelineLayout	pipelineLayout,
360 											  const vk::VkShaderStageFlags	stageFlags)
361 {
362 	m_vk.cmdPushConstants(*m_cmdBuffer, pipelineLayout, stageFlags, 0u, static_cast<uint32_t>(sizeof(uint32_t)), &vertexOffset);
363 }
364 #endif // CTS_USES_VULKANSC
365 
366 } // DynamicState
367 } // vkt
368