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 
31 namespace vkt
32 {
33 namespace DynamicState
34 {
35 
36 using namespace Draw;
37 
DynamicStateBaseClass(Context & context,const char * vertexShaderName,const char * fragmentShaderName)38 DynamicStateBaseClass::DynamicStateBaseClass (Context& context, const char* vertexShaderName, const char* fragmentShaderName)
39 	: TestInstance				(context)
40 	, m_colorAttachmentFormat   (vk::VK_FORMAT_R8G8B8A8_UNORM)
41 	, m_topology				(vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
42 	, m_vk						(context.getDeviceInterface())
43 	, m_vertexShaderName		(vertexShaderName)
44 	, m_fragmentShaderName		(fragmentShaderName)
45 {
46 }
47 
initialize(void)48 void DynamicStateBaseClass::initialize (void)
49 {
50 	const vk::VkDevice device		= m_context.getDevice();
51 	const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
52 
53 	const PipelineLayoutCreateInfo pipelineLayoutCreateInfo;
54 	m_pipelineLayout = vk::createPipelineLayout(m_vk, device, &pipelineLayoutCreateInfo);
55 
56 	const vk::VkExtent3D targetImageExtent = { WIDTH, HEIGHT, 1 };
57 	const ImageCreateInfo targetImageCreateInfo(vk::VK_IMAGE_TYPE_2D, m_colorAttachmentFormat, targetImageExtent, 1, 1, vk::VK_SAMPLE_COUNT_1_BIT,
58 												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);
59 
60 	m_colorTargetImage = Image::createAndAlloc(m_vk, device, targetImageCreateInfo, m_context.getDefaultAllocator(), m_context.getUniversalQueueFamilyIndex());
61 
62 	const ImageViewCreateInfo colorTargetViewInfo(m_colorTargetImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, m_colorAttachmentFormat);
63 	m_colorTargetView = vk::createImageView(m_vk, device, &colorTargetViewInfo);
64 
65 	const vk::VkVertexInputBindingDescription vertexInputBindingDescription =
66 	{
67 		0,
68 		(deUint32)sizeof(tcu::Vec4) * 2,
69 		vk::VK_VERTEX_INPUT_RATE_VERTEX,
70 	};
71 
72 	const vk::VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
73 	{
74 		{
75 			0u,
76 			0u,
77 			vk::VK_FORMAT_R32G32B32A32_SFLOAT,
78 			0u
79 		},
80 		{
81 			1u,
82 			0u,
83 			vk::VK_FORMAT_R32G32B32A32_SFLOAT,
84 			(deUint32)(sizeof(float)* 4),
85 		}
86 	};
87 
88 	m_vertexInputState = PipelineCreateInfo::VertexInputState(
89 		1,
90 		&vertexInputBindingDescription,
91 		2,
92 		vertexInputAttributeDescriptions);
93 
94 	const vk::VkDeviceSize dataSize = m_data.size() * sizeof(PositionColorVertex);
95 	m_vertexBuffer = Buffer::createAndAlloc(m_vk, device, BufferCreateInfo(dataSize, vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT),
96 											m_context.getDefaultAllocator(), vk::MemoryRequirement::HostVisible);
97 
98 	deUint8* ptr = reinterpret_cast<unsigned char *>(m_vertexBuffer->getBoundMemory().getHostPtr());
99 	deMemcpy(ptr, &m_data[0], (size_t)dataSize);
100 
101 	vk::flushAlloc(m_vk, device, m_vertexBuffer->getBoundMemory());
102 
103 	const CmdPoolCreateInfo cmdPoolCreateInfo(queueFamilyIndex);
104 	m_cmdPool = vk::createCommandPool(m_vk, device, &cmdPoolCreateInfo);
105 
106 	const vk::VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
107 	{
108 		vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,	// VkStructureType			sType;
109 		DE_NULL,											// const void*				pNext;
110 		*m_cmdPool,											// VkCommandPool			commandPool;
111 		vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY,				// VkCommandBufferLevel		level;
112 		1u,													// deUint32					bufferCount;
113 	};
114 	m_cmdBuffer = vk::allocateCommandBuffer(m_vk, device, &cmdBufferAllocateInfo);
115 
116 	initRenderPass(device);
117 	initFramebuffer(device);
118 	initPipeline(device);
119 }
120 
121 
initRenderPass(const vk::VkDevice device)122 void DynamicStateBaseClass::initRenderPass (const vk::VkDevice device)
123 {
124 	RenderPassCreateInfo renderPassCreateInfo;
125 	renderPassCreateInfo.addAttachment(AttachmentDescription(m_colorAttachmentFormat,
126 		vk::VK_SAMPLE_COUNT_1_BIT,
127 		vk::VK_ATTACHMENT_LOAD_OP_LOAD,
128 		vk::VK_ATTACHMENT_STORE_OP_STORE,
129 		vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
130 		vk::VK_ATTACHMENT_STORE_OP_STORE,
131 		vk::VK_IMAGE_LAYOUT_GENERAL,
132 		vk::VK_IMAGE_LAYOUT_GENERAL));
133 
134 	const vk::VkAttachmentReference colorAttachmentReference =
135 	{
136 		0,
137 		vk::VK_IMAGE_LAYOUT_GENERAL
138 	};
139 
140 	renderPassCreateInfo.addSubpass(SubpassDescription(
141 		vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
142 		0,
143 		0,
144 		DE_NULL,
145 		1,
146 		&colorAttachmentReference,
147 		DE_NULL,
148 		AttachmentReference(),
149 		0,
150 		DE_NULL
151 	)
152 	);
153 
154 	m_renderPass = vk::createRenderPass(m_vk, device, &renderPassCreateInfo);
155 }
156 
initFramebuffer(const vk::VkDevice device)157 void DynamicStateBaseClass::initFramebuffer (const vk::VkDevice device)
158 {
159 	std::vector<vk::VkImageView> colorAttachments(1);
160 	colorAttachments[0] = *m_colorTargetView;
161 
162 	const FramebufferCreateInfo framebufferCreateInfo(*m_renderPass, colorAttachments, WIDTH, HEIGHT, 1);
163 
164 	m_framebuffer = vk::createFramebuffer(m_vk, device, &framebufferCreateInfo);
165 }
166 
initPipeline(const vk::VkDevice device)167 void DynamicStateBaseClass::initPipeline (const vk::VkDevice device)
168 {
169 	const vk::Unique<vk::VkShaderModule> vs(createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_vertexShaderName), 0));
170 	const vk::Unique<vk::VkShaderModule> fs(createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_fragmentShaderName), 0));
171 
172 	const PipelineCreateInfo::ColorBlendState::Attachment vkCbAttachmentState;
173 
174 	PipelineCreateInfo pipelineCreateInfo(*m_pipelineLayout, *m_renderPass, 0, 0);
175 	pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", vk::VK_SHADER_STAGE_VERTEX_BIT));
176 	pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, "main", vk::VK_SHADER_STAGE_FRAGMENT_BIT));
177 	pipelineCreateInfo.addState(PipelineCreateInfo::VertexInputState(m_vertexInputState));
178 	pipelineCreateInfo.addState(PipelineCreateInfo::InputAssemblerState(m_topology));
179 	pipelineCreateInfo.addState(PipelineCreateInfo::ColorBlendState(1, &vkCbAttachmentState));
180 	pipelineCreateInfo.addState(PipelineCreateInfo::ViewportState(1));
181 	pipelineCreateInfo.addState(PipelineCreateInfo::DepthStencilState());
182 	pipelineCreateInfo.addState(PipelineCreateInfo::RasterizerState());
183 	pipelineCreateInfo.addState(PipelineCreateInfo::MultiSampleState());
184 	pipelineCreateInfo.addState(PipelineCreateInfo::DynamicState());
185 
186 	m_pipeline = vk::createGraphicsPipeline(m_vk, device, DE_NULL, &pipelineCreateInfo);
187 }
188 
iterate(void)189 tcu::TestStatus DynamicStateBaseClass::iterate (void)
190 {
191 	DE_ASSERT(false);
192 	return tcu::TestStatus::fail("Implement iterate() method!");
193 }
194 
beginRenderPass(void)195 void DynamicStateBaseClass::beginRenderPass (void)
196 {
197 	const vk::VkClearColorValue clearColor = { { 0.0f, 0.0f, 0.0f, 1.0f } };
198 	beginRenderPassWithClearColor(clearColor);
199 }
200 
beginRenderPassWithClearColor(const vk::VkClearColorValue & clearColor,const bool skipBeginCmdBuffer)201 void DynamicStateBaseClass::beginRenderPassWithClearColor(const vk::VkClearColorValue& clearColor, const bool skipBeginCmdBuffer)
202 {
203 	if (!skipBeginCmdBuffer)
204 	{
205 		beginCommandBuffer(m_vk, *m_cmdBuffer, 0u);
206 	}
207 
208 	initialTransitionColor2DImage(m_vk, *m_cmdBuffer, m_colorTargetImage->object(), vk::VK_IMAGE_LAYOUT_GENERAL,
209 								  vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT);
210 
211 	const ImageSubresourceRange subresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT);
212 	m_vk.cmdClearColorImage(*m_cmdBuffer, m_colorTargetImage->object(),
213 		vk::VK_IMAGE_LAYOUT_GENERAL, &clearColor, 1, &subresourceRange);
214 
215 	const vk::VkMemoryBarrier memBarrier =
216 	{
217 		vk::VK_STRUCTURE_TYPE_MEMORY_BARRIER,
218 		DE_NULL,
219 		vk::VK_ACCESS_TRANSFER_WRITE_BIT,
220 		vk::VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
221 	};
222 
223 	m_vk.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
224 		vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
225 		0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
226 
227 	vk::beginRenderPass(m_vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, vk::makeRect2D(0, 0, WIDTH, HEIGHT));
228 }
229 
setDynamicViewportState(const deUint32 width,const deUint32 height)230 void DynamicStateBaseClass::setDynamicViewportState (const deUint32 width, const deUint32 height)
231 {
232 	vk::VkViewport viewport = vk::makeViewport(tcu::UVec2(width, height));
233 	m_vk.cmdSetViewport(*m_cmdBuffer, 0, 1, &viewport);
234 
235 	vk::VkRect2D scissor = vk::makeRect2D(tcu::UVec2(width, height));
236 	m_vk.cmdSetScissor(*m_cmdBuffer, 0, 1, &scissor);
237 }
238 
setDynamicViewportState(deUint32 viewportCount,const vk::VkViewport * pViewports,const vk::VkRect2D * pScissors)239 void DynamicStateBaseClass::setDynamicViewportState (deUint32 viewportCount, const vk::VkViewport* pViewports, const vk::VkRect2D* pScissors)
240 {
241 	m_vk.cmdSetViewport(*m_cmdBuffer, 0, viewportCount, pViewports);
242 	m_vk.cmdSetScissor(*m_cmdBuffer, 0, viewportCount, pScissors);
243 }
244 
setDynamicRasterizationState(const float lineWidth,const float depthBiasConstantFactor,const float depthBiasClamp,const float depthBiasSlopeFactor)245 void DynamicStateBaseClass::setDynamicRasterizationState (const float lineWidth,
246 														 const float depthBiasConstantFactor,
247 														 const float depthBiasClamp,
248 														 const float depthBiasSlopeFactor)
249 {
250 	m_vk.cmdSetLineWidth(*m_cmdBuffer, lineWidth);
251 	m_vk.cmdSetDepthBias(*m_cmdBuffer, depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor);
252 }
253 
setDynamicBlendState(const float const1,const float const2,const float const3,const float const4)254 void DynamicStateBaseClass::setDynamicBlendState (const float const1, const float const2, const float const3, const float const4)
255 {
256 	float blendConstantsants[4] = { const1, const2, const3, const4 };
257 	m_vk.cmdSetBlendConstants(*m_cmdBuffer, blendConstantsants);
258 }
259 
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)260 void DynamicStateBaseClass::setDynamicDepthStencilState (const float	minDepthBounds,
261 														 const float	maxDepthBounds,
262 														 const deUint32 stencilFrontCompareMask,
263 														 const deUint32 stencilFrontWriteMask,
264 														 const deUint32 stencilFrontReference,
265 														 const deUint32 stencilBackCompareMask,
266 														 const deUint32 stencilBackWriteMask,
267 														 const deUint32 stencilBackReference)
268 {
269 	m_vk.cmdSetDepthBounds(*m_cmdBuffer, minDepthBounds, maxDepthBounds);
270 	m_vk.cmdSetStencilCompareMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontCompareMask);
271 	m_vk.cmdSetStencilWriteMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontWriteMask);
272 	m_vk.cmdSetStencilReference(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontReference);
273 	m_vk.cmdSetStencilCompareMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackCompareMask);
274 	m_vk.cmdSetStencilWriteMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackWriteMask);
275 	m_vk.cmdSetStencilReference(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackReference);
276 }
277 
278 } // DynamicState
279 } // vkt
280