• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2016 The Khronos Group Inc.
6  * Copyright (c) 2016 The Android Open Source Project
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 Geometry Basic Class
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktGeometryBasicClass.hpp"
26 
27 #include "vkDefs.hpp"
28 #include "vktTestCase.hpp"
29 #include "vktTestCaseUtil.hpp"
30 #include "vkImageUtil.hpp"
31 #include "vkPrograms.hpp"
32 #include "vkBuilderUtil.hpp"
33 #include "vkRefUtil.hpp"
34 #include "vkQueryUtil.hpp"
35 #include "vkMemUtil.hpp"
36 
37 #include <string>
38 
39 namespace vkt
40 {
41 namespace geometry
42 {
43 using namespace vk;
44 using tcu::IVec2;
45 using tcu::Vec4;
46 using tcu::TestStatus;
47 using tcu::TestContext;
48 using tcu::TestCaseGroup;
49 using de::MovePtr;
50 using std::string;
51 using std::vector;
52 using std::size_t;
53 
54 static const int TEST_CANVAS_SIZE = 256;
55 
GeometryExpanderRenderTestInstance(Context & context,const VkPrimitiveTopology primitiveType,const char * name)56 GeometryExpanderRenderTestInstance::GeometryExpanderRenderTestInstance (Context&					context,
57 																		const VkPrimitiveTopology	primitiveType,
58 																		const char*					name)
59 	: TestInstance		(context)
60 	, m_primitiveType	(primitiveType)
61 	, m_name			(name)
62 {
63 	checkGeometryShaderSupport(context.getInstanceInterface(), context.getPhysicalDevice());
64 }
65 
iterate(void)66 tcu::TestStatus GeometryExpanderRenderTestInstance::iterate (void)
67 {
68 	const DeviceInterface&			vk						= m_context.getDeviceInterface();
69 	const VkDevice					device					= m_context.getDevice();
70 	const deUint32					queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
71 	const VkQueue					queue					= m_context.getUniversalQueue();
72 	Allocator&						memAlloc				= m_context.getDefaultAllocator();
73 	const IVec2						resolution				= IVec2(TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
74 	const VkFormat					colorFormat				= VK_FORMAT_R8G8B8A8_UNORM;
75 	const Image						colorAttachmentImage	(
76 																vk,
77 																device,
78 																memAlloc,
79 																makeImageCreateInfo(resolution, colorFormat, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT),
80 																MemoryRequirement::Any
81 															);
82 	const Unique<VkRenderPass>		renderPass				(makeRenderPass(vk, device, colorFormat));
83 
84 	const Move<VkPipelineLayout>	pipelineLayout			(createPipelineLayout(vk, device));
85 	const VkImageSubresourceRange	colorSubRange			= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
86 	const Unique<VkImageView>		colorAttachmentView		(makeImageView(vk, device, *colorAttachmentImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubRange));
87 	const Unique<VkFramebuffer>		framebuffer				(makeFramebuffer(vk, device, *renderPass, *colorAttachmentView, resolution.x(), resolution.y(), 1u));
88 	const Unique<VkCommandPool>		cmdPool					(makeCommandPool(vk, device, queueFamilyIndex));
89 	const Unique<VkCommandBuffer>	cmdBuffer				(makeCommandBuffer(vk, device, *cmdPool));
90 
91 	const VkDeviceSize				vertexDataSizeBytes		= sizeInBytes(m_vertexPosData) + sizeInBytes(m_vertexAttrData);
92 	const deUint32					vertexPositionsOffset	= 0u;
93 	const deUint32					vertexAtrrOffset		= static_cast<deUint32>(sizeof(Vec4));
94 	const string					geometryShaderName		= (m_context.getBinaryCollection().contains("geometry_pointsize") && checkPointSize (m_context.getInstanceInterface(), m_context.getPhysicalDevice()))?
95 																"geometry_pointsize" : "geometry";
96 
97 	const Unique<VkPipeline>		pipeline				(GraphicsPipelineBuilder()
98 																.setRenderSize			(resolution)
99 																.setShader				(vk, device, VK_SHADER_STAGE_VERTEX_BIT, m_context.getBinaryCollection().get("vertex"), DE_NULL)
100 																.setShader				(vk, device, VK_SHADER_STAGE_GEOMETRY_BIT, m_context.getBinaryCollection().get(geometryShaderName), DE_NULL)
101 																.setShader				(vk, device, VK_SHADER_STAGE_FRAGMENT_BIT, m_context.getBinaryCollection().get("fragment"), DE_NULL)
102 																.addVertexBinding		(makeVertexInputBindingDescription(0u, 2u*vertexAtrrOffset, VK_VERTEX_INPUT_RATE_VERTEX))
103 																.addVertexAttribute		(makeVertexInputAttributeDescription(0u, 0u, VK_FORMAT_R32G32B32A32_SFLOAT, vertexPositionsOffset))
104 																.addVertexAttribute		(makeVertexInputAttributeDescription(1u, 0u, VK_FORMAT_R32G32B32A32_SFLOAT, vertexAtrrOffset))
105 																.setPrimitiveTopology	(m_primitiveType)
106 																.build					(vk, device, *pipelineLayout, *renderPass));
107 
108 	const VkDeviceSize				colorBufferSizeBytes	= resolution.x()*resolution.y() * tcu::getPixelSize(mapVkFormat(colorFormat));
109 	const Buffer					colorBuffer				(vk, device, memAlloc, makeBufferCreateInfo(colorBufferSizeBytes,
110 																VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible);
111 	const Buffer					vertexBuffer			(vk, device, memAlloc, makeBufferCreateInfo(vertexDataSizeBytes,
112 																VK_BUFFER_USAGE_VERTEX_BUFFER_BIT ), MemoryRequirement::HostVisible);
113 	{
114 		const Allocation& alloc = vertexBuffer.getAllocation();
115 		struct DataVec4
116 		{
117 			Vec4 pos;
118 			Vec4 color;
119 		};
120 
121 		DataVec4* const pData = static_cast<DataVec4*>(alloc.getHostPtr());
122 		for(int ndx = 0; ndx < m_numDrawVertices; ++ndx)
123 		{
124 			pData[ndx].pos = m_vertexPosData[ndx];
125 			pData[ndx].color = m_vertexAttrData[ndx];
126 		}
127 		flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), vertexDataSizeBytes);
128 		// No barrier needed, flushed memory is automatically visible
129 	}
130 
131 	// Draw commands
132 	beginCommandBuffer(vk, *cmdBuffer);
133 
134 	// Change color attachment image layout
135 	{
136 		const VkImageMemoryBarrier colorAttachmentLayoutBarrier = makeImageMemoryBarrier(
137 				(VkAccessFlags)0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
138 				VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
139 				*colorAttachmentImage, colorSubRange);
140 
141 		vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u,
142 						0u, DE_NULL, 0u, DE_NULL, 1u, &colorAttachmentLayoutBarrier);
143 	}
144 
145 	// Begin render pass
146 	{
147 		const VkRect2D renderArea = {
148 				makeOffset2D(0, 0),
149 				makeExtent2D(resolution.x(), resolution.y()),
150 			};
151 			const tcu::Vec4 clearColor(0.0f, 0.0f, 0.0f, 1.0f);
152 			beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderArea, clearColor);
153 	}
154 
155 	vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
156 	{
157 		const VkBuffer buffers[] = { vertexBuffer.get()};
158 		const VkDeviceSize offsets[] = { vertexPositionsOffset };
159 		vk.cmdBindVertexBuffers(*cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(buffers), buffers, offsets);
160 	}
161 
162 	bindDescriptorSets(vk, device, memAlloc, *cmdBuffer, *pipelineLayout);
163 
164 	drawCommand (*cmdBuffer);
165 	endRenderPass(vk, *cmdBuffer);
166 
167 	// Copy render result to a host-visible buffer
168 	{
169 		const VkImageMemoryBarrier colorAttachmentPreCopyBarrier = makeImageMemoryBarrier(
170 				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
171 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
172 				*colorAttachmentImage, colorSubRange);
173 
174 		vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
175 				0u, DE_NULL, 0u, DE_NULL, 1u, &colorAttachmentPreCopyBarrier);
176 	}
177 	{
178 		const VkBufferImageCopy copyRegion = makeBufferImageCopy(makeExtent3D(resolution.x(), resolution.y(), 1), makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
179 		vk.cmdCopyImageToBuffer(*cmdBuffer, *colorAttachmentImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorBuffer, 1u, &copyRegion);
180 	}
181 
182 	{
183 		const VkBufferMemoryBarrier postCopyBarrier = makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *colorBuffer, 0ull, colorBufferSizeBytes);
184 
185 		vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u,
186 			0u, DE_NULL, 1u, &postCopyBarrier, 0u, DE_NULL);
187 	}
188 
189 	endCommandBuffer(vk, *cmdBuffer);
190 	submitCommandsAndWait(vk, device, queue, *cmdBuffer);
191 
192 	{
193 		// Log the result image.
194 		const Allocation& colorBufferAlloc = colorBuffer.getAllocation();
195 		invalidateMappedMemoryRange(vk, device, colorBufferAlloc.getMemory(), colorBufferAlloc.getOffset(), colorBufferSizeBytes);
196 		const tcu::ConstPixelBufferAccess imagePixelAccess(mapVkFormat(colorFormat), resolution.x(), resolution.y(), 1, colorBufferAlloc.getHostPtr());
197 
198 		if (!compareWithFileImage(m_context, imagePixelAccess, m_name))
199 			return TestStatus::fail("Fail");
200 	}
201 
202 	return TestStatus::pass("Pass");
203 }
204 
createPipelineLayout(const DeviceInterface & vk,const VkDevice device)205 Move<VkPipelineLayout> GeometryExpanderRenderTestInstance::createPipelineLayout (const DeviceInterface& vk, const VkDevice device)
206 {
207 	return makePipelineLayout(vk, device);
208 }
209 
drawCommand(const VkCommandBuffer & cmdBuffer)210 void GeometryExpanderRenderTestInstance::drawCommand (const VkCommandBuffer& cmdBuffer)
211 {
212 	const DeviceInterface& vk = m_context.getDeviceInterface();
213 	vk.cmdDraw(cmdBuffer, static_cast<deUint32>(m_numDrawVertices), 1u, 0u, 0u);
214 }
215 
216 } // geometry
217 } // vkt
218