コード例 #1
0
  void GraphicsSystem::Initialize()
  {
    mVulkanSuccess = vkelInit();

    mBaseQuad.mVertex1.mPosition = { -0.5f, -0.5f, 0.0f, 1.0f };
    mBaseQuad.mVertex1.mUVCoordinates = { 0.0f, 0.0f };
    mBaseQuad.mVertex1.mNormal = { 0.0f, 0.0f, 1.0 };

    mBaseQuad.mVertex2.mPosition = { 0.5f, -0.5f, 0.0f, 1.0f };
    mBaseQuad.mVertex2.mUVCoordinates = { 1.0f, 0.0f };
    mBaseQuad.mVertex2.mNormal = { 0.0f, 0.0f, 1.0 };

    mBaseQuad.mVertex3.mPosition = { 0.5f, 0.5f, 0.0f, 1.0f };
    mBaseQuad.mVertex3.mUVCoordinates = { 1.0f, 1.0f };
    mBaseQuad.mVertex3.mNormal = { 0.0f, 0.0f, 1.0 };

    mBaseQuad.mVertex4.mPosition = { -0.5f, 0.5f, 0.0f, 1.0f };
    mBaseQuad.mVertex4.mUVCoordinates = { 0.0f, 1.0f };
    mBaseQuad.mVertex4.mNormal = { 0.0f, 0.0f, 1.0 };

    if (mVulkanSuccess)
    {
      auto self = mPlatformSpecificData.Get<VulkanContext>();

      vk::ApplicationInfo appInfo;
      appInfo.setPApplicationName("First Test");
      appInfo.setEngineVersion(1);
      appInfo.setApiVersion(VK_MAKE_VERSION(1, 0, 0));

      auto instanceInfo = vk::InstanceCreateInfo()
        .setPApplicationInfo(&appInfo);

      auto layers = vk::enumerateInstanceLayerProperties();
      vulkan_assert(layers.size(), "Failed to find layers.");

      bool foundValidator = false;

      auto validationLayer = "VK_LAYER_LUNARG_standard_validation";

      for (auto &layer : layers)
      {
        if (StringCompare(layer.layerName, validationLayer) == StringComparison::Equal)
        {
          foundValidator = true;
        }
      }

      if (foundValidator)
      {
      }

      const char *enabledLayers[] = { validationLayer };

      if (foundValidator)
      {
        #if _DEBUG
        instanceInfo.setEnabledLayerCount(1);
        instanceInfo.setPpEnabledLayerNames(enabledLayers);
        #endif
      }
      else
      {
          printf("Could not find validation layers.");
      }

      auto extensions = vk::enumerateInstanceExtensionProperties();

      std::array<const char *, 3> requiredExtensions = {
        "VK_KHR_surface",
        "VK_KHR_win32_surface",
        "VK_EXT_debug_report"
      };

      decltype(requiredExtensions)::size_type foundExtensions = 0;

      for (auto &extension : extensions)
      {
        for (auto &requiredExtension : requiredExtensions)
        {
          if (std::strcmp(extension.extensionName, requiredExtension) == 0)
          {
            ++foundExtensions;
            requiredExtension = "";
            break;
          }
        }
      }

      requiredExtensions = {
          "VK_KHR_surface",
          "VK_KHR_win32_surface",
          "VK_EXT_debug_report"
      };


      if (requiredExtensions.size() == foundExtensions)
      {
        instanceInfo.setEnabledExtensionCount((u32)requiredExtensions.size());
        instanceInfo.setPpEnabledExtensionNames(requiredExtensions.data());

        auto result = vk::createInstance(&instanceInfo, nullptr, &self->mInstance);
        checkVulkanResult(result, "Failed to create vulkan instance.");
      }
      else
      {
        printf("Could not find debug extension");
      }

      vkelInstanceInit(self->mInstance);

      if (requiredExtensions.size() == foundExtensions)
      {
        vk::DebugReportCallbackCreateInfoEXT callbackCreateInfo;
        callbackCreateInfo.setFlags(vk::DebugReportFlagBitsEXT::eError |
                                    vk::DebugReportFlagBitsEXT::eWarning |
                                    vk::DebugReportFlagBitsEXT::ePerformanceWarning);
        callbackCreateInfo.setPfnCallback(&DebugReportCallback);

        auto debugReport = self->mInstance.createDebugReportCallbackEXT(callbackCreateInfo);
        vulkan_assert(static_cast<bool>(debugReport), "Failed to create degub report callback.");
      }

      // TODO: Abstract this for multiple windows.
      auto window = mEngine->mPrimaryWindow;
      auto windowData = window->mPlatformSpecificData.Get<WindowData>();
      vk::Win32SurfaceCreateInfoKHR surfaceCreateInfo;
      surfaceCreateInfo.setHinstance(windowData->mInstance);
      surfaceCreateInfo.setHwnd(windowData->mWindowHandle);

      self->mHeight = window->mHeight;
      self->mWidth = window->mWidth;

      self->mSurface = self->mInstance.createWin32SurfaceKHR(surfaceCreateInfo);

      auto physicalDevices = self->mInstance.enumeratePhysicalDevices();

      u32 deviceCount = 0;
      for (auto &physicalDevice : physicalDevices)
      {
        auto properties = physicalDevice.getProperties();

        auto queueProperties = physicalDevice.getQueueFamilyProperties();

        printf("Device #%d: %s\n", deviceCount, properties.deviceName);

        u32 queueCount = 0;
        for (auto &queueProperty : queueProperties)
        {
          i32 supportsPresent = physicalDevice.getSurfaceSupportKHR(queueCount, self->mSurface);

          if (supportsPresent && (queueProperty.queueFlags & vk::QueueFlagBits::eGraphics))
          {
            self->mPhysicalDevice = physicalDevice;
            self->mPhysicalDeviceProperties = properties;
            self->mPresentQueueIdx = queueCount;

            ++queueCount;
            break;
          }

          ++queueCount;
          ++deviceCount;
        }


        // TODO: Maybe grab more than just one physical device?
        if (self->mPhysicalDevice)
        {
          break;
        }
      }

      vulkan_assert(self->mPhysicalDevice, "No physical device detected that can render and present!");

      self->mPhysicalMemoryProperties = self->mPhysicalDevice.getMemoryProperties();

      // info for accessing one of the devices rendering queues:
      vk::DeviceQueueCreateInfo queueCreateInfo;
      queueCreateInfo.setQueueFamilyIndex(self->mPresentQueueIdx);
      queueCreateInfo.setQueueCount(1);

      float queuePriorities[] = { 1.0f };   // ask for highest priority for our queue. (range [0,1])
      queueCreateInfo.pQueuePriorities = queuePriorities;

      const char *deviceExtensions[] = { "VK_KHR_swapchain" };

      vk::DeviceCreateInfo deviceInfo;
      deviceInfo.setQueueCreateInfoCount(1);
      deviceInfo.setPQueueCreateInfos(&queueCreateInfo);
      deviceInfo.setEnabledLayerCount(1);
      deviceInfo.setPpEnabledLayerNames(enabledLayers);
      deviceInfo.setEnabledExtensionCount(1);
      deviceInfo.setPpEnabledExtensionNames(deviceExtensions);

      auto features = vk::PhysicalDeviceFeatures().setShaderClipDistance(true);
      
      deviceInfo.setPEnabledFeatures(&features);

      self->mLogicalDevice = self->mPhysicalDevice.createDevice(deviceInfo);

      vulkan_assert(self->mLogicalDevice, "Failed to create logical device!");

      auto formats = self->mPhysicalDevice.getSurfaceFormatsKHR(self->mSurface);

      // If the format list includes just one entry of VK_FORMAT_UNDEFINED, the surface has
      // no preferred format. Otherwise, at least one supported format will be returned.
      vk::Format colorFormat;

      if (formats.size() == 1 && formats[0].format == vk::Format::eUndefined)
      {
        colorFormat = vk::Format::eB8G8R8Unorm;
      }
      else 
      {
        colorFormat = formats[0].format;
      }

      vk::ColorSpaceKHR colorSpace;
      colorSpace = formats[0].colorSpace;

      vk::SurfaceCapabilitiesKHR surfaceCapabilities = self->mPhysicalDevice.getSurfaceCapabilitiesKHR(self->mSurface);

      // We are effectively looking for double-buffering:
      // if surfaceCapabilities.maxImageCount == 0 there is actually no limit on the number of images! 
      //
      // TODO: Make the amount of buffering configurable.
      u32 desiredImageCount = 2;

      if (desiredImageCount < surfaceCapabilities.minImageCount) 
      {
        desiredImageCount = surfaceCapabilities.minImageCount;
      }
      else if ((surfaceCapabilities.maxImageCount != 0) && (desiredImageCount > surfaceCapabilities.maxImageCount)) 
      {
        desiredImageCount = surfaceCapabilities.maxImageCount;
      }

      vk::Extent2D surfaceResolution = surfaceCapabilities.currentExtent;

      if (surfaceResolution.width == -1) 
      {
        surfaceResolution.width = self->mWidth;
        surfaceResolution.height = self->mHeight;
      }
      else 
      {
        self->mWidth = surfaceResolution.width;
        self->mHeight = surfaceResolution.height;
      }

      vk::SurfaceTransformFlagBitsKHR preTransform = surfaceCapabilities.currentTransform;

      if (surfaceCapabilities.supportedTransforms & vk::SurfaceTransformFlagBitsKHR::eIdentity)
      {
        preTransform = vk::SurfaceTransformFlagBitsKHR::eIdentity;
      }

      auto presentModes = self->mPhysicalDevice.getSurfacePresentModesKHR(self->mSurface);

      // Always supported.
      vk::PresentModeKHR presentationMode = vk::PresentModeKHR::eFifo;

      // TODO: Look into the rest of the vk::PresentModeKHR options.
      for (auto &presentMode : presentModes) 
      {
          // This is what we'd prefer.
        if (presentMode == vk::PresentModeKHR::eMailbox)
        {
          presentationMode = vk::PresentModeKHR::eMailbox;
          break;
        }
          // We'll take this if Mailbox isn't available.
        else if (presentMode == vk::PresentModeKHR::eFifoRelaxed)
        {
          presentationMode = vk::PresentModeKHR::eFifoRelaxed;
        }
      }

      vk::SwapchainCreateInfoKHR swapChainCreateInfo;
      swapChainCreateInfo.setSurface(self->mSurface);
      swapChainCreateInfo.setMinImageCount(desiredImageCount);
      swapChainCreateInfo.setImageFormat(colorFormat);
      swapChainCreateInfo.setImageColorSpace(colorSpace);
      swapChainCreateInfo.setImageExtent(surfaceResolution);
      swapChainCreateInfo.setImageArrayLayers(1);
      swapChainCreateInfo.setImageUsage(vk::ImageUsageFlagBits::eColorAttachment);
      swapChainCreateInfo.setImageSharingMode(vk::SharingMode::eExclusive);   // TODO: Learn how to share queues.
      swapChainCreateInfo.setPreTransform(preTransform);
      swapChainCreateInfo.setCompositeAlpha(vk::CompositeAlphaFlagBitsKHR::eOpaque); //TODO: Pretty sure we want to do pre-multiplied.
      swapChainCreateInfo.setPresentMode(presentationMode);
      swapChainCreateInfo.setClipped(true); // If we want clipping outside the extents
                                            // (remember our device features?)

      self->mSwapChain = self->mLogicalDevice.createSwapchainKHR(swapChainCreateInfo);
      vulkan_assert(self->mSwapChain, "Failed to create swapchain.");

      self->mQueue = self->mLogicalDevice.getQueue(self->mPresentQueueIdx, 0);

      vk::CommandPoolCreateInfo commandPoolCreateInfo;
      commandPoolCreateInfo.setFlags(vk::CommandPoolCreateFlagBits::eResetCommandBuffer);
      commandPoolCreateInfo.setQueueFamilyIndex(self->mPresentQueueIdx);

      self->mCommandPool = self->mLogicalDevice.createCommandPool(commandPoolCreateInfo);
      vulkan_assert(self->mCommandPool, "Failed to create command pool.");

      vk::CommandBufferAllocateInfo commandBufferAllocationInfo;
      commandBufferAllocationInfo.setCommandPool(self->mCommandPool);
      commandBufferAllocationInfo.setLevel(vk::CommandBufferLevel::ePrimary);
      commandBufferAllocationInfo.setCommandBufferCount(1);

      self->mSetupCommandBuffer = self->mLogicalDevice.allocateCommandBuffers(commandBufferAllocationInfo)[0];
      vulkan_assert(self->mSetupCommandBuffer, "Failed to allocate setup command buffer.");

      self->mPresentImages = self->mLogicalDevice.getSwapchainImagesKHR(self->mSwapChain);

      commandBufferAllocationInfo.commandBufferCount = static_cast<u32>(self->mPresentImages.size());
      self->mDrawCommandBuffers = self->mLogicalDevice.allocateCommandBuffers(commandBufferAllocationInfo);
      vulkan_assert(self->mDrawCommandBuffers.size(), "Failed to allocate draw command buffer.");

      vk::ImageViewCreateInfo presentImagesViewCreateInfo;
      presentImagesViewCreateInfo.setViewType(vk::ImageViewType::e2D);
      presentImagesViewCreateInfo.setFormat(colorFormat);
      presentImagesViewCreateInfo.setFlags((vk::ImageViewCreateFlagBits)0);
      presentImagesViewCreateInfo.setComponents({ vk::ComponentSwizzle::eR,
                                                  vk::ComponentSwizzle::eG,
                                                  vk::ComponentSwizzle::eB,
                                                  vk::ComponentSwizzle::eA });

      presentImagesViewCreateInfo.subresourceRange.setAspectMask(vk::ImageAspectFlagBits::eColor);
      presentImagesViewCreateInfo.subresourceRange.setLevelCount(1);
      presentImagesViewCreateInfo.subresourceRange.setLayerCount(1);

      vk::ImageCreateInfo imageCreateInfo;
      imageCreateInfo.setImageType(vk::ImageType::e2D);
      imageCreateInfo.setFormat(vk::Format::eD32SfloatS8Uint);
      imageCreateInfo.setExtent({ self->mWidth, self->mHeight, 1 });
      imageCreateInfo.setMipLevels(1);
      imageCreateInfo.setArrayLayers(1);
      imageCreateInfo.setSamples(vk::SampleCountFlagBits::e1);
      imageCreateInfo.setTiling(vk::ImageTiling::eOptimal);
      imageCreateInfo.setUsage(vk::ImageUsageFlagBits::eDepthStencilAttachment);
      imageCreateInfo.setSharingMode(vk::SharingMode::eExclusive); // TODO: Change this when you learn more.
      imageCreateInfo.setInitialLayout(vk::ImageLayout::eUndefined);

      self->mDepthImage = self->mLogicalDevice.createImage(imageCreateInfo);

      vulkan_assert(self->mDepthImage, "Failed to create depth image.");

      auto memoryRequirements = self->mLogicalDevice.getImageMemoryRequirements(self->mDepthImage);
      auto imageAllocationInfo = vk::MemoryAllocateInfo().setAllocationSize(memoryRequirements.size);

      // memoryTypeBits is a bitfield where if bit i is set, it means that 
      // the VkMemoryType i of the VkPhysicalDeviceMemoryProperties structure 
      // satisfies the memory requirements:
      u32 memoryTypeBits = memoryRequirements.memoryTypeBits;
      vk::MemoryPropertyFlags desiredMemoryFlags = vk::MemoryPropertyFlagBits::eDeviceLocal;
      for (u32 i = 0; i < 32; ++i)
      {
        vk::MemoryType memoryType = self->mPhysicalMemoryProperties.memoryTypes[i];
        if (memoryTypeBits & 1)
        {
          if ((memoryType.propertyFlags & desiredMemoryFlags) == desiredMemoryFlags)
          {
            imageAllocationInfo.memoryTypeIndex = i;
            break;
          }
        }
        memoryTypeBits = memoryTypeBits >> 1;
      }

      auto imageMemory = self->mLogicalDevice.allocateMemory(imageAllocationInfo);
      self->mLogicalDevice.bindImageMemory(self->mDepthImage, imageMemory, 0);

      auto beginInfo = vk::CommandBufferBeginInfo().setFlags(vk::CommandBufferUsageFlagBits::eOneTimeSubmit);

      auto submitFence = self->mLogicalDevice.createFence(vk::FenceCreateInfo());

      std::vector<bool> transitioned;
      transitioned.resize(self->mPresentImages.size(), false);

      // This sets the image layout on the images.
      u32 doneCount = 0;
      while (doneCount != self->mPresentImages.size())
      {
        vk::SemaphoreCreateInfo semaphoreCreateInfo;
        vk::Semaphore presentCompleteSemaphore = self->mLogicalDevice.createSemaphore(semaphoreCreateInfo);
      
        u32 nextImageIdx;
        auto result = self->mLogicalDevice.acquireNextImageKHR(self->mSwapChain, UINT64_MAX, presentCompleteSemaphore, VK_NULL_HANDLE, &nextImageIdx);
        checkVulkanResult(result, "Could not acquireNextImageKHR.");
      
        if (!transitioned.at(nextImageIdx))
        {
          // start recording out image layout change barrier on our setup command buffer:
          self->mSetupCommandBuffer.begin(&beginInfo);
      
          vk::ImageMemoryBarrier layoutTransitionBarrier;
          layoutTransitionBarrier.setDstAccessMask(vk::AccessFlagBits::eMemoryRead);
          layoutTransitionBarrier.setOldLayout(vk::ImageLayout::eUndefined);
          layoutTransitionBarrier.setNewLayout(vk::ImageLayout::ePresentSrcKHR);
          layoutTransitionBarrier.setSrcQueueFamilyIndex(VK_QUEUE_FAMILY_IGNORED);
          layoutTransitionBarrier.setDstQueueFamilyIndex(VK_QUEUE_FAMILY_IGNORED);
          layoutTransitionBarrier.setImage(self->mPresentImages[nextImageIdx]);
      
          vk::ImageSubresourceRange resourceRange = { vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 };
          layoutTransitionBarrier.setSubresourceRange(resourceRange);
          vk::ClearColorValue clear;
          clear.setFloat32( { 0.0f, 0.0f, 0.0f, 1.0f });
          self->mSetupCommandBuffer.clearColorImage(self->mPresentImages[nextImageIdx],
                                                    vk::ImageLayout::eTransferDstOptimal,
                                                    clear,
                                                    resourceRange);
      
          self->mSetupCommandBuffer.pipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, 
                                                    vk::PipelineStageFlagBits::eTopOfPipe, 
                                                    vk::DependencyFlags(),
                                                    nullptr, 
                                                    nullptr,
                                                    layoutTransitionBarrier);
      
          self->mSetupCommandBuffer.end();
      
          vk::PipelineStageFlags waitStageMash[] = { vk::PipelineStageFlagBits::eColorAttachmentOutput };
          vk::SubmitInfo submitInfo;
          submitInfo.setWaitSemaphoreCount(1);
          submitInfo.setPWaitSemaphores(&presentCompleteSemaphore);
          submitInfo.setPWaitDstStageMask(waitStageMash);
          submitInfo.setCommandBufferCount(1);
          submitInfo.setPCommandBuffers(&self->mSetupCommandBuffer);
      
          self->mQueue.submit(submitInfo, submitFence);
          
          self->mLogicalDevice.waitForFences(submitFence, true, UINT64_MAX);
          self->mLogicalDevice.resetFences(submitFence);
      
          self->mLogicalDevice.destroySemaphore(presentCompleteSemaphore);
      
          // NOTE: Instead of eReleaseResources should it be 0?
          self->mSetupCommandBuffer.reset(vk::CommandBufferResetFlagBits::eReleaseResources);
      
          transitioned[nextImageIdx] = true;
          ++doneCount;
        }

        // TODO: Fix the issue where we present without writing to the images.
        auto presentInfo = vk::PresentInfoKHR()
                                .setSwapchainCount(1)
                                .setPSwapchains(&self->mSwapChain)
                                .setPImageIndices(&nextImageIdx);
        
        self->mQueue.presentKHR(presentInfo);
      }


      self->mPresentImageViews = std::vector<vk::ImageView>(self->mPresentImages.size(), vk::ImageView());

      for (uint32_t i = 0; i < self->mPresentImages.size(); ++i)
      {
        presentImagesViewCreateInfo.image = self->mPresentImages[i];

        self->mPresentImageViews[i] = self->mLogicalDevice.createImageView(presentImagesViewCreateInfo);

        vulkan_assert(self->mPresentImageViews[i], "Could not create ImageView.");
      }

      namespace fs = std::experimental::filesystem;

      TextureLoader loader(self->mPhysicalDevice, self->mLogicalDevice, self->mQueue, self->mCommandPool);

      u32 i = 0;
      for (auto& file : fs::directory_iterator(L"./Textures"))
      {
        std::string texturePath = file.path().string();
        self->mTextures.emplace_back(loader.loadTexture(texturePath));
      }

      self->mSetupCommandBuffer.begin(beginInfo);
      vk::ImageMemoryBarrier layoutTransitionBarrier;
      layoutTransitionBarrier.setDstAccessMask(vk::AccessFlagBits::eDepthStencilAttachmentRead |
                                               vk::AccessFlagBits::eDepthStencilAttachmentWrite);
      layoutTransitionBarrier.setOldLayout(vk::ImageLayout::eUndefined);
      layoutTransitionBarrier.setNewLayout(vk::ImageLayout::eDepthStencilAttachmentOptimal);
      layoutTransitionBarrier.setSrcQueueFamilyIndex(VK_QUEUE_FAMILY_IGNORED);
      layoutTransitionBarrier.setDstQueueFamilyIndex(VK_QUEUE_FAMILY_IGNORED);
      layoutTransitionBarrier.setImage(self->mDepthImage);

      auto resourceRange = vk::ImageSubresourceRange(vk::ImageAspectFlagBits::eDepth | vk::ImageAspectFlagBits::eStencil, 0, 1, 0, 1);

      layoutTransitionBarrier.setSubresourceRange(resourceRange);

      self->mSetupCommandBuffer.pipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe,
                                                vk::PipelineStageFlagBits::eTopOfPipe,
                                                vk::DependencyFlags(),
                                                nullptr,
                                                nullptr,
                                                layoutTransitionBarrier);

      self->mSetupCommandBuffer.end();

      vk::PipelineStageFlags waitStageMask[] = { vk::PipelineStageFlagBits::eColorAttachmentOutput };
      vk::SubmitInfo submitInfo;
      submitInfo.setPWaitDstStageMask(waitStageMask);
      submitInfo.setCommandBufferCount(1);
      submitInfo.setPCommandBuffers(&self->mSetupCommandBuffer);

      self->mQueue.submit(submitInfo, submitFence);

      self->mLogicalDevice.waitForFences(submitFence, true, UINT64_MAX);
      self->mLogicalDevice.resetFences(submitFence);

      // NOTE: Instead of eReleaseResources should it be 0?
      self->mSetupCommandBuffer.reset(vk::CommandBufferResetFlagBits::eReleaseResources);

      vk::ImageAspectFlags aspectMask = vk::ImageAspectFlagBits::eDepth | vk::ImageAspectFlagBits::eStencil;
      vk::ImageViewCreateInfo imageViewCreateInfo;
      imageViewCreateInfo.setImage(self->mDepthImage);
      imageViewCreateInfo.setViewType(vk::ImageViewType::e2D);
      imageViewCreateInfo.setFormat(imageCreateInfo.format);
      imageViewCreateInfo.setComponents({ vk::ComponentSwizzle::eIdentity,
                                          vk::ComponentSwizzle::eIdentity,
                                          vk::ComponentSwizzle::eIdentity ,
                                          vk::ComponentSwizzle::eIdentity });
      imageViewCreateInfo.setSubresourceRange(vk::ImageSubresourceRange(aspectMask, 0, 1, 0, 1));

      self->mDepthImageView = self->mLogicalDevice.createImageView(imageViewCreateInfo);

      vulkan_assert(self->mDepthImageView, "Failed to create image view.");

      std::array<vk::AttachmentDescription, 2> passAttachments = {};
      passAttachments[0].format = colorFormat;
      passAttachments[0].samples = vk::SampleCountFlagBits::e1;
      passAttachments[0].loadOp = vk::AttachmentLoadOp::eClear;
      passAttachments[0].storeOp = vk::AttachmentStoreOp::eStore;
      passAttachments[0].stencilLoadOp = vk::AttachmentLoadOp::eDontCare;
      passAttachments[0].stencilStoreOp = vk::AttachmentStoreOp::eDontCare;
      passAttachments[0].initialLayout = vk::ImageLayout::eColorAttachmentOptimal;
      passAttachments[0].finalLayout = vk::ImageLayout::eColorAttachmentOptimal;

      //passAttachments[1].format = vk::Format::eD16Unorm;
      passAttachments[1].format = vk::Format::eD32SfloatS8Uint;
      passAttachments[1].samples = vk::SampleCountFlagBits::e1;
      passAttachments[1].loadOp = vk::AttachmentLoadOp::eClear;
      passAttachments[1].storeOp = vk::AttachmentStoreOp::eDontCare;
      passAttachments[1].stencilLoadOp = vk::AttachmentLoadOp::eDontCare;
      passAttachments[1].stencilStoreOp = vk::AttachmentStoreOp::eDontCare;
      passAttachments[1].initialLayout = vk::ImageLayout::eDepthStencilAttachmentOptimal;
      passAttachments[1].finalLayout = vk::ImageLayout::eDepthStencilAttachmentOptimal;

      vk::AttachmentReference colorAttachmentReference;
      colorAttachmentReference.setAttachment(0); // First attachment is the color attachment.
      colorAttachmentReference.setLayout(vk::ImageLayout::eColorAttachmentOptimal);

      vk::AttachmentReference depthAttachmentReference;
      depthAttachmentReference.setAttachment(1); // Second attachment is the depth attachment.
      depthAttachmentReference.setLayout(vk::ImageLayout::eDepthStencilAttachmentOptimal);

      vk::SubpassDescription subpass;
      subpass.setPipelineBindPoint(vk::PipelineBindPoint::eGraphics);
      subpass.setColorAttachmentCount(1);
      subpass.setPColorAttachments(&colorAttachmentReference);
      subpass.setPDepthStencilAttachment(&depthAttachmentReference);

      vk::SubpassDependency subpassDependency;
      subpassDependency.setSrcStageMask(vk::PipelineStageFlagBits::eTopOfPipe);
      subpassDependency.setDstStageMask(vk::PipelineStageFlagBits::eTopOfPipe);
      //subpassDependency.setSrcAccessMask(vk::AccessFlagBits(0));
      //subpassDependency.setDstAccessMask(vk::AccessFlagBits(0));
      //subpassDependency.setSrcStageMask(vk::PipelineStageFlagBits::eColorAttachmentOutput);
      //subpassDependency.setDstStageMask(vk::PipelineStageFlagBits::eColorAttachmentOutput);
      subpassDependency.setSrcSubpass(0);
      subpassDependency.setDstSubpass(0);

      vk::RenderPassCreateInfo renderPassCreateInfo;
      renderPassCreateInfo.setAttachmentCount(static_cast<u32>(passAttachments.size()));
      renderPassCreateInfo.setPAttachments(passAttachments.data());
      renderPassCreateInfo.setSubpassCount(1);
      renderPassCreateInfo.setDependencyCount(1);
      renderPassCreateInfo.setPDependencies(&subpassDependency);
      renderPassCreateInfo.setPSubpasses(&subpass);

      self->mRenderPass = self->mLogicalDevice.createRenderPass(renderPassCreateInfo);
      vulkan_assert(self->mRenderPass, "Failed to create renderpass");
      
      // create our frame buffers:
      vk::ImageView frameBufferAttachments[2];
      frameBufferAttachments[1] = self->mDepthImageView;

      vk::FramebufferCreateInfo frameBufferCreateInfo = {};
      frameBufferCreateInfo.renderPass = self->mRenderPass;
      frameBufferCreateInfo.attachmentCount = 2;  // must be equal to the attachment count on render pass
      frameBufferCreateInfo.pAttachments = frameBufferAttachments;
      frameBufferCreateInfo.width = self->mWidth;
      frameBufferCreateInfo.height = self->mHeight;
      frameBufferCreateInfo.layers = 1;

      // create a framebuffer per swap chain imageView:
      auto imageCount = self->mPresentImages.size();
      self->mFrameBuffers = std::vector<vk::Framebuffer>(imageCount, vk::Framebuffer());
      for (u32 i = 0; i < imageCount; ++i) 
      {
        frameBufferAttachments[0] = self->mPresentImageViews[i];
        auto result = self->mLogicalDevice.createFramebuffer(&frameBufferCreateInfo, NULL, &self->mFrameBuffers[i]);
        checkVulkanResult(result, "Failed to create framebuffer.");
      }

      // Prepare and initialize a uniform buffer block containing shader uniforms
      // In Vulkan there are no more single uniforms like in GL
      // All shader uniforms are passed as uniform buffer blocks 

      // Vertex shader uniform buffer block

      // Most implementations offer multiple memory types and selecting the 
      // correct one to allocate memory from is important
      // We also want the buffer to be host coherent so we don't have to flush 
      // after every update. 
      // Note that this may affect performance so you might not want to do this 
      // in a real world application that updates buffers on a regular base
      self->mUniform = self->CreateBuffer(sizeof(UniformBufferObject), 
                                          vk::BufferUsageFlagBits::eUniformBuffer, 
                                          vk::MemoryPropertyFlagBits::eHostVisible |
                                          vk::MemoryPropertyFlagBits::eHostCoherent);

      // Store information in the uniform's descriptor
      self->mUniformBufferInfo.buffer = self->mUniform.mBuffer;
      self->mUniformBufferInfo.offset = 0;
      self->mUniformBufferInfo.range = sizeof(UniformBufferObject);

      self->UpdateUniformBuffers(true);

      self->SetupDescriptorSetLayout();

      Shader vert{ "./Shaders/vert.spv", ShaderType::Vertex, self };
      Shader frag{ "./Shaders/frag.spv", ShaderType::Fragment, self };
      
      std::array<vk::PipelineShaderStageCreateInfo, 2> shaderStageCreateInfo;
      shaderStageCreateInfo[0] = vert.CreateShaderStage();
      shaderStageCreateInfo[1] = frag.CreateShaderStage();
      
      ShaderDescriptions descriptions;
      descriptions.AddBinding<Vertex>(vk::VertexInputRate::eVertex);

      //glm::vec4 mPosition;
      descriptions.AddAttribute<glm::vec4>(vk::Format::eR32G32B32A32Sfloat);

      //glm::vec2 mUVCoordinates;
      descriptions.AddAttribute<glm::vec2>(vk::Format::eR32G32Sfloat);

      //glm::vec2 mNormal;
      descriptions.AddAttribute<glm::vec3>(vk::Format::eR32G32B32Sfloat);

      ///////////////////////////////////////////////////////////
      // Instance Attributes
      ///////////////////////////////////////////////////////////
      descriptions.AddBinding<Object>(vk::VertexInputRate::eInstance);

      //glm::vec3 mTranslation
      descriptions.AddAttribute<glm::vec3>(vk::Format::eR32G32B32Sfloat);
      
      //glm::vec3 mScale
      descriptions.AddAttribute<glm::vec3>(vk::Format::eR32G32B32Sfloat);

      //glm::vec3 mRotation;
      descriptions.AddAttribute<glm::vec3>(vk::Format::eR32G32B32Sfloat);

      //glm::vec3 mColor
      descriptions.AddAttribute<glm::vec3>(vk::Format::eR32G32B32Sfloat);

      //u32 mTextureId
      descriptions.AddAttribute<u32>(vk::Format::eR32Uint);

      //glm::mat4 mTransform;
      descriptions.AddAttribute<glm::vec3>(vk::Format::eR32G32B32A32Sfloat);
      descriptions.AddAttribute<glm::vec3>(vk::Format::eR32G32B32A32Sfloat);
      descriptions.AddAttribute<glm::vec3>(vk::Format::eR32G32B32A32Sfloat);
      descriptions.AddAttribute<glm::vec3>(vk::Format::eR32G32B32A32Sfloat);

      vk::PipelineVertexInputStateCreateInfo vertexInputStateCreateInfo;
      vertexInputStateCreateInfo.vertexBindingDescriptionCount = static_cast<u32>(descriptions.BindingSize());
      vertexInputStateCreateInfo.pVertexBindingDescriptions = descriptions.BindingData();
      vertexInputStateCreateInfo.vertexAttributeDescriptionCount = static_cast<u32>(descriptions.AttributeSize());
      vertexInputStateCreateInfo.pVertexAttributeDescriptions = descriptions.AttributeData();

      // vertex topology config:
      vk::PipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo;
      inputAssemblyStateCreateInfo.topology = vk::PrimitiveTopology::eTriangleList;
      
      vk::Viewport viewport = {};
      viewport.width = static_cast<float>(self->mWidth);
      viewport.height = static_cast<float>(self->mHeight);
      viewport.maxDepth = 1;

      vk::Rect2D scissors = {};
      scissors.extent.setWidth(self->mWidth).setHeight(self->mHeight);

      vk::PipelineViewportStateCreateInfo viewportState = {};
      viewportState.viewportCount = 1;
      viewportState.pViewports = &viewport;
      viewportState.scissorCount = 1;
      viewportState.pScissors = &scissors;

      vk::PipelineRasterizationStateCreateInfo rasterizationState;
      rasterizationState.polygonMode = vk::PolygonMode::eFill;
      //rasterizationState.cullMode = vk::CullModeFlagBits::eBack; // TODO: Investigate
      rasterizationState.cullMode = vk::CullModeFlagBits::eNone;
      rasterizationState.frontFace = vk::FrontFace::eCounterClockwise;
      //rasterizationState.frontFace = vk::FrontFace::eClockwise;
      rasterizationState.lineWidth = 1;
      rasterizationState.depthClampEnable = true;
      rasterizationState.depthBiasEnable = true;

      vk::PipelineMultisampleStateCreateInfo multisampleState = {};
      multisampleState.rasterizationSamples = vk::SampleCountFlagBits::e1;

      vk::StencilOpState stencilState = {};
      stencilState.failOp = vk::StencilOp::eReplace;
      stencilState.passOp = vk::StencilOp::eKeep;
      stencilState.depthFailOp = vk::StencilOp::eReplace;
      stencilState.compareOp = vk::CompareOp::eLessOrEqual;

      vk::PipelineDepthStencilStateCreateInfo depthState;
      depthState.depthTestEnable = true;
      depthState.depthWriteEnable = true;
      depthState.depthCompareOp = vk::CompareOp::eLessOrEqual;
      depthState.setDepthBoundsTestEnable(false);
      depthState.setStencilTestEnable(false);
      //depthState.front = noOPStencilState;
      //depthState.back = noOPStencilState;

      //depthState.back.compareOp = vk::CompareOp::eAlways;
      //depthState.front = stencilState;
      //depthState.back = stencilState;

      vk::PipelineColorBlendAttachmentState colorBlendAttachmentState;
      colorBlendAttachmentState.srcColorBlendFactor = vk::BlendFactor::eSrc1Color;
      colorBlendAttachmentState.dstColorBlendFactor = vk::BlendFactor::eOneMinusDstColor;
      colorBlendAttachmentState.colorBlendOp = vk::BlendOp::eAdd;
      colorBlendAttachmentState.srcAlphaBlendFactor = vk::BlendFactor::eZero;
      colorBlendAttachmentState.dstAlphaBlendFactor = vk::BlendFactor::eZero;
      colorBlendAttachmentState.alphaBlendOp = vk::BlendOp::eAdd;
      colorBlendAttachmentState.colorWriteMask = vk::ColorComponentFlagBits::eR | 
                                                 vk::ColorComponentFlagBits::eG |
                                                 vk::ColorComponentFlagBits::eB |
                                                 vk::ColorComponentFlagBits::eA;

      vk::PipelineColorBlendStateCreateInfo colorBlendState;
      colorBlendState.logicOpEnable = VK_FALSE;
      colorBlendState.logicOp = vk::LogicOp::eClear;
      colorBlendState.attachmentCount = 1;
      colorBlendState.pAttachments = &colorBlendAttachmentState;
      colorBlendState.blendConstants[0] = 0.0;
      colorBlendState.blendConstants[1] = 0.0;
      colorBlendState.blendConstants[2] = 0.0;
      colorBlendState.blendConstants[3] = 0.0;

      vk::DynamicState dynamicState[2] = { vk::DynamicState::eViewport, vk::DynamicState::eScissor };
      vk::PipelineDynamicStateCreateInfo dynamicStateCreateInfo ;
      dynamicStateCreateInfo.dynamicStateCount = 2;
      dynamicStateCreateInfo.pDynamicStates = dynamicState;

      vk::GraphicsPipelineCreateInfo pipelineCreateInfo;
      pipelineCreateInfo.stageCount = static_cast<u32>(shaderStageCreateInfo.size());
      pipelineCreateInfo.pStages = shaderStageCreateInfo.data();
      pipelineCreateInfo.pVertexInputState = &vertexInputStateCreateInfo;
      pipelineCreateInfo.pInputAssemblyState = &inputAssemblyStateCreateInfo;
      pipelineCreateInfo.pViewportState = &viewportState;
      pipelineCreateInfo.pRasterizationState = &rasterizationState;
      pipelineCreateInfo.pMultisampleState = &multisampleState;
      pipelineCreateInfo.pDepthStencilState = &depthState;
      pipelineCreateInfo.pColorBlendState = &colorBlendState;
      pipelineCreateInfo.pDynamicState = &dynamicStateCreateInfo;
      pipelineCreateInfo.layout = self->mPipelineLayout;
      pipelineCreateInfo.renderPass = self->mRenderPass;

      self->SetupDescriptorPool();
      self->SetupDescriptorSet();

      self->mPipeline = self->mLogicalDevice.createGraphicsPipelines(VK_NULL_HANDLE, pipelineCreateInfo)[0];
      vulkan_assert(self->mPipeline, "Failed to create graphics pipeline.");

      mQuadIndicies = self->CreateFilledBuffer({ 0, 1, 2, 2, 3, 0 });

      YTE::Vertex mVertex1;

      mVertex1.mPosition = { -0.5f, -0.5f, 0.0f, 1.0f };
      mVertex1.mUVCoordinates = { 0.0f, 0.0f };
      mVertex1.mNormal = { 0.0f, 0.0f, 1.0 };

      YTE::Vertex mVertex2;

      mVertex2.mPosition = { 0.5f, -0.5f, 0.0f, 1.0f };
      mVertex2.mUVCoordinates = { 1.0f, 0.0f };
      mVertex2.mNormal = { 0.0f, 0.0f, 1.0 };

      YTE::Vertex mVertex3;

      mVertex3.mPosition = { 0.5f, 0.5f, 0.0f, 1.0f };
      mVertex3.mUVCoordinates = { 1.0f, 1.0f };
      mVertex3.mNormal = { 0.0f, 0.0f, 1.0 };

      YTE::Vertex mVertex4;

      mVertex4.mPosition = { -0.5f, 0.5f, 0.0f, 1.0f };
      mVertex4.mUVCoordinates = { 0.0f, 1.0f };
      mVertex4.mNormal = { 0.0f, 0.0f, 1.0 };

      mQuadVerticies = self->CreateFilledBuffer({ mVertex1, mVertex2, mVertex3, mVertex4 });

    } 
  }
コード例 #2
0
ファイル: Render.cpp プロジェクト: flosmn/AntiradianceCuts
Renderer::Renderer(CCamera* m_camera, COGLContext* glContext, CConfigManager* confManager) 
	: m_camera(m_camera), m_glContext(glContext), m_confManager(confManager) 
{
	{
		std::vector<float3> positions;
		positions.push_back(make_float3(536.419, 548.9, 431.274));
		positions.push_back(make_float3(540.488, 548.9, 465.94));
		positions.push_back(make_float3(419.977, 469.29, 559.3));
		positions.push_back(make_float3(555.476, 471.466, 510.595));
		positions.push_back(make_float3(438.946, 548.9, 506.097));
		positions.push_back(make_float3(434.071, 501.603, 559.3));
		positions.push_back(make_float3(452.146, 548.9, 529.52));
		positions.push_back(make_float3(504.6, 509.978, 559.3));
		std::vector<float3> normals;
		for (int i = 0; i < positions.size(); ++i)
		{
			normals.push_back(make_float3(0.f, 1.f, 0.f));
		}

		SimpleBvh bvh(positions, normals, false);
	}

	m_cudaContext		.reset(new cuda::CudaContext());
	m_textureViewer 	.reset(new TextureViewer());
	m_postProcess		.reset(new Postprocess(m_confManager));
	m_fullScreenQuad	.reset(new FullScreenQuad());
	m_shadowMap			.reset(new CShadowMap(512));
	m_experimentData	.reset(new CExperimentData());
	m_export			.reset(new CExport());
	
	m_depthBuffer.reset(new COGLTexture2D(m_camera->GetWidth(), m_camera->GetHeight(), GL_DEPTH_COMPONENT32F,
		GL_DEPTH_COMPONENT, GL_FLOAT, 1, false, "Renderer.m_pDepthBuffer"));

	m_testTexture.reset(new COGLTexture2D(m_camera->GetWidth(), m_camera->GetHeight(), GL_RGBA32F, 
		GL_RGBA, GL_FLOAT, 1, false, "Renderer.m_pTestTexture"));

	m_gbuffer.reset(new CGBuffer(m_camera->GetWidth(), m_camera->GetHeight(), m_depthBuffer.get()));

	m_ubTransform.reset(new COGLUniformBuffer(sizeof(TRANSFORM),	0, GL_DYNAMIC_DRAW	, "UBTransform"	));
	m_ubMaterial .reset(new COGLUniformBuffer(sizeof(MATERIAL),		0, GL_DYNAMIC_DRAW	, "UBMaterial"	));
	m_ubLight	 .reset(new COGLUniformBuffer(sizeof(AVPL_STRUCT),	0, GL_DYNAMIC_DRAW	, "UBLight"		));
	m_ubConfig	 .reset(new COGLUniformBuffer(sizeof(CONFIG),		0, GL_DYNAMIC_DRAW	, "UBConfig"	));
	m_ubCamera	 .reset(new COGLUniformBuffer(sizeof(CAMERA),		0, GL_DYNAMIC_DRAW	, "UBCamera"	));
	m_ubInfo	 .reset(new COGLUniformBuffer(sizeof(INFO),			0, GL_DYNAMIC_DRAW	, "UBInfo"		));
	
	m_linearSampler		.reset(new COGLSampler(GL_LINEAR,	GL_LINEAR,	GL_CLAMP,			GL_CLAMP,			"LinearSampler"));
	m_pointSampler		.reset(new COGLSampler(GL_NEAREST,	GL_NEAREST, GL_REPEAT,			GL_REPEAT,			"PointSampler"));
	m_shadowMapSampler	.reset(new COGLSampler(GL_NEAREST,	GL_NEAREST, GL_CLAMP_TO_BORDER, GL_CLAMP_TO_BORDER, "ShadowMapSampler"));

	m_postProcessRenderTarget			.reset(new CRenderTarget(m_camera->GetWidth(), m_camera->GetHeight(), 1, 0));
	m_errorRenderTarget					.reset(new CRenderTarget(m_camera->GetWidth(), m_camera->GetHeight(), 1, 0));
	m_gatherShadowmapRenderTarget		.reset(new CRenderTarget(m_camera->GetWidth(), m_camera->GetHeight(), 4, 0));
	m_gatherAntiradianceRenderTarget	.reset(new CRenderTarget(m_camera->GetWidth(), m_camera->GetHeight(), 4, 0));
	m_normalizeShadowmapRenderTarget	.reset(new CRenderTarget(m_camera->GetWidth(), m_camera->GetHeight(), 3, m_depthBuffer.get()));
	m_normalizeAntiradianceRenderTarget .reset(new CRenderTarget(m_camera->GetWidth(), m_camera->GetHeight(), 3, m_depthBuffer.get()));
	m_resultRenderTarget				.reset(new CRenderTarget(m_camera->GetWidth(), m_camera->GetHeight(), 1, m_depthBuffer.get()));
	m_lightDebugRenderTarget			.reset(new CRenderTarget(m_camera->GetWidth(), m_camera->GetHeight(), 1, m_depthBuffer.get()));
	m_cudaRenderTarget					.reset(new CRenderTarget(m_camera->GetWidth(), m_camera->GetHeight(), 4, 0));
	m_cudaRenderTargetSum				.reset(new CRenderTarget(m_camera->GetWidth(), m_camera->GetHeight(), 4, 0));

	m_gatherProgram					.reset(new CProgram("Shaders/Gather.vert"			, "Shaders/Gather.frag"					, "GatherProgram"				));
	m_normalizeProgram				.reset(new CProgram("Shaders/Gather.vert"			, "Shaders/Normalize.frag"				, "NormalizeProgram"			));
	m_errorProgram					.reset(new CProgram("Shaders/Gather.vert"			, "Shaders/Error.frag"					, "ErrorProgram"				));
	m_addProgram					.reset(new CProgram("Shaders/Gather.vert"			, "Shaders/Add.frag"					, "AddProgram"					));
	m_createGBufferProgram			.reset(new CProgram("Shaders/CreateGBuffer.vert"	, "Shaders/CreateGBuffer.frag"			, "CreateGBufferProgram"		));
	m_createSMProgram				.reset(new CProgram("Shaders/CreateSM.vert"			, "Shaders/CreateSM.frag"				, "CreateSMProgram"				));
	m_gatherRadianceWithSMProgram	.reset(new CProgram("Shaders/Gather.vert"			, "Shaders/GatherRadianceWithSM.frag"	, "GatherRadianceWithSMProgram"	));
	m_areaLightProgram				.reset(new CProgram("Shaders/DrawAreaLight.vert"	, "Shaders/DrawAreaLight.frag"			, "AreaLightProgram"			));
	m_drawSphere			 		.reset(new CProgram("Shaders/DrawSphere.vert"		, "Shaders/DrawSphere.frag"				, "DrawSphere"					));
	m_debugProgram			 		.reset(new CProgram("Shaders/Debug.vert"			, "Shaders/Debug.frag"					, "Debug"					));

	m_scene.reset(new Scene(m_camera, m_confManager));
	m_scene->LoadCornellBox();

	m_avplShooter.reset(new AvplShooter(m_scene.get(), m_confManager));

	m_imagePlane				.reset(new CImagePlane(m_scene->GetCamera()));
	m_pathTracingIntegrator		.reset(new CPathTracingIntegrator(m_scene.get(), m_imagePlane.get()));
	
	m_cpuTimer			.reset(new CTimer(CTimer::CPU));
	m_glTimer			.reset(new CTimer(CTimer::OGL));
	m_globalTimer		.reset(new CTimer(CTimer::CPU));
	m_resultTimer		.reset(new CTimer(CTimer::CPU));
	m_cpuFrameProfiler	.reset(new CTimer(CTimer::CPU));
	m_gpuFrameProfiler	.reset(new CTimer(CTimer::OGL));
	
	m_Finished = false;
	m_FinishedDirectLighting = false;
	m_FinishedIndirectLighting = false;
	m_FinishedDebug = false;
	m_ProfileFrame = false;
	m_NumAVPLsForNextDataExport = 1000;
	m_NumAVPLsForNextImageExport = 10000;
	m_NumAVPLs = 0;
	m_NumPathsDebug = 0;
	m_ClearLighting = false;
	m_ClearAccumulationBuffer = false;

	BindSamplers();

	UpdateUniformBuffers();

	time(&m_StartTime);
	
	InitDebugLights();
		
	ClearAccumulationBuffer();
	
	m_globalTimer->Start();

	m_cudaTargetTexture.reset(new COGLTexture2D(m_camera->GetWidth(), m_camera->GetWidth(), GL_RGBA32F,
		GL_RGBA, GL_FLOAT, 1, false, "m_cudaTarget"));
	
	m_cudaGather.reset(new CudaGather(m_camera,
		m_gbuffer->GetPositionTextureWS()->GetResourceIdentifier(),
		m_gbuffer->GetNormalTexture()->GetResourceIdentifier(),
		m_cudaRenderTarget->GetTarget(0)->GetResourceIdentifier(),
		m_cudaRenderTarget->GetTarget(1)->GetResourceIdentifier(),
		m_cudaRenderTarget->GetTarget(2)->GetResourceIdentifier(),
		m_scene->GetMaterialBuffer()->getMaterials(),
		m_ubTransform.get(), m_confManager));
}
コード例 #3
0
  void GraphicsSystem::VulkanRender()
  {
    auto self = mPlatformSpecificData.Get<VulkanContext>();

    if (mObjectsBufferSize < mObjects.size())
    {
      SetupObjectBuffer();

      SetupDrawing();
    }

    auto bufferSize = static_cast<u32>(mObjects.size() * sizeof(Object));

    //for (auto &object : mObjects)
    //{
    //  glm::mat4 objectToWorld = glm::translate(glm::mat4(), object.mTranslation);
    //  
    //  objectToWorld = glm::rotate(objectToWorld, object.mRotation.x, glm::vec3(1.0, 0.0, 0.0));
    //  objectToWorld = glm::rotate(objectToWorld, object.mRotation.y, glm::vec3(0.0, 1.0, 0.0));
    //  objectToWorld = glm::rotate(objectToWorld, object.mRotation.z, glm::vec3(0.0, 0.0, 1.0));
    //
    //  objectToWorld = glm::scale(objectToWorld, object.mScale);
    //  object.mTransform = objectToWorld;
    //}

    auto objectsBufferPtr = static_cast<Object*>(self->mLogicalDevice.mapMemory(mObjectsBuffer.mMemory, 0, bufferSize));
    memcpy(objectsBufferPtr, mObjects.data(), bufferSize);
    self->mLogicalDevice.unmapMemory(mObjectsBuffer.mMemory);

    const float zoomSpeed = 0.15f;
    const float rotationSpeed = 1.25f;

    // Update rotation
    auto &mouse = mEngine->mPrimaryWindow->mMouse;
    if (true == mouse.mLeftMouseDown)
    {
      self->mRotation.x += (mMousePosition.y - (float)mouse.mY) * rotationSpeed;
      self->mRotation.y -= (mMousePosition.x - (float)mouse.mX) * rotationSpeed;

      mMousePosition.x = mouse.mX;
      mMousePosition.y = mouse.mY;
    }

    // Update zoom
    auto zoom = self->mZoom;
    self->mZoom += mEngine->mPrimaryWindow->mMouse.mWheelDelta * zoomSpeed;

    if (zoom != self->mZoom || true == mouse.mLeftMouseDown)
    {
      self->UpdateUniformBuffers(true);
    }
    
    vk::SemaphoreCreateInfo semaphoreCreateInfo = vk::SemaphoreCreateInfo();

    auto presentCompleteSemaphore = self->mLogicalDevice.createSemaphore(semaphoreCreateInfo);
    auto renderingCompleteSemaphore = self->mLogicalDevice.createSemaphore(semaphoreCreateInfo);

    auto result = self->mLogicalDevice.acquireNextImageKHR(self->mSwapChain, UINT64_MAX, presentCompleteSemaphore, VK_NULL_HANDLE, &self->mCurrentDrawBuffer);
    checkVulkanResult(result, "Could not acquireNextImageKHR.");


    // present:
    vk::Fence renderFence = self->mLogicalDevice.createFence(vk::FenceCreateInfo());

    vk::PipelineStageFlags waitStageMash = { vk::PipelineStageFlagBits::eBottomOfPipe };
    vk::SubmitInfo submitInfo = {};
    submitInfo.waitSemaphoreCount = 1;
    submitInfo.pWaitSemaphores = &presentCompleteSemaphore;
    submitInfo.pWaitDstStageMask = &waitStageMash;
    submitInfo.commandBufferCount = 1;
    submitInfo.pCommandBuffers = &self->mDrawCommandBuffers[self->mCurrentDrawBuffer];
    submitInfo.signalSemaphoreCount = 1;
    submitInfo.pSignalSemaphores = &renderingCompleteSemaphore;
    
    self->mQueue.submit(submitInfo, renderFence);

    self->mLogicalDevice.waitForFences(renderFence, true, UINT64_MAX);
    self->mLogicalDevice.destroyFence(renderFence);

    vk::PresentInfoKHR presentInfo = {};
    presentInfo.waitSemaphoreCount = 1;
    presentInfo.pWaitSemaphores = &renderingCompleteSemaphore;
    presentInfo.swapchainCount = 1;
    presentInfo.pSwapchains = &self->mSwapChain;
    presentInfo.pImageIndices = &self->mCurrentDrawBuffer;

    self->mQueue.presentKHR(presentInfo);

    self->mLogicalDevice.destroySemaphore(presentCompleteSemaphore);
    self->mLogicalDevice.destroySemaphore(renderingCompleteSemaphore);
  }
コード例 #4
0
ファイル: Render.cpp プロジェクト: flosmn/AntiradianceCuts
void Renderer::Render() 
{	
	if(m_ClearLighting)
		ClearLighting();
	if(m_ClearAccumulationBuffer)
		ClearAccumulationBuffer();
	
	CTimer frameTimer(CTimer::OGL);
	CTimer timer(CTimer::OGL);

	if(m_ProfileFrame)
	{	
		std::cout << std::endl;
		std::cout << "Profile frame --------------- " << std::endl;
		std::cout << std::endl;
		frameTimer.Start();
		timer.Start();
	}

	SetUpRender();

	if(m_ProfileFrame) timer.Stop("set up render");
	if(m_ProfileFrame) timer.Start();

	UpdateUniformBuffers();

	if(m_ProfileFrame) timer.Stop("update ubs");
	
	if(m_CurrentPathAntiradiance == 0 && m_CurrentPathShadowmap == 0)
	{
		m_experimentData->Init("test", "nois.data");
		m_experimentData->MaxTime(450);

		m_globalTimer->Start();
		m_resultTimer->Start();
		m_glTimer->Start();
		CreateGBuffer();

		m_cudaGather->rebuildVisiblePointsBvh();
	}
	
	if (m_confManager->GetConfVars()->drawGBufferTextures) {
		int border = 10;
		int width = (m_camera->GetWidth() - 4 * border) / 2;
		int height = (m_camera->GetHeight() - 4 * border) / 2;
		m_textureViewer->drawTexture(m_gbuffer->GetNormalTexture(),  border, border, width, height);
		m_textureViewer->drawTexture(m_gbuffer->GetPositionTextureWS(),  3 * border + width, border, width, height);
		m_textureViewer->drawTexture(m_normalizeAntiradianceRenderTarget->GetTarget(2),  border, 3 * border + height, width, height);
		m_textureViewer->drawTexture(m_depthBuffer.get(),  3 * border + width, 3 * border + height, width, height);
		return;
	}
	
	std::vector<Avpl> avpls_shadowmap;
	std::vector<Avpl> avpls_antiradiance;

	if(m_ProfileFrame) timer.Start();

	//GetAVPLs(avpls_shadowmap, avpls_antiradiance);

	m_avplShooter->shoot(avpls_shadowmap, avpls_antiradiance, m_confManager->GetConfVars()->NumAVPLsPerFrame);
	m_CurrentPathAntiradiance += m_confManager->GetConfVars()->NumAVPLsPerFrame;
	
	if(m_ProfileFrame) timer.Stop("get avpls");
	if(m_ProfileFrame) timer.Start();

	if (m_confManager->GetConfVars()->gatherWithCuda) 
	{
		if (avpls_antiradiance.size() > 0) {
			m_cudaGather->run(avpls_antiradiance, m_camera->GetPosition(), 
				m_sceneProbe.get(), m_scene->getSceneExtent(), m_ProfileFrame);
			
			Add(m_gatherAntiradianceRenderTarget.get(), m_cudaRenderTarget.get());
		}
		
		if(m_ProfileFrame) timer.Stop("gather");
		if(m_ProfileFrame) timer.Start();
	}
	else
	{
		Gather(avpls_shadowmap, avpls_antiradiance);
		
		if(m_ProfileFrame) timer.Stop("gather");
		if(m_ProfileFrame) timer.Start();
	}

	Normalize(m_normalizeShadowmapRenderTarget.get(), m_gatherShadowmapRenderTarget.get(), m_CurrentPathShadowmap);
	Normalize(m_normalizeAntiradianceRenderTarget.get(), m_gatherAntiradianceRenderTarget.get(), m_CurrentPathAntiradiance);
	
	if(m_ProfileFrame) timer.Stop("normalize");
	if(m_ProfileFrame) timer.Start();

	if(m_confManager->GetConfVars()->LightingMode == 2)
	{
		drawAreaLight(m_normalizeShadowmapRenderTarget.get(), glm::vec3(0.f, 0.f, 0.f));
		drawAreaLight(m_normalizeAntiradianceRenderTarget.get(), glm::vec3(0.f, 0.f, 0.f));
	}
	else
	{
		drawAreaLight(m_normalizeShadowmapRenderTarget.get(), m_scene->getAreaLight()->getRadiance());
	}
	
	SetTransformToCamera();
	
	Add(m_resultRenderTarget.get(), m_normalizeAntiradianceRenderTarget.get(), m_normalizeShadowmapRenderTarget.get());

	if (m_confManager->GetConfVars()->UseDebugMode)
	{
		if (m_confManager->GetConfVars()->DrawClusterLights) {
			CRenderTargetLock lock(m_resultRenderTarget.get());
			PointCloud pc(m_cudaGather->getVisiblePointsBvh()->centerPositions,
				m_cudaGather->getVisiblePointsBvh()->colors, m_ubTransform.get(),
				m_confManager->GetConfVars()->lightRadiusScale * m_scene->getSceneExtent() / 100.f);
			pc.Draw();
			//m_cudaGather->getPointCloud()->Draw();
		}
		if (m_confManager->GetConfVars()->DrawClusterAABBs) {
			CRenderTargetLock lock(m_resultRenderTarget.get());
			AABBCloud aabb(m_cudaGather->getVisiblePointsBvh()->clusterMin, 
				m_cudaGather->getVisiblePointsBvh()->clusterMax, m_ubTransform.get());
			aabb.Draw();
			//m_cudaGather->getAABBCloud()->Draw();
		}
		
		if (m_confManager->GetConfVars()->DrawLights) {
			CRenderTargetLock lock(m_resultRenderTarget.get());
			m_pointCloud->Draw();
		}

		if (m_sceneProbe) {
			m_sceneProbe->draw(m_resultRenderTarget.get(), m_debugProgram.get(), 
					m_ubTransform.get(), m_camera);
			m_pointCloud->Draw();
		}
	}
	DrawDebug();

	if(m_ProfileFrame) timer.Stop("draw debug");
		
	m_postProcess->postprocess(m_resultRenderTarget->GetTarget(0), m_postProcessRenderTarget.get());
	m_textureViewer->drawTexture(m_postProcessRenderTarget->GetTarget(0), 0, 0, m_camera->GetWidth(), m_camera->GetHeight());	
	
	m_NumAVPLs += (int)avpls_antiradiance.size();
	m_NumAVPLs += (int)avpls_shadowmap.size();

	if(m_ProfileFrame) timer.Start();

	avpls_antiradiance.clear();
	avpls_shadowmap.clear();

	if(m_ProfileFrame) timer.Stop("clear avpls");
	
	CheckExport();

	m_Frame++;

	if(m_ProfileFrame) frameTimer.Stop("frame time");
		
	m_ProfileFrame = false;
	m_FinishedDebug = true;
}