17#include"VulkanRenderPassAbstract.h"
21#include"../WindowAbstract.h"
23#include"InputProvider.h"
26static const char* kTAG =
"drawing";
28 ((void)__android_log_print(ANDROID_LOG_INFO, kTAG, __VA_ARGS__))
36 this->context = context;
37 this->renderPass = renderPass;
38 this->window = window;
39 this->wrapper = wraps;
45 this->inputProvider = inputProvider;
47 for(
int i = 0 ; i < viewNumber; i++){
48 currentFrame.push_back(0);
52 createCommandBuffers();
61 for (
int view = 0; view < viewNumber; view++) {
70 for (
size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
71 if (i < wrapper->getAttachmentSize()) {
74 context->
device.destroyFence(inFlightFences[view][i]);
82 inFlightFences.clear();
83 imagesInFlight.clear();
88 context->
device.destroyCommandPool(commandPool);
89 commandBuffers.clear();
94vk::Fence
VulkanDrawing::submitDrawCall(std::tuple<int , uint32_t> idImage,
const std::vector<vk::Semaphore> & imageAvailableSemaphores, std::vector<vk::Semaphore> & signalSemaphore, uint32_t depthIndex) {
98 std::tie(view, imageIndex) = idImage;
99 currentFrame[view] = imageIndex;
103 context->
device.waitForFences(1, &inFlightFences[view][currentFrame[view]],
true, UINT64_MAX);
109 renderPass->
updateBuffer(imageIndex,
true, streamFrameInfos,view);
112 commandBuffers[view][imageIndex].reset(vk::CommandBufferResetFlagBits::eReleaseResources);
113 recordCommandBuffers(commandBuffers[view][imageIndex], view, imageIndex, streamFrameInfos);
116 if (imagesInFlight[view][imageIndex].has_value()) {
117 context->
device.waitForFences(1, &imagesInFlight[view][imageIndex].value(),
true, UINT64_MAX);
120 imagesInFlight[view][imageIndex] = inFlightFences[view][currentFrame[view]];
123 vk::PipelineStageFlags waitDestinationStageMask(vk::PipelineStageFlagBits::eColorAttachmentOutput);
124 context->
device.resetFences(1, &inFlightFences[view][currentFrame[view]]);
126 uint32_t semSize = imageAvailableSemaphores.size();
127 vk::SubmitInfo submitInfo(
129 semSize > 0 ? imageAvailableSemaphores.data() :
nullptr,
130 semSize > 0 ? &waitDestinationStageMask :
nullptr,
132 &commandBuffers[view][imageIndex],
133 static_cast<uint32_t
>(signalSemaphore.size()),
134 signalSemaphore.size() == 0 ?
nullptr : signalSemaphore.data()
136 context->
graphicsQueue.submit(submitInfo, inFlightFences[view][currentFrame[view]]);
139 vk::SubmitInfo submitInfo(
144 &commandBuffers[view][imageIndex],
148 context->
graphicsQueue.submit(submitInfo, inFlightFences[view][currentFrame[view]]);
150 const uint32_t timeoutNs = 1 * 1000 * 1000 * 1000;
151 for (
int i = 0; i < 5; ++i) {
152 auto res = context->
device.waitForFences(1, &inFlightFences[view][currentFrame[view]], VK_TRUE, timeoutNs);
153 if (res == vk::Result::eSuccess) {
157 std::cout <<
"Waiting for CmdBuffer fence timed out, retrying..." << std::endl;
162 inputProvider->releaseStreamsFrames();
173 return inFlightFences[view][currentFrame[view]];
182void VulkanDrawing::createCommandPool()
187 vk::CommandPoolCreateFlags flags = vk::CommandPoolCreateFlags();
189 flags = vk::CommandPoolCreateFlagBits::eResetCommandBuffer;
191 vk::CommandPoolCreateInfo commandPoolInfo(flags, queueFamilyIndices.
graphicsFamily.value());
192 commandPool = context->
device.createCommandPool(commandPoolInfo);
195void VulkanDrawing::createCommandBuffers()
197 commandBuffers.resize(viewNumber);
199 for(
int view = 0; view < viewNumber; view++) {
200 vk::CommandBufferAllocateInfo commandBufferInfo(commandPool,
201 vk::CommandBufferLevel::ePrimary,
204 commandBuffers[view] = context->
device.allocateCommandBuffers(commandBufferInfo);
207 for (
int i = 0; i < commandBuffers[view].size(); i++) {
208 auto name =
"cmdBuff Draw v: " + std::to_string(view) +
" " + std::to_string(i);
209 vk::DebugUtilsObjectNameInfoEXT debug(vk::ObjectType::eCommandBuffer, (uint64_t)
static_cast<VkCommandBuffer
>(commandBuffers[view][i]), name.c_str());
210 context->
device.setDebugUtilsObjectNameEXT(debug);
218void VulkanDrawing::recordCommandBuffers(vk::CommandBuffer& buff,
int view ,
int i, std::span<InputProvider::StreamFrameInfo> frameInfos)
221 buff.begin(vk::CommandBufferBeginInfo(vk::CommandBufferUsageFlags()));
226 vk::ImageAspectFlags aspectMask = vk::ImageAspectFlagBits::eColor;
227 vk::ImageSubresourceRange subRessources(
235 vk::ImageSubresourceLayers srcRes(vk::ImageAspectFlagBits::eColor, 0, 0, 1);
236 vk::ImageSubresourceLayers dstRes(vk::ImageAspectFlagBits::eColor, 0, 0, 1);
240 std::array<vk::Offset3D, 2> offsetSrc = { vk::Offset3D(0, 0, 0),
243 vk::Offset3D(sourceWidth,sourceHeight,1) };
246 if (!renderDirectlyToSwapchain) {
257 double minRatio = std::min(wRatio, hRatio);
258 uint32_t newH = minRatio * sourceHeight;
259 uint32_t newW = minRatio * sourceWidth;
267 std::array<vk::Offset3D, 2> offsetDst = { vk::Offset3D(0, 0, 0),
268 vk::Offset3D(newW, newH, 1) };
277 vk::ImageMemoryBarrier barrierBeforeBlit(
279 vk::AccessFlagBits::eTransferWrite,
280 vk::ImageLayout::eUndefined,
281 vk::ImageLayout::eTransferDstOptimal,
282 VK_QUEUE_FAMILY_IGNORED,
283 VK_QUEUE_FAMILY_IGNORED,
287 buff.pipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe,
288 vk::PipelineStageFlagBits::eTransfer, {}, 0,
nullptr,
289 0,
nullptr, 1, &barrierBeforeBlit);
291 vk::ImageBlit region(srcRes, offsetSrc, dstRes, offsetDst);
292 vk::ImageLayout newLayout = window->
useOpenXR() ? vk::ImageLayout::eColorAttachmentOptimal : vk::ImageLayout::ePresentSrcKHR;
310 vk::ImageLayout::eTransferSrcOptimal,
312 vk::ImageLayout::eTransferDstOptimal, region,
313 vk::Filter::eNearest);
314 vk::ImageMemoryBarrier barrier(
315 vk::AccessFlagBits::eTransferWrite,
316 vk::AccessFlagBits::eMemoryRead,
317 vk::ImageLayout::eTransferDstOptimal,
319 VK_QUEUE_FAMILY_IGNORED,
320 VK_QUEUE_FAMILY_IGNORED,
324 buff.pipelineBarrier(vk::PipelineStageFlagBits::eTransfer,
325 vk::PipelineStageFlagBits::eTopOfPipe, {}, 0,
nullptr,
326 0,
nullptr, 1, &barrier);
331 vk::ImageSubresourceLayers subRessources(
332 vk::ImageAspectFlagBits::eColor,
337 vk::BufferImageCopy region(
343 { sourceWidth,sourceHeight,1 }
347 buff.copyImageToBuffer(renderPass->
getImageToBlit(i), vk::ImageLayout::eTransferSrcOptimal, buf, 1, ®ion);
355 if (destinations.size() > 0) {
362 vk::ImageMemoryBarrier barrierSrcBeforeBlit(
364 vk::AccessFlagBits::eTransferWrite,
365 vk::ImageLayout::eUndefined,
366 vk::ImageLayout::eTransferSrcOptimal,
367 VK_QUEUE_FAMILY_IGNORED,
368 VK_QUEUE_FAMILY_IGNORED,
372 for (
int d = 0; d < destinations.size(); d++) {
373 vk::ImageMemoryBarrier barrierDstBeforeBlit(
375 vk::AccessFlagBits::eTransferWrite,
376 vk::ImageLayout::eUndefined,
377 vk::ImageLayout::eTransferDstOptimal,
378 VK_QUEUE_FAMILY_IGNORED,
379 VK_QUEUE_FAMILY_IGNORED,
383 std::array<vk::ImageMemoryBarrier, 2> barriers = { barrierSrcBeforeBlit,barrierDstBeforeBlit };
384 buff.pipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe,
385 vk::PipelineStageFlagBits::eTransfer, {}, 0,
nullptr,
386 0,
nullptr,
static_cast<uint32_t
>(barriers.size()), barriers.data());
388 double wRatio = (double)(destinationsExtents[d].width) / (sourceWidth);
389 double hRatio = (double)(destinationsExtents[d].height) / (sourceHeight);
390 double minRatio = std::min(wRatio, hRatio);
391 uint32_t newH = minRatio * sourceHeight;
392 uint32_t newW = minRatio * sourceWidth;
393 std::array<vk::Offset3D, 2> offsetDst = { vk::Offset3D(0, 0, 0),
394 vk::Offset3D(newW, newH , 1) };
395 vk::ImageBlit region(srcRes, offsetSrc, dstRes, offsetDst);
396 buff.blitImage(srcImage,
397 vk::ImageLayout::eTransferSrcOptimal,
399 vk::ImageLayout::eTransferDstOptimal, region,
400 vk::Filter::eNearest);
402 vk::ImageMemoryBarrier barrierDest(
403 vk::AccessFlagBits::eTransferWrite,
404 vk::AccessFlagBits::eMemoryRead,
405 vk::ImageLayout::eTransferDstOptimal,
406 vk::ImageLayout::ePresentSrcKHR,
407 VK_QUEUE_FAMILY_IGNORED,
408 VK_QUEUE_FAMILY_IGNORED,
412 buff.pipelineBarrier(vk::PipelineStageFlagBits::eTransfer,
413 vk::PipelineStageFlagBits::eTopOfPipe, {}, 0,
nullptr,
414 0,
nullptr, 1, &barrierDest);
418 vk::ImageMemoryBarrier barrier(
419 vk::AccessFlagBits::eTransferWrite,
420 vk::AccessFlagBits::eMemoryRead,
421 vk::ImageLayout::eTransferSrcOptimal,
422 vk::ImageLayout::eColorAttachmentOptimal,
423 VK_QUEUE_FAMILY_IGNORED,
424 VK_QUEUE_FAMILY_IGNORED,
428 buff.pipelineBarrier(vk::PipelineStageFlagBits::eTransfer,
429 vk::PipelineStageFlagBits::eTopOfPipe, {}, 0,
nullptr,
430 0,
nullptr, 1, &barrier);
435void VulkanDrawing::createSyncObjects()
452 inFlightFences.resize(viewNumber);
453 imagesInFlight.resize(viewNumber);
455 for (
int view = 0; view < viewNumber; view++) {
458 inFlightFences[view].resize(MAX_FRAMES_IN_FLIGHT);
459 imagesInFlight[view].resize(MAX_FRAMES_IN_FLIGHT, std::nullopt);
461 vk::FenceCreateInfo fenceInfo(vk::FenceCreateFlagBits::eSignaled);
463 for (
size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
466 inFlightFences[view][i] = context->
device.createFence(fenceInfo);
File that contain the VulkanContext class to manage Vulkan Instance, Physical device,...
Contains the class that manage the drawing process (manage and record command buffer,...
Class that contains helper functions for Vulkan.
file that contains the VulkanWrapper class that manages the classes related to Vulkan code and ease t...
class that manages tasks related to Vulkan context (Vulkan Instance, Vulkan Physical device,...
vk::PhysicalDevice physicalDevice
bool isIndepFromWindowDimension()
QueueFamilyIndices findQueueFamilies(vk::PhysicalDevice device)
vk::Fence submitDrawCall(std::tuple< int, uint32_t > idImage, const std::vector< vk::Semaphore > &imageAvailableSemaphores, std::vector< vk::Semaphore > &signalSemaphore, uint32_t depthIndex=UINT_MAX)
void init(InputProvider *inputProvider)
VulkanDrawing(VulkanContext *context, VulkanRenderPassAbstract *renderPass, WindowAbstract *window, VulkanWrapper *wraps)
An abstract class that contains a common base of code for the class that inherit from it.
virtual vk::Image getImageToBlit(int imageIndex)=0
virtual void recordCommandBuffer(vk::CommandBuffer &commandBuffer, int i, std::span< InputProvider::StreamFrameInfo > frameInfos, int view)
virtual void updateBuffer(uint32_t currentImage, bool initAll, std::span< InputProvider::StreamFrameInfo > infos, int view)
Class that manages the classes related to Vulkan code and act as a wrapper around them.
const std::vector< InputProvider::StreamFrameInfo > getFramesInfo(int view)
bool isDepthOutputRecquired()
vk::Extent2D getSwapchainExtend(int view=0)
Abstraction of the way of the result is displayed (screen or HMD).
virtual const bool useOpenXR()
virtual vk::Buffer getRenderingDestination()
virtual vk::Extent2D getSwapchainExtent(int view)
virtual std::vector< vk::Extent2D > getBlitExtentDestinations(int view, int elem)
virtual std::vector< vk::Image > getBlitDestinations(int view, int elem)
virtual vk::Image getSwapchainImage(int view, int index)
Struct to encapsulate the indice of the queues families.
std::optional< uint32_t > graphicsFamily