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