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 "vktApiComputeInstanceResultBuffer.hpp"
24#include "vktApiBufferComputeInstance.hpp"
25#include "vkRefUtil.hpp"
26
27namespace vkt
28{
29namespace api
30{
31
32using namespace vk;
33
34ComputeInstanceResultBuffer::ComputeInstanceResultBuffer (const DeviceInterface &vki,
35																	  VkDevice device,
36																	  Allocator &allocator,
37																	  float initValue)
38		: m_vki(vki),
39		m_device(device),
40		m_bufferMem(DE_NULL),
41		m_buffer(createResultBuffer(m_vki, m_device, allocator, &m_bufferMem, initValue)),
42		m_bufferBarrier(createResultBufferBarrier(*m_buffer))
43{
44}
45
46void ComputeInstanceResultBuffer::readResultContentsTo(tcu::Vec4 (*results)[4]) const
47{
48	invalidateMappedMemoryRange(m_vki, m_device, m_bufferMem->getMemory(), m_bufferMem->getOffset(), sizeof(*results));
49	deMemcpy(*results, m_bufferMem->getHostPtr(), sizeof(*results));
50}
51
52void ComputeInstanceResultBuffer::readResultContentsTo(deUint32 *result) const
53{
54	invalidateMappedMemoryRange(m_vki, m_device, m_bufferMem->getMemory(), m_bufferMem->getOffset(), sizeof(*result));
55	deMemcpy(result, m_bufferMem->getHostPtr(), sizeof(*result));
56}
57
58Move<VkBuffer> ComputeInstanceResultBuffer::createResultBuffer(const DeviceInterface &vki,
59																	 VkDevice device,
60																	 Allocator &allocator,
61																	 de::MovePtr<Allocation> *outAllocation,
62																	 float initValue)
63{
64	const VkBufferCreateInfo createInfo =
65	{
66		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
67		DE_NULL,
68		0u,															// flags
69		(VkDeviceSize) DATA_SIZE,									// size
70		VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,							// usage
71		VK_SHARING_MODE_EXCLUSIVE,									// sharingMode
72		0u,															// queueFamilyCount
73		DE_NULL,													// pQueueFamilyIndices
74	};
75
76	Move<VkBuffer> buffer(createBuffer(vki, device, &createInfo));
77
78	const VkMemoryRequirements				requirements			= getBufferMemoryRequirements(vki, device, *buffer);
79	de::MovePtr<Allocation>					allocation				= allocator.allocate(requirements, MemoryRequirement::HostVisible);
80
81	VK_CHECK(vki.bindBufferMemory(device, *buffer, allocation->getMemory(), allocation->getOffset()));
82
83	const float								clearValue				= initValue;
84	void*									mapPtr					= allocation->getHostPtr();
85
86	for (size_t offset = 0; offset < DATA_SIZE; offset += sizeof(float))
87		deMemcpy(((deUint8 *) mapPtr) + offset, &clearValue, sizeof(float));
88
89	flushMappedMemoryRange(vki, device, allocation->getMemory(), allocation->getOffset(), (VkDeviceSize) DATA_SIZE);
90
91	*outAllocation = allocation;
92	return buffer;
93}
94
95VkBufferMemoryBarrier ComputeInstanceResultBuffer::createResultBufferBarrier(VkBuffer buffer)
96{
97	const VkBufferMemoryBarrier bufferBarrier =
98	{
99		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
100		DE_NULL,
101		VK_ACCESS_SHADER_WRITE_BIT,									// outputMask
102		VK_ACCESS_SHADER_READ_BIT,									// inputMask
103		VK_QUEUE_FAMILY_IGNORED,									// srcQueueFamilyIndex
104		VK_QUEUE_FAMILY_IGNORED,									// destQueueFamilyIndex
105		buffer,														// buffer
106		(VkDeviceSize) 0u,											// offset
107		DATA_SIZE,													// size
108	};
109
110	return bufferBarrier;
111}
112
113} // api
114} // vkt
115