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