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> createColorDataBuffer (deUint32 offset,
37									  deUint32 bufferSize,
38									  const tcu::Vec4& color1,
39									  const tcu::Vec4& color2,
40									  de::MovePtr<Allocation>* outAllocation,
41									  vkt::Context& context)
42{
43	const DeviceInterface&					vki						= context.getDeviceInterface();
44	const VkDevice							device					= context.getDevice();
45	Allocator&								allocator				= context.getDefaultAllocator();
46
47	DE_ASSERT(offset + sizeof(tcu::Vec4[2]) <= bufferSize);
48
49	const VkBufferUsageFlags				usageFlags				= (VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
50	const VkBufferCreateInfo				createInfo				=
51	{
52		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
53		DE_NULL,
54		0u,															// flags
55		(VkDeviceSize) bufferSize,									// size
56		usageFlags,													// usage
57		VK_SHARING_MODE_EXCLUSIVE,									// sharingMode
58		0u,															// queueFamilyCount
59		DE_NULL,													// pQueueFamilyIndices
60	};
61	Move<VkBuffer> buffer(createBuffer(vki, device, &createInfo));
62
63	const VkMemoryRequirements				requirements			= getBufferMemoryRequirements(vki, device, *buffer);
64	de::MovePtr<Allocation>					allocation				= allocator.allocate(requirements, MemoryRequirement::HostVisible);
65
66	VK_CHECK(vki.bindBufferMemory(device, *buffer, allocation->getMemory(), allocation->getOffset()));
67
68
69	void*									mapPtr					= allocation->getHostPtr();
70
71	if (offset)
72		deMemset(mapPtr, 0x5A, (size_t) offset);
73
74	deMemcpy((deUint8 *) mapPtr + offset, color1.getPtr(), sizeof(tcu::Vec4));
75	deMemcpy((deUint8 *) mapPtr + offset + sizeof(tcu::Vec4), color2.getPtr(), sizeof(tcu::Vec4));
76	deMemset((deUint8 *) mapPtr + offset + 2 * sizeof(tcu::Vec4), 0x5A,
77			 (size_t) bufferSize - (size_t) offset - 2 * sizeof(tcu::Vec4));
78
79	flushMappedMemoryRange(vki, device, allocation->getMemory(), allocation->getOffset(), bufferSize);
80
81	*outAllocation = allocation;
82	return buffer;
83}
84
85Move<VkDescriptorSetLayout> createDescriptorSetLayout (vkt::Context& context)
86{
87
88	const DeviceInterface&					vki						= context.getDeviceInterface();
89	const VkDevice							device					= context.getDevice();
90
91	DescriptorSetLayoutBuilder				builder;
92
93	builder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
94	builder.addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
95
96	return builder.build(vki, device);
97}
98
99Move<VkDescriptorPool> createDescriptorPool (vkt::Context& context)
100{
101	const DeviceInterface&					vki						= context.getDeviceInterface();
102	const VkDevice							device					= context.getDevice();
103
104	return vk::DescriptorPoolBuilder()
105		.addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
106		.addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,1u)
107		.build(vki, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
108}
109
110Move<VkDescriptorSet> createDescriptorSet (VkDescriptorPool pool,
111										   VkDescriptorSetLayout layout,
112										   VkBuffer viewA,
113										   deUint32 offsetA,
114										   VkBuffer viewB,
115										   deUint32 offsetB,
116										   VkBuffer resBuf,
117										   vkt::Context& context)
118{
119	const DeviceInterface&					vki						= context.getDeviceInterface();
120	const VkDevice							device					= context.getDevice();
121
122	const vk::VkDescriptorBufferInfo		resultInfo				= makeDescriptorBufferInfo(resBuf, 0u, (vk::VkDeviceSize) ComputeInstanceResultBuffer::DATA_SIZE);
123	const vk::VkDescriptorBufferInfo		bufferInfos[2]			=
124	{
125		vk::makeDescriptorBufferInfo(viewA, (vk::VkDeviceSize)offsetA, (vk::VkDeviceSize)sizeof(tcu::Vec4[2])),
126		vk::makeDescriptorBufferInfo(viewB, (vk::VkDeviceSize)offsetB, (vk::VkDeviceSize)sizeof(tcu::Vec4[2])),
127	};
128
129	const vk::VkDescriptorSetAllocateInfo	allocInfo				=
130	{
131		vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
132		DE_NULL,
133		pool,
134		1u,
135		&layout
136	};
137	vk::Move<vk::VkDescriptorSet>			descriptorSet			= allocateDescriptorSet(vki, device, &allocInfo);
138
139	DescriptorSetUpdateBuilder builder;
140
141	// result
142	builder.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
143
144	// buffers
145	builder.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &bufferInfos[0]);
146
147	builder.update(vki, device);
148	return descriptorSet;
149}
150
151} // api
152} // vkt
153