~sircmpwn/xrgears

ref: 5629b6b27c3ce4fa6a5fadc28adcc70d44122bc6 xrgears/vitamin-k/render/vikRendererTextOverlay.hpp -rw-r--r-- 4.0 KiB
5629b6b2 — Lubosz Sarnecki render: fix some vulkan validation warnings. 4 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*
 * vitamin-k
 *
 * Copyright 2016 Sascha Willems - www.saschawillems.de
 * Copyright 2017-2018 Collabora Ltd.
 *
 * Authors: Lubosz Sarnecki <lubosz.sarnecki@collabora.com>
 * SPDX-License-Identifier: MIT
 *
 * Based on Vulkan Examples written by Sascha Willems
 */

#pragma once

#include <string>
#include <vector>

#include "vikRenderer.hpp"

namespace vik {

class RendererTextOverlay : public Renderer {
 public:
  TextOverlay *textOverlay;

  VkSemaphore text_overlay_complete;

  std::string name;

  RendererTextOverlay(Settings *s) : Renderer(s) {}
  virtual ~RendererTextOverlay() {
    vkDestroySemaphore(device, text_overlay_complete, nullptr);
    if (settings->enable_text_overlay)
      delete textOverlay;
  }

  void init(const std::string &n) {
    Renderer::init(n);
    name = n;
    if (settings->enable_text_overlay) {
      init_text_overlay();
      update_text_overlay();
    }
  }

  void init_text_overlay() {
    // Load the text rendering shaders
    std::vector<VkPipelineShaderStageCreateInfo> shaderStages;
    shaderStages.push_back(Shader::load(device, "base/textoverlay.vert.spv", VK_SHADER_STAGE_VERTEX_BIT));
    shaderStages.push_back(Shader::load(device, "base/textoverlay.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT));

    textOverlay = new TextOverlay(
          vksDevice,
          queue,
          &frame_buffers,
          window->get_swap_chain()->surface_format.format,
          depthFormat,
          &width,
          &height,
          shaderStages);
  }

  VkSubmitInfo init_text_submit_info() {
    // Wait for color attachment output to finish before rendering the text overlay
    VkPipelineStageFlags stageFlags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;

    VkSubmitInfo submit_info = initializers::submitInfo();
    submit_info.pWaitDstStageMask = &stageFlags;
    submit_info.waitSemaphoreCount = 1;
    submit_info.pWaitSemaphores = &semaphores.render_complete;
    submit_info.signalSemaphoreCount = 1;
    submit_info.pSignalSemaphores = &text_overlay_complete;
    submit_info.commandBufferCount = 1;
    return submit_info;
  }

  void update_text_overlay() {
    if (!settings->enable_text_overlay)
      return;

    std::stringstream ss;
    ss << std::fixed
       << std::setprecision(3)
       << (timer.frame_time_seconds * 1000.0f)
       << "ms (" << timer.frames_per_second
       << " fps)";
    std::string deviceName(deviceProperties.deviceName);

    textOverlay->update(name, ss.str(), deviceName);
  }

  void submit_text_overlay() {
    VkSubmitInfo submit_info = init_text_submit_info();
    submit_info.pCommandBuffers = &textOverlay->cmdBuffers[currentBuffer];
    vik_log_check(vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE));
  }

  void check_tick_finnished() {
    if (timer.tick_finnished()) {
      timer.update_fps();
      if (settings->enable_text_overlay)
        update_text_overlay();
      timer.reset();
    }
  }

  void resize() {
    Renderer::resize();
    if (settings->enable_text_overlay) {
      textOverlay->reallocateCommandBuffers();
      update_text_overlay();
    }
  }

  void submit_frame() {
    VkSemaphore waitSemaphore;
    if (settings->enable_text_overlay && textOverlay->visible) {
      submit_text_overlay();
      waitSemaphore = text_overlay_complete;
    } else {
      waitSemaphore = semaphores.render_complete;
    }

    SwapChainVK *sc = (SwapChainVK*) window->get_swap_chain();
    vik_log_check(sc->present(queue, currentBuffer, waitSemaphore));
    vik_log_check(vkQueueWaitIdle(queue));
  }

  void init_semaphores() {
    Renderer::init_semaphores();
     VkSemaphoreCreateInfo semaphore_info = initializers::semaphoreCreateInfo();
    // Create a semaphore used to synchronize command submission
    // Ensures that the image is not presented until all commands for the text overlay have been sumbitted and executed
    // Will be inserted after the render complete semaphore if the text overlay is enabled
    vik_log_check(vkCreateSemaphore(device, &semaphore_info, nullptr, &text_overlay_complete));
  }
};
}  // namespace vik