Advertisement
Guest User

Untitled

a guest
Aug 12th, 2019
138
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include "stardustqt3doffscreen.h"
  2.  
  3. StardustQt3DOffscreen::StardustQt3DOffscreen(QObject *parent) : QObject(parent) {
  4.  
  5. }
  6.  
  7. void StardustQt3DOffscreen::initialize() {
  8.     //Get the render size from OpenXRGraphics
  9.     eyeDimensions = graphics->eyeDimensions;
  10.  
  11.     //Create the cameras
  12.     leftEyeEngine = new OffscreenEngine(leftEye, eyeDimensions);
  13.     rightEyeEngine = new OffscreenEngine(rightEye, eyeDimensions);
  14.  
  15.     //Add the scene root to be rendered to each eye
  16.     leftEyeEngine->setSceneRoot(sceneRoot);
  17.     rightEyeEngine->setSceneRoot(sceneRoot);
  18.  
  19.     //Create the frameAction and connect it to capturing the frames
  20.     frameAction = new Qt3DLogic::QFrameAction(sceneRoot);
  21.     connect(frameAction, &Qt3DLogic::QFrameAction::triggered, this, &StardustQt3DOffscreen::captureFrames);
  22. }
  23.  
  24. void StardustQt3DOffscreen::captureFrames(float dt) {
  25.     Q_UNUSED(dt);
  26. //    if(leftEyeCapture != nullptr)
  27. //        delete leftEyeCapture;
  28. //    if(rightEyeCapture != nullptr)
  29. //        delete rightEyeCapture;
  30.  
  31.     leftEyeCapture = leftEyeEngine->getRenderCapture()->requestCapture();
  32.     rightEyeCapture = rightEyeEngine->getRenderCapture()->requestCapture();
  33.     connect(leftEyeCapture, &Qt3DRender::QRenderCaptureReply::completed, this, &StardustQt3DOffscreen::onLeftEyeFrameRendered);
  34.     connect(rightEyeCapture, &Qt3DRender::QRenderCaptureReply::completed, this, &StardustQt3DOffscreen::onRightEyeFrameRendered);
  35. }
  36.  
  37. void StardustQt3DOffscreen::onFrameRendered(Qt3DRender::QRenderCaptureReply *capture, VkImage *image) {
  38.     VkCommandBuffer commandBuffer = beginSingleTimeCommands();
  39.     VkBuffer stagingBuffer;
  40.     VkDeviceMemory stagingBufferMemory;
  41.     VkDeviceSize imageSize = eyeDimensions.width()*eyeDimensions.height()*4;
  42.     VkMemoryRequirements memRequirements;
  43.  
  44.     createBuffer(imageSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, stagingBuffer, stagingBufferMemory, memRequirements);
  45.  
  46.     capture->image().convertTo(QImage::Format_RGB888);
  47.  
  48.     const int align_mod = memRequirements.size % memRequirements.alignment;
  49.     const int aligned_size = ((memRequirements.size % memRequirements.alignment) == 0)
  50.                              ? memRequirements.size
  51.                              : (memRequirements.size + memRequirements.alignment - align_mod);
  52.  
  53.     uint imgData[imageSize];
  54.  
  55.     void* data;
  56.     vkMapMemory(graphics->openxr->vulkan->device, stagingBufferMemory, 0, aligned_size, 0, &data);
  57.         memcpy(data, &imgData, imageSize);
  58.     vkUnmapMemory(graphics->openxr->vulkan->device, stagingBufferMemory);
  59.  
  60.     void* outData;
  61.     vkMapMemory(graphics->openxr->vulkan->device, stagingBufferMemory, 0, imageSize, 0, &outData);
  62.  
  63.     vkUnmapMemory(graphics->openxr->vulkan->device, stagingBufferMemory);
  64.  
  65.     VkBufferImageCopy region = {};
  66.     region.bufferOffset = 0;
  67.     region.bufferRowLength = 0;
  68.     region.bufferImageHeight = 0;
  69.  
  70.     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
  71.     region.imageSubresource.mipLevel = 0;
  72.     region.imageSubresource.baseArrayLayer = 0;
  73.     region.imageSubresource.layerCount = 1;
  74.  
  75.     region.imageOffset = {0, 0, 0};
  76.     region.imageExtent = graphics->vulkanImageTemplateInfo.extent;
  77.  
  78.     vkCmdCopyBufferToImage(
  79.         commandBuffer,
  80.         stagingBuffer,
  81.         *image,
  82.         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
  83.         1,
  84.         &region
  85.     );
  86.  
  87.     endSingleTimeCommands(commandBuffer);
  88.  
  89.     VkSubmitInfo submitInfo = {
  90.         VK_STRUCTURE_TYPE_SUBMIT_INFO,
  91.         nullptr
  92.     };
  93.     submitInfo.commandBufferCount = 1;
  94.     submitInfo.pCommandBuffers = &commandBuffer;
  95.  
  96.     vkQueueSubmit(*graphics->openxr->vulkan->queue, 1, &submitInfo, VK_NULL_HANDLE);
  97.     vkQueueWaitIdle(*graphics->openxr->vulkan->queue);
  98. }
  99.  
  100. void StardustQt3DOffscreen::onLeftEyeFrameRendered() {
  101.     onFrameRendered(leftEyeCapture, graphics->leftEyeImage);
  102. }
  103.  
  104. void StardustQt3DOffscreen::onRightEyeFrameRendered() {
  105.     onFrameRendered(rightEyeCapture, graphics->leftEyeImage);
  106. }
  107.  
  108. VkCommandBuffer StardustQt3DOffscreen::beginSingleTimeCommands() {
  109.     VkCommandBufferAllocateInfo allocInfo = {};
  110.     allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
  111.     allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
  112.     allocInfo.commandPool = graphics->openxr->vulkan->pool;
  113.     allocInfo.commandBufferCount = 1;
  114.  
  115.     VkCommandBuffer commandBuffer;
  116.     vkAllocateCommandBuffers(graphics->openxr->vulkan->device, &allocInfo, &commandBuffer);
  117.  
  118.     VkCommandBufferBeginInfo beginInfo = {};
  119.     beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
  120.     beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
  121.  
  122.     vkBeginCommandBuffer(commandBuffer, &beginInfo);
  123.  
  124.     return commandBuffer;
  125. }
  126. void StardustQt3DOffscreen::createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer& buffer, VkDeviceMemory& bufferMemory, VkMemoryRequirements& memRequirements) {
  127.     VkBufferCreateInfo bufferInfo = {};
  128.     bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
  129.     bufferInfo.size = size;
  130.     bufferInfo.usage = usage;
  131.     bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
  132.  
  133.     if (vkCreateBuffer(graphics->openxr->vulkan->device, &bufferInfo, nullptr, &buffer) != VK_SUCCESS) {
  134.         throw std::runtime_error("failed to create buffer!");
  135.     }
  136.  
  137.     vkGetBufferMemoryRequirements(graphics->openxr->vulkan->device, buffer, &memRequirements);
  138.  
  139.     const int align_mod = memRequirements.size % memRequirements.alignment;
  140.     const int aligned_size = ((memRequirements.size % memRequirements.alignment) == 0)
  141.                              ? memRequirements.size
  142.                              : (memRequirements.size + memRequirements.alignment - align_mod);
  143.  
  144.     VkMemoryAllocateInfo allocInfo = {};
  145.     allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
  146.     allocInfo.allocationSize = aligned_size;
  147.     allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, properties);
  148.  
  149.     if (vkAllocateMemory(graphics->openxr->vulkan->device, &allocInfo, nullptr, &bufferMemory) != VK_SUCCESS) {
  150.         throw std::runtime_error("failed to allocate buffer memory!");
  151.     }
  152.  
  153.     VkResult result = vkBindBufferMemory(graphics->openxr->vulkan->device, buffer, bufferMemory, 0);
  154. }
  155.  
  156. uint32_t StardustQt3DOffscreen::findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties) {
  157.     VkPhysicalDeviceMemoryProperties memProperties;
  158.     vkGetPhysicalDeviceMemoryProperties(graphics->openxr->vulkan->physicalDevice, &memProperties);
  159.     for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++) {
  160.         if ((typeFilter & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties) {
  161.             return i;
  162.         }
  163.     }
  164. }
  165.  
  166. void StardustQt3DOffscreen::endSingleTimeCommands(VkCommandBuffer commandBuffer) {
  167.     vkEndCommandBuffer(commandBuffer);
  168.  
  169.     VkSubmitInfo submitInfo = {};
  170.     submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
  171.     submitInfo.commandBufferCount = 1;
  172.     submitInfo.pCommandBuffers = &commandBuffer;
  173.  
  174.     vkQueueSubmit(*graphics->openxr->vulkan->queue, 1, &submitInfo, VK_NULL_HANDLE);
  175.     vkQueueWaitIdle(*graphics->openxr->vulkan->queue);
  176.  
  177.     vkFreeCommandBuffers(graphics->openxr->vulkan->device, graphics->openxr->vulkan->pool, 1, &commandBuffer);
  178. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement