HoviTron Video Pipeline
Macros | Functions
VulkanHelperFunction.h File Reference

Class that contains helper functions for Vulkan. More...

#include "commonVulkan.h"
#include "VulkanContext.h"

Go to the source code of this file.

Macros

#define INDEX_E(x, y, W)   ((y)*(W) + (x))
 

Functions

uint32_t findMemoryType (vk::PhysicalDevice &physicalDevice, uint32_t typeFilter, vk::MemoryPropertyFlags properties)
 
uint32_t findFastMemoryType (vk::PhysicalDevice &physicalDevice, uint32_t typeFilter, vk::MemoryPropertyFlags properties)
 
void createImage (vk::Device &device, vk::PhysicalDevice &physicalDevice, uint32_t width, uint32_t height, vk::Format format, vk::ImageTiling tiling, vk::ImageUsageFlags usage, vk::MemoryPropertyFlags properties, vk::Image &image, vk::DeviceMemory &imageMemory)
 
vk::ImageView createImageView (vk::Device &device, vk::Image image, vk::Format format, vk::ImageAspectFlags aspectFlags)
 
vk::CommandBuffer beginSingleTimeCommands (VulkanContext *context, vk::CommandPool &commandPool)
 
void endSingleTimeCommands (VulkanContext *context, vk::CommandPool &commandPool, vk::CommandBuffer commandBuffer)
 
void transitionImageLayout (VulkanContext *context, vk::CommandPool &commandPool, vk::Image image, vk::Format format, vk::ImageLayout oldLayout, vk::ImageLayout newLayout)
 
void createBuffer (vk::DeviceSize size, vk::BufferUsageFlags usage, vk::MemoryPropertyFlags properties, vk::Buffer &buffer, vk::DeviceMemory &bufferMemory, vk::Device &device, vk::PhysicalDevice &physicalDevice)
 
void createFastBuffer (vk::DeviceSize size, vk::BufferUsageFlags usage, vk::MemoryPropertyFlags properties, vk::Buffer &buffer, vk::DeviceMemory &bufferMemory, vk::Device &device, vk::PhysicalDevice &physicalDevice)
 
std::vector< uint32_t > generate_picture_EBO (const glm::vec2 &s)
 
glm::mat3x3 glmEulerAnglesDegreeToRotationMatrix (glm::vec3)
 
glm::mat3x3 glmEulerAnglesDegreeToRotationMatrixNotOMAF (glm::vec3)
 
glm::quat ApproximateAverage (std::vector< glm::quat > quaternions)
 
glm::vec3 eulerAngleXYZFromRotationMatrix (glm::mat3x3 &mat)
 
glm::vec3 quatToEuler (glm::quat)
 

Detailed Description

Class that contains helper functions for Vulkan.

Definition in file VulkanHelperFunction.h.

Macro Definition Documentation

◆ INDEX_E

#define INDEX_E (   x,
  y,
 
)    ((y)*(W) + (x))

Definition at line 41 of file VulkanHelperFunction.h.

Function Documentation

◆ ApproximateAverage()

glm::quat ApproximateAverage ( std::vector< glm::quat >  quaternions)

Average of quaternions "close" to each other (faster than full conversion)

Definition at line 406 of file VulkanHelperFunction.cpp.

406 {
407 auto qLength = quaternions.size();
408 const float weightCst = 1.0f / qLength;
409 glm::quat qAvg = { 0.0, 0.0, 0.0, 0.0 };
410 for (int i = 0; i < qLength; i++) {
411 glm::quat q = quaternions[i];
412 double weight = weightCst;
413
414 // Correct for double cover, by ensuring that dot product
415 // of quats[i] and quats[0] is positive
416
417 if (i > 0 && glm::dot(quaternions[i], quaternions[0]) < 0.0) {
418 weight = -weight;
419 }
420
421 qAvg += glm::quat(weight * q.x, weight * q.y, weight * q.z, weight * q.w);
422 }
423 return glm::normalize(qAvg);
424}

◆ beginSingleTimeCommands()

vk::CommandBuffer beginSingleTimeCommands ( VulkanContext context,
vk::CommandPool &  commandPool 
)

Definition at line 117 of file VulkanHelperFunction.cpp.

118{
119 vk::CommandBufferAllocateInfo allocInfo(commandPool, vk::CommandBufferLevel::ePrimary, 1);
120 vk::CommandBuffer commandBuffer = context->device.allocateCommandBuffers(allocInfo).front();
121
122 vk::CommandBufferBeginInfo beginInfo(vk::CommandBufferUsageFlagBits::eOneTimeSubmit);
123 commandBuffer.begin(beginInfo);
124
125 return commandBuffer;
126}
vk::Device device
Definition: VulkanContext.h:87

◆ createBuffer()

void createBuffer ( vk::DeviceSize  size,
vk::BufferUsageFlags  usage,
vk::MemoryPropertyFlags  properties,
vk::Buffer &  buffer,
vk::DeviceMemory &  bufferMemory,
vk::Device &  device,
vk::PhysicalDevice &  physicalDevice 
)

Definition at line 243 of file VulkanHelperFunction.cpp.

244{
245 // create buffer
246 vk::BufferCreateInfo createInfo(
247 vk::BufferCreateFlags(),
248 size, //size
249 usage, //usage
250 vk::SharingMode::eExclusive //sharing mode
251 );
252 buffer = device.createBuffer(createInfo);
253
254 // allocate device memory for that buffer
255 vk::MemoryRequirements memRequirements = device.getBufferMemoryRequirements(buffer);
256 uint32_t memoryTypeIndex = findMemoryType(physicalDevice, memRequirements.memoryTypeBits, properties);
257 vk::MemoryAllocateInfo memAllocInfo(memRequirements.size, memoryTypeIndex);
258 bufferMemory = device.allocateMemory(memAllocInfo);
259
260 device.bindBufferMemory(buffer, bufferMemory, 0);
261}

◆ createFastBuffer()

void createFastBuffer ( vk::DeviceSize  size,
vk::BufferUsageFlags  usage,
vk::MemoryPropertyFlags  properties,
vk::Buffer &  buffer,
vk::DeviceMemory &  bufferMemory,
vk::Device &  device,
vk::PhysicalDevice &  physicalDevice 
)

Definition at line 224 of file VulkanHelperFunction.cpp.

225{
226 // create buffer
227 vk::BufferCreateInfo createInfo(
228 vk::BufferCreateFlags(),
229 size, //size
230 usage, //usage
231 vk::SharingMode::eExclusive //sharing mode
232 );
233 buffer = device.createBuffer(createInfo);
234
235 // allocate device memory for that buffer
236 vk::MemoryRequirements memRequirements = device.getBufferMemoryRequirements(buffer);
237 uint32_t memoryTypeIndex = findFastMemoryType(physicalDevice, memRequirements.memoryTypeBits, properties);
238 vk::MemoryAllocateInfo memAllocInfo(memRequirements.size, memoryTypeIndex);
239 bufferMemory = device.allocateMemory(memAllocInfo);
240
241 device.bindBufferMemory(buffer, bufferMemory, 0);
242}

◆ createImage()

void createImage ( vk::Device &  device,
vk::PhysicalDevice &  physicalDevice,
uint32_t  width,
uint32_t  height,
vk::Format  format,
vk::ImageTiling  tiling,
vk::ImageUsageFlags  usage,
vk::MemoryPropertyFlags  properties,
vk::Image &  image,
vk::DeviceMemory &  imageMemory 
)

Definition at line 73 of file VulkanHelperFunction.cpp.

74{
75 vk::ImageCreateInfo imageInfo(
76 vk::ImageCreateFlags(), //flags
77 vk::ImageType::e2D, //imageType
78 format, //format
79 { static_cast<uint32_t>(width), static_cast<uint32_t>(height), 1 }, //extend
80 1, //mipLevels
81 1, //array
82 vk::SampleCountFlagBits::e1, //samples
83 tiling, //tiling
84 usage, //usage
85 vk::SharingMode::eExclusive //sharingMode
86 );
87 imageInfo.initialLayout = vk::ImageLayout::eUndefined;
88
89 image = device.createImage(imageInfo);
90
91 vk::MemoryRequirements memRequirement = device.getImageMemoryRequirements(image);
92 vk::MemoryAllocateInfo allocInfo(memRequirement.size, findMemoryType(physicalDevice, memRequirement.memoryTypeBits, properties));
93
94 imageMemory = device.allocateMemory(allocInfo, nullptr);
95 device.bindImageMemory(image, imageMemory, 0);
96}

◆ createImageView()

vk::ImageView createImageView ( vk::Device &  device,
vk::Image  image,
vk::Format  format,
vk::ImageAspectFlags  aspectFlags 
)

Definition at line 98 of file VulkanHelperFunction.cpp.

99{
100 vk::ImageSubresourceRange subRessources(
101 aspectFlags, //aspectMask
102 0, //baseMipLevel
103 1, //levelCount
104 0, //baseArrayLayer
105 1 //layerCount
106 );
107 vk::ImageViewCreateInfo viewInfo(
108 vk::ImageViewCreateFlags(), //flags
109 image, //image
110 vk::ImageViewType::e2D, //imageView
111 format, //format
112 {}, //components
113 subRessources //subRessourceRange
114 );
115 return device.createImageView(viewInfo);
116}

◆ endSingleTimeCommands()

void endSingleTimeCommands ( VulkanContext context,
vk::CommandPool &  commandPool,
vk::CommandBuffer  commandBuffer 
)

Definition at line 128 of file VulkanHelperFunction.cpp.

129{
130 commandBuffer.end();
131
132 vk::SubmitInfo submitInfo(0, nullptr, nullptr, 1, &commandBuffer);
133
134 context->graphicsQueue.submit(submitInfo, nullptr);
135 context->graphicsQueue.waitIdle();
136 context->device.freeCommandBuffers(commandPool, 1, &commandBuffer);
137}
vk::Queue graphicsQueue
Definition: VulkanContext.h:89

◆ eulerAngleXYZFromRotationMatrix()

glm::vec3 eulerAngleXYZFromRotationMatrix ( glm::mat3x3 &  mat)

Definition at line 426 of file VulkanHelperFunction.cpp.

426 {
427 //source: http://eecs.qmul.ac.uk/~gslabaugh/publications/euler.pdf
428 auto mat = glm::transpose(matA);
429
430 auto R11 = mat[0][0];
431 auto R21 = mat[1][0];
432 auto R31 = mat[2][0];
433
434 auto R12 = mat[0][1];
435 auto R22 = mat[1][1];
436 auto R32 = mat[2][1];
437
438 auto R13 = mat[0][2];
439 auto R23 = mat[1][2];
440 auto R33 = mat[2][2];
441
442 float theta = 0;
443 float phi = 0;
444 float psi = 0;
445
446#ifndef __ANDROID__
447 const double pi = std::numbers::pi;
448#else
449 const double pi = M_PI;
450#endif
451 if (std::abs(R31) != 1) {
452 auto t1 = std::asin(R31);
453 auto t2 = pi - t1;
454 theta = std::abs(t1) <= std::abs(t2) ? t1 : t2;
455
456 auto cost1 = std::cos(t1);
457 auto cost2 = std::cos(t2);
458
459 auto psi1 = std::atan2(R32/cost1,R33/cost1);
460 auto psi2 = std::atan2(R32 /cost2, R33 /cost2);
461 psi = std::abs(t1) <= std::abs(t2) ? psi1 : psi2;
462
463 auto phi1 = std::atan2(R21 / cost1, R11 / cost1);
464 auto phi2 = std::atan2(R21 / cost2, R11 / cost2);
465 phi = std::abs(t1) <= std::abs(t2) ? phi1 : phi2;
466 }
467 else {
468 phi = 0;
469 if (R31 == -1) {
470 theta = pi / 2.0f;
471 psi = phi + atan2(R12, R13);
472 }
473 else {
474 theta = -1.0f * pi / 2.0f;
475 psi = -1 * phi + atan2(-R12, -R13);
476 }
477 }
478 return 180.0f * glm::vec3(psi,theta,phi) / (float) pi;
479}

◆ findFastMemoryType()

uint32_t findFastMemoryType ( vk::PhysicalDevice &  physicalDevice,
uint32_t  typeFilter,
vk::MemoryPropertyFlags  properties 
)

Definition at line 39 of file VulkanHelperFunction.cpp.

40{
41 vk::PhysicalDeviceMemoryProperties memProperties = physicalDevice.getMemoryProperties();
42
43 uint32_t memoryType = 0;
44 bool found = false;
45 int score = 0;
46 for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++) {
47 if ((typeFilter & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties) {
48 if (!found){
49 memoryType = i;
50 found = true;
51 }
52 else {
53 if ( ((properties & vk::MemoryPropertyFlagBits::eHostVisible) == vk::MemoryPropertyFlagBits::eHostVisible)&& (memProperties.memoryTypes[i].propertyFlags & (vk::MemoryPropertyFlagBits::eDeviceLocal | vk::MemoryPropertyFlagBits::eHostVisible))) {
54 //in general memory with device type is faster than one with eHostVisible only
55 //but it is also smaller
56 memoryType = i;
57 }
58 else if ( ((properties & vk::MemoryPropertyFlagBits::eDeviceLocal) == vk::MemoryPropertyFlagBits::eDeviceLocal)&& !(memProperties.memoryTypes[i].propertyFlags & (vk::MemoryPropertyFlagBits::eDeviceLocal | vk::MemoryPropertyFlagBits::eHostVisible))) {
59 //in general memory with device local flag is enough and can fit more
60 memoryType = i;
61 }
62 }
63 }
64 }
65 if (found) {
66 return memoryType;
67 }
68 else {
69 throw std::runtime_error("failed to find suitable memory type!");
70 }
71}

◆ findMemoryType()

uint32_t findMemoryType ( vk::PhysicalDevice &  physicalDevice,
uint32_t  typeFilter,
vk::MemoryPropertyFlags  properties 
)

Definition at line 29 of file VulkanHelperFunction.cpp.

30{
31 vk::PhysicalDeviceMemoryProperties memProperties = physicalDevice.getMemoryProperties();
32 for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++) {
33 if ((typeFilter & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties) {
34 return i;
35 }
36 }
37 throw std::runtime_error("failed to find suitable memory type!");
38}

◆ generate_picture_EBO()

std::vector< uint32_t > generate_picture_EBO ( const glm::vec2 &  s)

Definition at line 265 of file VulkanHelperFunction.cpp.

266{
267 const size_t tileSize = 4;
268 const size_t W = s[0];
269 const size_t H = s[1];
270
271 const size_t nbOfTileW = (W + tileSize - 1) / tileSize;
272 const size_t nbOfTileH = (H + tileSize - 1) / tileSize;
273
274 size_t elements_number = 3 * 2 * (H - 1) * (W - 1);
275 std::vector<uint32_t> indices;
276 indices.resize(elements_number);
277
278 size_t offset = 0;
279 const auto tileOffset = 6 * tileSize * tileSize;
280
281 for (size_t yTile = 0; yTile < nbOfTileH ; ++yTile)
282 {
283 for (size_t xTile = 0; xTile < nbOfTileW ; ++xTile)
284 {
285 auto yBase = yTile * tileSize;
286 auto xBase = xTile * tileSize;
287
288 auto currentTileOffset = offset;
289
290 for (size_t xd = 0 ; xd < tileSize ; xd++) {
291 for (size_t yd = 0 ; yd < tileSize ; yd++) {
292 auto x = xd + xBase;
293 auto y = yd + yBase;
294
295 auto currentTileSizeW = std::min(tileSize, W -1 - xBase);
296 if (x < W - 1 && y < H-1) {
297 indices[currentTileOffset + 6 * INDEX_E(xd, yd, (currentTileSizeW)) + 0] = uint32_t(INDEX_E(x, y, W));
298 indices[currentTileOffset + 6 * INDEX_E(xd, yd, (currentTileSizeW)) + 1] = uint32_t(INDEX_E(x + 1, y, W));
299 indices[currentTileOffset + 6 * INDEX_E(xd, yd, (currentTileSizeW)) + 2] = uint32_t(INDEX_E(x, y + 1, W));
300
301 indices[currentTileOffset + 6 * INDEX_E(xd, yd, (currentTileSizeW)) + 3] = uint32_t(INDEX_E(x, y + 1, W));
302 indices[currentTileOffset + 6 * INDEX_E(xd, yd, (currentTileSizeW)) + 4] = uint32_t(INDEX_E(x + 1, y, W));
303 indices[currentTileOffset + 6 * INDEX_E(xd, yd, (currentTileSizeW)) + 5] = uint32_t(INDEX_E(x + 1, y + 1, W));
304
305 offset += 6;
306 }
307 }
308 }
309 }
310 }
311
312 printf("Real number of elements %i\n", int(elements_number));
313 return indices;
314}

◆ glmEulerAnglesDegreeToRotationMatrix()

glm::mat3x3 glmEulerAnglesDegreeToRotationMatrix ( glm::vec3  rotationDegrees)

Get rotation as a matrix

Definition at line 131 of file helpersSynthesis.cpp.

132{
133 // /!\ should be in rad !!!!!!!!!!!!!!!
134 //for rotation in OMAF
135 auto const radperdeg = 0.01745329252f;
136 auto rotation = radperdeg * rotationDegrees;
137 return
138 glmRotationMatrixFromRotationAroundZ(rotation[0]) *
139 glmRotationMatrixFromRotationAroundY(rotation[1]) *
140 glmRotationMatrixFromRotationAroundX(rotation[2]);
141}

◆ glmEulerAnglesDegreeToRotationMatrixNotOMAF()

glm::mat3x3 glmEulerAnglesDegreeToRotationMatrixNotOMAF ( glm::vec3  rotationDegrees)

Get a matrix (from euler angles in openxr) NOT OMAF !

Definition at line 143 of file helpersSynthesis.cpp.

144{
145 // /!\ should be in degree !!!!!!!!!!!!!!!
146 // not for OMAF !!!!
147 auto const radperdeg = 0.01745329252f;
148 auto rotation = radperdeg * rotationDegrees;
149 return glmRotationMatrixFromRotationAroundZ(rotation[2]) *
150 glmRotationMatrixFromRotationAroundY(rotation[1]) *
151 glmRotationMatrixFromRotationAroundX(rotation[0]);
152}

◆ quatToEuler()

glm::vec3 quatToEuler ( glm::quat  q)

Definition at line 495 of file VulkanHelperFunction.cpp.

495 {
496 //for eulerInOpenXRSpace
497 glm::vec3 out = {0,0,0};
498
499 //roll
500 double siny_cosp = 2 * (q.w * q.z + q.x * q.y);
501 double cosy_cosp = 1 - 2 * (q.y * q.y + q.z * q.z);
502 out[2] = std::atan2(siny_cosp, cosy_cosp) * (180.0 / M_PI);
503
504 // pitch
505 double sinp = 2 * (q.w * q.y - q.z * q.x);
506 if (std::abs(sinp) >= 1) {
507 out[1] = std::copysign(M_PI / 2, sinp) * (180.0 / M_PI); // use 90 degrees if out of range
508 }
509 else {
510 //rotationsOMAF[view][2] = std::asin(sinp) * (180.0 / M_PI);
511 out[1] = std::asin(sinp) * (180.0 / M_PI);
512 }
513
514 // Roll
515 double sinr_cosp = 2 * (q.w * q.x + q.y * q.z);
516 double cosr_cosp = 1 - 2 * (q.x * q.x + q.y * q.y);
517 //rotationsOMAF[view][1] = -1 * std::atan2(sinr_cosp, cosr_cosp) * (180.0 / M_PI);
518 out[0] = std::atan2(sinr_cosp, cosr_cosp) * (180.0 / M_PI);
519
520 return out;
521}

◆ transitionImageLayout()

void transitionImageLayout ( VulkanContext context,
vk::CommandPool &  commandPool,
vk::Image  image,
vk::Format  format,
vk::ImageLayout  oldLayout,
vk::ImageLayout  newLayout 
)

Definition at line 139 of file VulkanHelperFunction.cpp.

140{
141 vk::CommandBuffer commandBuffer = beginSingleTimeCommands(context, commandPool);
142
143 vk::ImageAspectFlags aspectMask = vk::ImageAspectFlagBits::eColor;
144
145 if (newLayout == vk::ImageLayout::eDepthStencilAttachmentOptimal) {
146 aspectMask = vk::ImageAspectFlagBits::eDepth;
147
148 if (context->hasStencilComponent(format)) {
149 aspectMask |= vk::ImageAspectFlagBits::eStencil;
150 }
151 }
152
153 vk::ImageSubresourceRange subRessources(
154 aspectMask, //aspectMask
155 0, //baseMipLevel
156 1, //levelCount
157 0, //baseArrayLayer
158 1 //layerCount
159 );
160 vk::PipelineStageFlags sourceStage;
161 vk::PipelineStageFlags destinationStage;
162 vk::AccessFlags srcAccess;
163 vk::AccessFlags dstAccess;
164
165 if (oldLayout == vk::ImageLayout::eUndefined && newLayout == vk::ImageLayout::eTransferDstOptimal) {
166 srcAccess = {};
167 dstAccess = vk::AccessFlagBits::eTransferWrite;
168
169 sourceStage = vk::PipelineStageFlagBits::eTopOfPipe;
170 destinationStage = vk::PipelineStageFlagBits::eTransfer;
171 }
172 else if (oldLayout == vk::ImageLayout::eTransferDstOptimal && newLayout == vk::ImageLayout::eShaderReadOnlyOptimal) {
173 srcAccess = vk::AccessFlagBits::eTransferWrite;
174 dstAccess = vk::AccessFlagBits::eShaderRead;
175
176 sourceStage = vk::PipelineStageFlagBits::eTransfer;
177 destinationStage = vk::PipelineStageFlagBits::eFragmentShader;
178 }
179 else if (oldLayout == vk::ImageLayout::eUndefined && newLayout == vk::ImageLayout::eShaderReadOnlyOptimal) {
180 srcAccess = {};
181 dstAccess = vk::AccessFlagBits::eShaderRead;
182
183 sourceStage = vk::PipelineStageFlagBits::eTopOfPipe;
184 destinationStage = vk::PipelineStageFlagBits::eFragmentShader;
185 }
186 else if (oldLayout == vk::ImageLayout::eUndefined && newLayout == vk::ImageLayout::eDepthStencilAttachmentOptimal) {
187 srcAccess = {};
188 dstAccess = vk::AccessFlagBits::eDepthStencilAttachmentRead | vk::AccessFlagBits::eDepthStencilAttachmentWrite;
189
190 sourceStage = vk::PipelineStageFlagBits::eTopOfPipe;
191 destinationStage = vk::PipelineStageFlagBits::eEarlyFragmentTests;
192 }
193 else if (oldLayout == vk::ImageLayout::eUndefined && newLayout == vk::ImageLayout::eColorAttachmentOptimal) {
194 //check this ?
195 srcAccess = {};
196 dstAccess = vk::AccessFlagBits::eColorAttachmentWrite;
197
198 sourceStage = vk::PipelineStageFlagBits::eTopOfPipe;
199 destinationStage = vk::PipelineStageFlagBits::eColorAttachmentOutput;
200
201 }
202 else {
203 throw std::invalid_argument("unsupported layout transition!");
204 }
205
206
207 vk::ImageMemoryBarrier barrier(
208 srcAccess, // srcAccessMask //TODO
209 dstAccess, //dstAccesMask //TODO
210 oldLayout, //oldLayout
211 newLayout, //newLayout
212 VK_QUEUE_FAMILY_IGNORED, // srcqueueFamily
213 VK_QUEUE_FAMILY_IGNORED, //dstQueueFamily
214 image, //image
215 subRessources //subressourcesRange
216 );
217 commandBuffer.pipelineBarrier(sourceStage, destinationStage, {}, 0, nullptr, 0, nullptr, 1, &barrier);
218
219
220 endSingleTimeCommands(context, commandPool, commandBuffer);
221}
bool hasStencilComponent(vk::Format format)