1/*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
7 * Copyright (c) 2015 Google Inc.
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
23#include "vktApiBufferComputeInstance.hpp"
24#include "vktApiComputeInstanceResultBuffer.hpp"
25#include "vkRefUtil.hpp"
26#include "vkBuilderUtil.hpp"
27#include "vkTypeUtil.hpp"
28
29namespace vkt
30{
31namespace api
32{
33
34using namespace vk;
35
36Move<VkBuffer> createDataBuffer (vkt::Context&				context,
37								 deUint32					offset,
38								 deUint32					bufferSize,
39								 deUint32					initData,
40								 deUint32					initDataSize,
41								 deUint32					uninitData,
42								 de::MovePtr<Allocation>*	outAllocation)
43{
44	const DeviceInterface&					vki             = context.getDeviceInterface();
45	const VkDevice							device          = context.getDevice();
46	Allocator&								allocator       = context.getDefaultAllocator();
47
48	DE_ASSERT(offset + initDataSize <= bufferSize);
49
50	const VkBufferUsageFlags				usageFlags      = (VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
51	const VkBufferCreateInfo				createInfo      =
52	{
53		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
54		DE_NULL,
55		0u,															// flags
56		(VkDeviceSize)bufferSize,									// size
57		usageFlags,													// usage
58		VK_SHARING_MODE_EXCLUSIVE,									// sharingMode
59		0u,															// queueFamilyCount
60		DE_NULL,													// pQueueFamilyIndices
61	};
62	Move<VkBuffer>							buffer(createBuffer(vki, device, &createInfo));
63
64	const VkMemoryRequirements				requirements    = getBufferMemoryRequirements(vki, device, *buffer);
65	de::MovePtr<Allocation>					allocation      = allocator.allocate(requirements, MemoryRequirement::HostVisible);
66
67	VK_CHECK(vki.bindBufferMemory(device, *buffer, allocation->getMemory(), allocation->getOffset()));
68
69	void* const								mapPtr          = allocation->getHostPtr();
70
71	if (offset)
72		deMemset(mapPtr, uninitData, (size_t)offset);
73
74	deMemset((deUint8 *)mapPtr + offset, initData, initDataSize);
75	deMemset((deUint8 *)mapPtr + offset + initDataSize, uninitData,
76		(size_t)bufferSize - (size_t)offset - initDataSize);
77
78	flushMappedMemoryRange(vki, device, allocation->getMemory(), allocation->getOffset(), bufferSize);
79
80	*outAllocation = allocation;
81	return buffer;
82}
83
84Move<VkBuffer> createColorDataBuffer (deUint32 offset,
85									  deUint32 bufferSize,
86									  const tcu::Vec4& color1,
87									  const tcu::Vec4& color2,
88									  de::MovePtr<Allocation>* outAllocation,
89									  vkt::Context& context)
90{
91	const DeviceInterface&					vki						= context.getDeviceInterface();
92	const VkDevice							device					= context.getDevice();
93	Allocator&								allocator				= context.getDefaultAllocator();
94
95	DE_ASSERT(offset + sizeof(tcu::Vec4[2]) <= bufferSize);
96
97	const VkBufferUsageFlags				usageFlags				= (VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
98	const VkBufferCreateInfo				createInfo				=
99	{
100		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
101		DE_NULL,
102		0u,															// flags
103		(VkDeviceSize) bufferSize,									// size
104		usageFlags,													// usage
105		VK_SHARING_MODE_EXCLUSIVE,									// sharingMode
106		0u,															// queueFamilyCount
107		DE_NULL,													// pQueueFamilyIndices
108	};
109	Move<VkBuffer> buffer(createBuffer(vki, device, &createInfo));
110
111	const VkMemoryRequirements				requirements			= getBufferMemoryRequirements(vki, device, *buffer);
112	de::MovePtr<Allocation>					allocation				= allocator.allocate(requirements, MemoryRequirement::HostVisible);
113
114	VK_CHECK(vki.bindBufferMemory(device, *buffer, allocation->getMemory(), allocation->getOffset()));
115
116	void*									mapPtr					= allocation->getHostPtr();
117
118	if (offset)
119		deMemset(mapPtr, 0x5A, (size_t) offset);
120
121	deMemcpy((deUint8 *) mapPtr + offset, color1.getPtr(), sizeof(tcu::Vec4));
122	deMemcpy((deUint8 *) mapPtr + offset + sizeof(tcu::Vec4), color2.getPtr(), sizeof(tcu::Vec4));
123	deMemset((deUint8 *) mapPtr + offset + 2 * sizeof(tcu::Vec4), 0x5A,
124			 (size_t) bufferSize - (size_t) offset - 2 * sizeof(tcu::Vec4));
125
126	flushMappedMemoryRange(vki, device, allocation->getMemory(), allocation->getOffset(), bufferSize);
127
128	*outAllocation = allocation;
129	return buffer;
130}
131
132Move<VkDescriptorSetLayout> createDescriptorSetLayout (vkt::Context& context)
133{
134
135	const DeviceInterface&					vki						= context.getDeviceInterface();
136	const VkDevice							device					= context.getDevice();
137
138	DescriptorSetLayoutBuilder				builder;
139
140	builder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
141	builder.addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
142
143	return builder.build(vki, device);
144}
145
146Move<VkDescriptorPool> createDescriptorPool (vkt::Context& context)
147{
148	const DeviceInterface&					vki						= context.getDeviceInterface();
149	const VkDevice							device					= context.getDevice();
150
151	return vk::DescriptorPoolBuilder()
152		.addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
153		.addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,1u)
154		.build(vki, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
155}
156
157Move<VkDescriptorSet> createDescriptorSet (vkt::Context& context,
158											VkDescriptorPool pool,
159											VkDescriptorSetLayout layout,
160											VkBuffer buffer,
161											deUint32 offset,
162											VkBuffer resBuf)
163{
164	const DeviceInterface&					vki             = context.getDeviceInterface();
165	const VkDevice							device          = context.getDevice();
166
167	const vk::VkDescriptorBufferInfo		resultInfo      = makeDescriptorBufferInfo(resBuf, 0u, (vk::VkDeviceSize) ComputeInstanceResultBuffer::DATA_SIZE);
168	const vk::VkDescriptorBufferInfo		bufferInfo      = makeDescriptorBufferInfo(buffer, (vk::VkDeviceSize)offset, (vk::VkDeviceSize)sizeof(tcu::Vec4[2]));
169
170	const vk::VkDescriptorSetAllocateInfo	allocInfo       =
171	{
172		vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
173		DE_NULL,
174		pool,
175		1u,
176		&layout
177	};
178	vk::Move<vk::VkDescriptorSet>			descriptorSet   = allocateDescriptorSet(vki, device, &allocInfo);
179
180	DescriptorSetUpdateBuilder builder;
181
182	// result
183	builder.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
184
185	// buffer
186	builder.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &bufferInfo);
187
188	builder.update(vki, device);
189	return descriptorSet;
190}
191
192Move<VkDescriptorSet> createDescriptorSet (VkDescriptorPool pool,
193										   VkDescriptorSetLayout layout,
194										   VkBuffer viewA,
195										   deUint32 offsetA,
196										   VkBuffer viewB,
197										   deUint32 offsetB,
198										   VkBuffer resBuf,
199										   vkt::Context& context)
200{
201	const DeviceInterface&					vki						= context.getDeviceInterface();
202	const VkDevice							device					= context.getDevice();
203
204	const vk::VkDescriptorBufferInfo		resultInfo				= makeDescriptorBufferInfo(resBuf, 0u, (vk::VkDeviceSize) ComputeInstanceResultBuffer::DATA_SIZE);
205	const vk::VkDescriptorBufferInfo		bufferInfos[2]			=
206	{
207		vk::makeDescriptorBufferInfo(viewA, (vk::VkDeviceSize)offsetA, (vk::VkDeviceSize)sizeof(tcu::Vec4[2])),
208		vk::makeDescriptorBufferInfo(viewB, (vk::VkDeviceSize)offsetB, (vk::VkDeviceSize)sizeof(tcu::Vec4[2])),
209	};
210
211	const vk::VkDescriptorSetAllocateInfo	allocInfo				=
212	{
213		vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
214		DE_NULL,
215		pool,
216		1u,
217		&layout
218	};
219	vk::Move<vk::VkDescriptorSet>			descriptorSet			= allocateDescriptorSet(vki, device, &allocInfo);
220
221	DescriptorSetUpdateBuilder builder;
222
223	// result
224	builder.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
225
226	// buffers
227	builder.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &bufferInfos[0]);
228
229	builder.update(vki, device);
230	return descriptorSet;
231}
232
233} // api
234} // vkt
235