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 Buffer Object Util
23 *//*--------------------------------------------------------------------*/
24
25#include "vktDrawBufferObjectUtil.hpp"
26
27#include "vkQueryUtil.hpp"
28
29namespace vkt
30{
31namespace Draw
32{
33
34Buffer::Buffer (const vk::DeviceInterface& vk, vk::VkDevice device, vk::Move<vk::VkBuffer> object_)
35	: m_allocation	(DE_NULL)
36	, m_allocOffset	(0ull)
37	, m_object		(object_)
38	, m_vk			(vk)
39	, m_device		(device)
40{
41}
42
43void Buffer::bindMemory (de::MovePtr<vk::Allocation> allocation, vk::VkDeviceSize allocOffset)
44{
45	DE_ASSERT(allocation);
46	VK_CHECK(m_vk.bindBufferMemory(m_device, *m_object, allocation->getMemory(), allocation->getOffset() + allocOffset));
47
48	DE_ASSERT(!m_allocation);
49	m_allocation = allocation;
50	m_allocOffset = allocOffset;
51}
52
53de::SharedPtr<Buffer> Buffer::createAndAlloc (const vk::DeviceInterface& vk,
54											  vk::VkDevice device,
55											  const vk::VkBufferCreateInfo &createInfo,
56											  vk::Allocator &allocator,
57											  vk::MemoryRequirement memoryRequirement,
58											  vk::VkDeviceSize allocationOffset)
59{
60	de::SharedPtr<Buffer> ret = create(vk, device, createInfo);
61
62	vk::VkMemoryRequirements bufferRequirements = vk::getBufferMemoryRequirements(vk, device, ret->object());
63
64	// If requested, allocate more memory for the extra offset inside the allocation.
65	const auto extraRoom = de::roundUp(allocationOffset, bufferRequirements.alignment);
66	bufferRequirements.size += extraRoom;
67
68	ret->bindMemory(allocator.allocate(bufferRequirements, memoryRequirement), extraRoom);
69	return ret;
70}
71
72de::SharedPtr<Buffer> Buffer::create (const vk::DeviceInterface& vk,
73									  vk::VkDevice device,
74									  const vk::VkBufferCreateInfo& createInfo)
75{
76	return de::SharedPtr<Buffer>(new Buffer(vk, device, vk::createBuffer(vk, device, &createInfo)));
77}
78
79void* Buffer::getHostPtr (void) const
80{
81	if (!m_allocation)
82		return nullptr;
83	return reinterpret_cast<uint8_t*>(m_allocation->getHostPtr()) + m_allocOffset;
84}
85
86void bufferBarrier (const vk::DeviceInterface&	vk,
87					vk::VkCommandBuffer			cmdBuffer,
88					vk::VkBuffer				buffer,
89					vk::VkAccessFlags			srcAccessMask,
90					vk::VkAccessFlags			dstAccessMask,
91					vk::VkPipelineStageFlags	srcStageMask,
92					vk::VkPipelineStageFlags	dstStageMask)
93{
94	vk::VkBufferMemoryBarrier barrier;
95	barrier.sType				= vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
96	barrier.pNext				= DE_NULL;
97	barrier.srcAccessMask		= srcAccessMask;
98	barrier.dstAccessMask		= dstAccessMask;
99	barrier.srcQueueFamilyIndex	= VK_QUEUE_FAMILY_IGNORED;
100	barrier.dstQueueFamilyIndex	= VK_QUEUE_FAMILY_IGNORED;
101	barrier.buffer				= buffer;
102	barrier.offset				= 0;
103	barrier.size				= VK_WHOLE_SIZE;
104
105	vk.cmdPipelineBarrier(cmdBuffer, srcStageMask, dstStageMask, (vk::VkDependencyFlags)0, 0, (const vk::VkMemoryBarrier*)DE_NULL,
106						  1, &barrier, 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
107}
108
109} // Draw
110} // vkt
111