MythTV  master
mythvisualmonoscopevulkan.cpp
Go to the documentation of this file.
1 // MythTV
7 
8 #define LineVertex450 (VK_SHADER_STAGE_VERTEX_BIT | (1 << 6))
9 #define LineFragment450 (VK_SHADER_STAGE_FRAGMENT_BIT | (1 << 7))
10 
12  { LineVertex450,
13  { VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,
14  { { 0, { 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT, nullptr } } },
15  { 0, 2 * sizeof(float), VK_VERTEX_INPUT_RATE_VERTEX },
16  { { 0, 0, VK_FORMAT_R32G32_SFLOAT, 0 } },
17  { VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(PushBuffer) } }
18  },
20  { VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,
21  { },
22  { },
23  { },
24  { } }
25  }
26 };
27 
29 {
31 {
32 "#version 450\n"
33 "#extension GL_ARB_separate_shader_objects : enable\n"
34 "layout(set = 0, binding = 0) uniform Projection { mat4 projection; } proj;\n"
35 "layout(push_constant) uniform ComboBuffer {\n"
36 " mat4 transform;\n"
37 " vec4 color;\n"
38 "} cb;\n"
39 "layout(location = 0) in vec2 fragPosition;\n"
40 "layout(location = 0) out vec4 fragColor;\n"
41 "void main() {\n"
42 " gl_Position = proj.projection * cb.transform * vec4(fragPosition, 0.0, 1.0);\n"
43 " fragColor = cb.color;\n"
44 "}\n",
45 {
46 0x07230203, 0x00010300, 0x00080008, 0x0000002F,
47 0x00000000, 0x00020011, 0x00000001, 0x0006000B,
48 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E,
49 0x00000000, 0x0003000E, 0x00000000, 0x00000001,
50 0x0008000F, 0x00000000, 0x00000004, 0x6E69616D,
51 0x00000000, 0x0000000D, 0x00000020, 0x0000002A,
52 0x00030003, 0x00000002, 0x000001C2, 0x00090004,
53 0x415F4C47, 0x735F4252, 0x72617065, 0x5F657461,
54 0x64616873, 0x6F5F7265, 0x63656A62, 0x00007374,
55 0x00040005, 0x00000004, 0x6E69616D, 0x00000000,
56 0x00060005, 0x0000000B, 0x505F6C67, 0x65567265,
57 0x78657472, 0x00000000, 0x00060006, 0x0000000B,
58 0x00000000, 0x505F6C67, 0x7469736F, 0x006E6F69,
59 0x00070006, 0x0000000B, 0x00000001, 0x505F6C67,
60 0x746E696F, 0x657A6953, 0x00000000, 0x00070006,
61 0x0000000B, 0x00000002, 0x435F6C67, 0x4470696C,
62 0x61747369, 0x0065636E, 0x00070006, 0x0000000B,
63 0x00000003, 0x435F6C67, 0x446C6C75, 0x61747369,
64 0x0065636E, 0x00030005, 0x0000000D, 0x00000000,
65 0x00050005, 0x00000011, 0x6A6F7250, 0x69746365,
66 0x00006E6F, 0x00060006, 0x00000011, 0x00000000,
67 0x6A6F7270, 0x69746365, 0x00006E6F, 0x00040005,
68 0x00000013, 0x6A6F7270, 0x00000000, 0x00050005,
69 0x00000017, 0x626D6F43, 0x6675426F, 0x00726566,
70 0x00060006, 0x00000017, 0x00000000, 0x6E617274,
71 0x726F6673, 0x0000006D, 0x00050006, 0x00000017,
72 0x00000001, 0x6F6C6F63, 0x00000072, 0x00030005,
73 0x00000019, 0x00006263, 0x00060005, 0x00000020,
74 0x67617266, 0x69736F50, 0x6E6F6974, 0x00000000,
75 0x00050005, 0x0000002A, 0x67617266, 0x6F6C6F43,
76 0x00000072, 0x00050048, 0x0000000B, 0x00000000,
77 0x0000000B, 0x00000000, 0x00050048, 0x0000000B,
78 0x00000001, 0x0000000B, 0x00000001, 0x00050048,
79 0x0000000B, 0x00000002, 0x0000000B, 0x00000003,
80 0x00050048, 0x0000000B, 0x00000003, 0x0000000B,
81 0x00000004, 0x00030047, 0x0000000B, 0x00000002,
82 0x00040048, 0x00000011, 0x00000000, 0x00000005,
83 0x00050048, 0x00000011, 0x00000000, 0x00000023,
84 0x00000000, 0x00050048, 0x00000011, 0x00000000,
85 0x00000007, 0x00000010, 0x00030047, 0x00000011,
86 0x00000002, 0x00040047, 0x00000013, 0x00000022,
87 0x00000000, 0x00040047, 0x00000013, 0x00000021,
88 0x00000000, 0x00040048, 0x00000017, 0x00000000,
89 0x00000005, 0x00050048, 0x00000017, 0x00000000,
90 0x00000023, 0x00000000, 0x00050048, 0x00000017,
91 0x00000000, 0x00000007, 0x00000010, 0x00050048,
92 0x00000017, 0x00000001, 0x00000023, 0x00000040,
93 0x00030047, 0x00000017, 0x00000002, 0x00040047,
94 0x00000020, 0x0000001E, 0x00000000, 0x00040047,
95 0x0000002A, 0x0000001E, 0x00000000, 0x00020013,
96 0x00000002, 0x00030021, 0x00000003, 0x00000002,
97 0x00030016, 0x00000006, 0x00000020, 0x00040017,
98 0x00000007, 0x00000006, 0x00000004, 0x00040015,
99 0x00000008, 0x00000020, 0x00000000, 0x0004002B,
100 0x00000008, 0x00000009, 0x00000001, 0x0004001C,
101 0x0000000A, 0x00000006, 0x00000009, 0x0006001E,
102 0x0000000B, 0x00000007, 0x00000006, 0x0000000A,
103 0x0000000A, 0x00040020, 0x0000000C, 0x00000003,
104 0x0000000B, 0x0004003B, 0x0000000C, 0x0000000D,
105 0x00000003, 0x00040015, 0x0000000E, 0x00000020,
106 0x00000001, 0x0004002B, 0x0000000E, 0x0000000F,
107 0x00000000, 0x00040018, 0x00000010, 0x00000007,
108 0x00000004, 0x0003001E, 0x00000011, 0x00000010,
109 0x00040020, 0x00000012, 0x00000002, 0x00000011,
110 0x0004003B, 0x00000012, 0x00000013, 0x00000002,
111 0x00040020, 0x00000014, 0x00000002, 0x00000010,
112 0x0004001E, 0x00000017, 0x00000010, 0x00000007,
113 0x00040020, 0x00000018, 0x00000009, 0x00000017,
114 0x0004003B, 0x00000018, 0x00000019, 0x00000009,
115 0x00040020, 0x0000001A, 0x00000009, 0x00000010,
116 0x00040017, 0x0000001E, 0x00000006, 0x00000002,
117 0x00040020, 0x0000001F, 0x00000001, 0x0000001E,
118 0x0004003B, 0x0000001F, 0x00000020, 0x00000001,
119 0x0004002B, 0x00000006, 0x00000022, 0x00000000,
120 0x0004002B, 0x00000006, 0x00000023, 0x3F800000,
121 0x00040020, 0x00000028, 0x00000003, 0x00000007,
122 0x0004003B, 0x00000028, 0x0000002A, 0x00000003,
123 0x0004002B, 0x0000000E, 0x0000002B, 0x00000001,
124 0x00040020, 0x0000002C, 0x00000009, 0x00000007,
125 0x00050036, 0x00000002, 0x00000004, 0x00000000,
126 0x00000003, 0x000200F8, 0x00000005, 0x00050041,
127 0x00000014, 0x00000015, 0x00000013, 0x0000000F,
128 0x0004003D, 0x00000010, 0x00000016, 0x00000015,
129 0x00050041, 0x0000001A, 0x0000001B, 0x00000019,
130 0x0000000F, 0x0004003D, 0x00000010, 0x0000001C,
131 0x0000001B, 0x00050092, 0x00000010, 0x0000001D,
132 0x00000016, 0x0000001C, 0x0004003D, 0x0000001E,
133 0x00000021, 0x00000020, 0x00050051, 0x00000006,
134 0x00000024, 0x00000021, 0x00000000, 0x00050051,
135 0x00000006, 0x00000025, 0x00000021, 0x00000001,
136 0x00070050, 0x00000007, 0x00000026, 0x00000024,
137 0x00000025, 0x00000022, 0x00000023, 0x00050091,
138 0x00000007, 0x00000027, 0x0000001D, 0x00000026,
139 0x00050041, 0x00000028, 0x00000029, 0x0000000D,
140 0x0000000F, 0x0003003E, 0x00000029, 0x00000027,
141 0x00050041, 0x0000002C, 0x0000002D, 0x00000019,
142 0x0000002B, 0x0004003D, 0x00000007, 0x0000002E,
143 0x0000002D, 0x0003003E, 0x0000002A, 0x0000002E,
144 0x000100FD, 0x00010038
145 } } },
146 {
148 {
149 "#version 450\n"
150 "#extension GL_ARB_separate_shader_objects : enable\n"
151 "layout(location = 0) in vec4 lineColor;\n"
152 "layout(location = 0) out vec4 fragColor;\n"
153 "void main() {\n"
154 " fragColor = lineColor;\n"
155 "}\n",
156 {
157 0x07230203, 0x00010300, 0x00080008, 0x0000000D,
158 0x00000000, 0x00020011, 0x00000001, 0x0006000B,
159 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E,
160 0x00000000, 0x0003000E, 0x00000000, 0x00000001,
161 0x0007000F, 0x00000004, 0x00000004, 0x6E69616D,
162 0x00000000, 0x00000009, 0x0000000B, 0x00030010,
163 0x00000004, 0x00000007, 0x00030003, 0x00000002,
164 0x000001C2, 0x00090004, 0x415F4C47, 0x735F4252,
165 0x72617065, 0x5F657461, 0x64616873, 0x6F5F7265,
166 0x63656A62, 0x00007374, 0x00040005, 0x00000004,
167 0x6E69616D, 0x00000000, 0x00050005, 0x00000009,
168 0x67617266, 0x6F6C6F43, 0x00000072, 0x00050005,
169 0x0000000B, 0x656E696C, 0x6F6C6F43, 0x00000072,
170 0x00040047, 0x00000009, 0x0000001E, 0x00000000,
171 0x00040047, 0x0000000B, 0x0000001E, 0x00000000,
172 0x00020013, 0x00000002, 0x00030021, 0x00000003,
173 0x00000002, 0x00030016, 0x00000006, 0x00000020,
174 0x00040017, 0x00000007, 0x00000006, 0x00000004,
175 0x00040020, 0x00000008, 0x00000003, 0x00000007,
176 0x0004003B, 0x00000008, 0x00000009, 0x00000003,
177 0x00040020, 0x0000000A, 0x00000001, 0x00000007,
178 0x0004003B, 0x0000000A, 0x0000000B, 0x00000001,
179 0x00050036, 0x00000002, 0x00000004, 0x00000000,
180 0x00000003, 0x000200F8, 0x00000005, 0x0004003D,
181 0x00000007, 0x0000000C, 0x0000000B, 0x0003003E,
182 0x00000009, 0x0000000C, 0x000100FD, 0x00010038
183 } } }
184 };
185 
187  : VideoVisualMonoScope(Audio, Render, Fade),
188  MythVisualVulkan(dynamic_cast<MythRenderVulkan*>(Render),
189  { VK_DYNAMIC_STATE_LINE_WIDTH },
192 {
193  m_needsPrepare = true;
194 }
195 
197 {
199 }
200 
202 {
203  if (!InitialiseVulkan(Area))
204  return;
205 
206  UpdateTime();
207 
208  // Rotate the vertex buffers and state
209  if (m_fade)
210  {
211  // fade away...
212  float fade = 1.0F - (m_rate / 150.0F);
213  float zoom = 1.0F - (m_rate / 4000.0F);
214  for (auto & state : m_vertexBuffers)
215  {
216  state.second[1] *= fade;
217  state.second[2] *= zoom;
218  }
219 
220  // drop oldest
221  auto vertex = m_vertexBuffers.front();
222  m_vertexBuffers.pop_front();
223  m_vertexBuffers.append(vertex);
224  }
225 
226  // Update the newest vertex buffer
227  auto & vertex = m_vertexBuffers.back();
228  vertex.second[0] = m_hue;
229  vertex.second[1] = 1.0;
230  vertex.second[2] = 1.0;
231  auto * buffer = vertex.first->GetMappedMemory();
232  if (!UpdateVertices(static_cast<float*>(buffer)))
233  return;
234  vertex.first->Update(nullptr);
235 }
236 
237 void MythVisualMonoScopeVulkan::Draw(const QRect Area, MythPainter* /*Painter*/, QPaintDevice* /*Device*/)
238 {
239  if (!InitialiseVulkan(Area))
240  return;
241 
242  if (Area.isEmpty())
243  return;
244 
245  // Retrieve current command buffer
246  auto *currentcmdbuf = m_vulkanWindow->currentCommandBuffer();
247 
248  // Bind our pipeline and retrieve layout
249  m_vulkanFuncs->vkCmdBindPipeline(currentcmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline);
250  VkPipelineLayout layout = m_vulkanShader->GetPipelineLayout();
251 
252  // Bind projection descriptor set
253  m_vulkanFuncs->vkCmdBindDescriptorSets(currentcmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS,
254  layout, 0, 1, &m_projectionDescriptor, 0, nullptr);
255 
256  // Iterate over vertex buffers - vertex buffers run oldest to newest, which
257  // ensures rendering is correct
258  float centrex = m_area.left() + m_area.width() / 2.0F;
259  float centrey = m_area.top() + m_area.height() / 2.0F;
260 
261  for (auto & vertex : m_vertexBuffers)
262  {
263  // Bind vertex buffer
264  VkDeviceSize offset = 0;
265  VkBuffer vbos { vertex.first->GetBuffer() };
266  m_vulkanFuncs->vkCmdBindVertexBuffers(currentcmdbuf, 0, 1, &vbos, &offset);
267 
268  // Set line width
269  m_vulkanFuncs->vkCmdSetLineWidth(currentcmdbuf,
270  std::clamp(m_lineWidth * vertex.second[2], 1.0F, m_maxLineWidth));
271 
272  // Push colour and transform
273  QMatrix4x4 transform;
274  if (m_fade)
275  {
276  transform.translate(centrex, centrey);
277  transform.scale(vertex.second[2]);
278  transform.translate(-centrex, -centrey);
279  }
280 
281  auto color = QColor::fromHsvF(static_cast<qreal>(vertex.second[0]), 1.0,
282  static_cast<qreal>(vertex.second[1]));
283 
284  memcpy(&m_pushBuffer.transform[0], transform.constData(), sizeof(float) * 16);
285  m_pushBuffer.color[0] = static_cast<float>(color.redF());
286  m_pushBuffer.color[1] = static_cast<float>(color.greenF());
287  m_pushBuffer.color[2] = static_cast<float>(color.blueF());
288  m_pushBuffer.color[3] = static_cast<float>(color.alphaF());
289 
290  m_vulkanFuncs->vkCmdPushConstants(currentcmdbuf, layout, VK_SHADER_STAGE_VERTEX_BIT,
291  0, sizeof(PushBuffer), &m_pushBuffer);
292 
293  // Draw
294  m_vulkanFuncs->vkCmdDraw(currentcmdbuf, NUM_SAMPLES, 1, 0, 0);
295  }
296 }
297 
299 {
300  if (m_disabled)
301  return nullptr;
302 
303  if (!IsValidVulkan())
304  return nullptr;
305 
306  if ((Area == m_area) && m_vulkanShader && m_pipeline &&
308  !m_vertexBuffers.empty())
309  {
310  return m_vulkanRender;
311  }
312 
313  TearDownVulkan();
314  InitCommon(Area);
315 
316  // Check wideLines support
317  // N.B. This still fails validation on Mesa for some reason
318  if (m_vulkanRender->GetPhysicalDeviceFeatures().wideLines)
319  {
321  }
322  else
323  {
324  m_lineWidth = 1.0;
325  m_maxLineWidth = 1.0;
326  }
327 
328  // Common init
330  return nullptr;
331 
332  // Create vertex buffer(s)
333  int size = m_fade ? 8 : 1;
334  while (m_vertexBuffers.size() < size)
335  m_vertexBuffers.push_back({MythBufferVulkan::Create(this, sizeof(float) * NUM_SAMPLES * 2), { }});
336 
337  if (m_vertexBuffers.size() == size)
338  return m_vulkanRender;
339  return nullptr;
340 }
341 
343 {
345  for (auto & vertex : m_vertexBuffers)
346  delete vertex.first;
347  m_vertexBuffers.clear();
348 }
349 
LineVertex450
#define LineVertex450
Definition: mythvisualmonoscopevulkan.cpp:8
VideoVisualMonoScope::UpdateVertices
bool UpdateVertices(float *Buffer)
Definition: videovisualmonoscope.cpp:31
MythVisualMonoScopeVulkan::m_pushBuffer
PushBuffer m_pushBuffer
Definition: mythvisualmonoscopevulkan.h:39
MythVisualVulkan::m_vulkanShader
MythShaderVulkan * m_vulkanShader
Definition: mythvisualvulkan.h:23
mythwindowvulkan.h
MythVisualMonoScopeVulkan::~MythVisualMonoScopeVulkan
~MythVisualMonoScopeVulkan() override
Definition: mythvisualmonoscopevulkan.cpp:196
AudioPlayer
Definition: audioplayer.h:28
VideoVisualMonoScope::m_maxLineWidth
float m_maxLineWidth
Definition: videovisualmonoscope.h:27
MythVisualVulkan::InitialiseVulkan
virtual MythRenderVulkan * InitialiseVulkan(QRect)
Definition: mythvisualvulkan.cpp:29
MythVisualVulkan
Definition: mythvisualvulkan.h:9
mythvisualmonoscopevulkan.h
MythVisualMonoScopeVulkan::m_vertexBuffers
VertexStates m_vertexBuffers
Definition: mythvisualmonoscopevulkan.h:38
VideoVisual::m_disabled
bool m_disabled
Definition: videovisual.h:70
MythVisualMonoScopeVulkan::MythVisualMonoScopeVulkan
MythVisualMonoScopeVulkan(AudioPlayer *Audio, MythRender *Render, bool Fade)
Definition: mythvisualmonoscopevulkan.cpp:186
PushBuffer::transform
float transform[16]
Definition: mythvisualmonoscopevulkan.h:20
MythRenderVulkan::GetPhysicalDeviceLimits
VkPhysicalDeviceLimits GetPhysicalDeviceLimits() const
Definition: mythrendervulkan.cpp:521
MythVisualMonoScopeVulkan::InitialiseVulkan
MythRenderVulkan * InitialiseVulkan(QRect Area) override
Definition: mythvisualmonoscopevulkan.cpp:298
MythVisualVulkan::m_projectionUniform
MythUniformBufferVulkan * m_projectionUniform
Definition: mythvisualvulkan.h:27
k450LineShaders
static const MythShaderMap k450LineShaders
Definition: mythvisualmonoscopevulkan.cpp:28
NUM_SAMPLES
#define NUM_SAMPLES
Definition: videovisualmonoscope.h:7
mythuniformbuffervulkan.h
MythRenderVulkan::GetPhysicalDeviceFeatures
VkPhysicalDeviceFeatures GetPhysicalDeviceFeatures() const
Definition: mythrendervulkan.cpp:516
MythVulkanObject::m_vulkanRender
MythRenderVulkan * m_vulkanRender
Definition: mythrendervulkan.h:45
MythShaderVulkan::GetPipelineLayout
VkPipelineLayout GetPipelineLayout(void) const
Definition: mythshadervulkan.cpp:458
clamp
float clamp(float val, float minimum, float maximum)
Definition: mythmiscutil.h:60
mythvertexbuffervulkan.h
LineFragment450
#define LineFragment450
Definition: mythvisualmonoscopevulkan.cpp:9
MythBufferVulkan::Create
static MythBufferVulkan * Create(MythVulkanObject *Vulkan, VkDeviceSize Size)
Definition: mythvertexbuffervulkan.cpp:7
MythVisualVulkan::m_descriptorPool
VkDescriptorPool m_descriptorPool
Definition: mythvisualvulkan.h:25
MythBindingMap
std::map< int, MythBindingDesc > MythBindingMap
Definition: mythshadervulkan.h:18
VideoVisualMonoScope::m_lineWidth
float m_lineWidth
Definition: videovisualmonoscope.h:26
MythVulkanObject::m_vulkanFuncs
QVulkanDeviceFunctions * m_vulkanFuncs
Definition: mythrendervulkan.h:47
MythVisualMonoScopeVulkan::TearDownVulkan
void TearDownVulkan() override
Definition: mythvisualmonoscopevulkan.cpp:342
PushBuffer::color
float color[4]
Definition: mythvisualmonoscopevulkan.h:21
MythVisualMonoScopeVulkan::Draw
void Draw(QRect Area, MythPainter *, QPaintDevice *) override
Definition: mythvisualmonoscopevulkan.cpp:237
MythVisualVulkan::TearDownVulkan
virtual void TearDownVulkan()
Definition: mythvisualvulkan.cpp:109
VideoVisualMonoScope
Definition: videovisualmonoscope.h:11
MythVisualVulkan::m_pipeline
VkPipeline m_pipeline
Definition: mythvisualvulkan.h:24
MythRender
Definition: mythrender_base.h:23
MythPainter
Definition: mythpainter.h:32
k450LineBindings
static const MythBindingMap k450LineBindings
Definition: mythvisualmonoscopevulkan.cpp:11
PushBuffer
Definition: mythvisualmonoscopevulkan.h:18
MythVulkanObject::m_vulkanWindow
MythWindowVulkan * m_vulkanWindow
Definition: mythrendervulkan.h:48
MythVulkanObject::IsValidVulkan
bool IsValidVulkan() const
Definition: mythrendervulkan.cpp:63
MythShaderMap
std::map< int, std::pair< QString, std::vector< uint32_t > >> MythShaderMap
Definition: mythshadervulkan.h:7
MythRenderVulkan
Definition: mythrendervulkan.h:54
VideoVisualMonoScope::m_hue
float m_hue
Definition: videovisualmonoscope.h:24
VideoVisual::m_area
QRect m_area
Definition: videovisual.h:71
VideoVisualMonoScope::m_rate
float m_rate
Definition: videovisualmonoscope.h:25
mythshadersvulkan.h
VideoVisualMonoScope::m_fade
bool m_fade
Definition: videovisualmonoscope.h:28
VideoVisualMonoScope::InitCommon
void InitCommon(QRect Area)
Definition: videovisualmonoscope.cpp:22
VideoVisualMonoScope::UpdateTime
void UpdateTime()
Definition: videovisualmonoscope.cpp:71
MythVisualVulkan::m_projectionDescriptor
VkDescriptorSet m_projectionDescriptor
Definition: mythvisualvulkan.h:26
MythVisualMonoScopeVulkan::Prepare
void Prepare(QRect Area) override
Definition: mythvisualmonoscopevulkan.cpp:201