<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>renderer.cpp Example File | Qt GUI 5.12.6</title> <link rel="stylesheet" type="text/css" href="style/offline-simple.css" /> <script type="text/javascript"> document.getElementsByTagName("link").item(0).setAttribute("href", "style/offline.css"); // loading style sheet breaks anchors that were jumped to before // so force jumping to anchor again setTimeout(function() { var anchor = location.hash; // need to jump to different anchor first (e.g. none) location.hash = "#"; setTimeout(function() { location.hash = anchor; }, 0); }, 0); </script> </head> <body> <div class="header" id="qtdocheader"> <div class="main"> <div class="main-rounded"> <div class="navigationbar"> <table><tr> <td >Qt 5.12</td><td ><a href="qtgui-index.html">Qt GUI</a></td><td ><a href="qtgui-hellovulkancubes-example.html">Hello Vulkan Cubes Example</a></td><td >renderer.cpp Example File</td></tr></table><table class="buildversion"><tr> <td id="buildversion" width="100%" align="right"><a href="qtgui-index.html">Qt 5.12.6 Reference Documentation</a></td> </tr></table> </div> </div> <div class="content"> <div class="line"> <div class="content mainContent"> <div class="sidebar"><div class="sidebar-content" id="sidebar-content"></div></div> <h1 class="title">renderer.cpp Example File</h1> <span class="subtitle">hellovulkancubes/renderer.cpp</span> <!-- $$$hellovulkancubes/renderer.cpp-description --> <div class="descr"> <a name="details"></a> <pre class="cpp"> <span class="comment">/**************************************************************************** ** ** Copyright (C) 2017 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** BSD License Usage ** Alternatively, you may use this file under the terms of the BSD license ** as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of The Qt Company Ltd nor the names of its ** contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/</span> <span class="preprocessor">#include "renderer.h"</span> <span class="preprocessor">#include <QVulkanFunctions></span> <span class="preprocessor">#include <QtConcurrentRun></span> <span class="preprocessor">#include <QTime></span> <span class="keyword">static</span> <span class="type">float</span> quadVert<span class="operator">[</span><span class="operator">]</span> <span class="operator">=</span> { <span class="comment">// Y up, front = CW</span> <span class="operator">-</span><span class="number">1</span><span class="operator">,</span> <span class="operator">-</span><span class="number">1</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="operator">-</span><span class="number">1</span><span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="operator">-</span><span class="number">1</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="number">0</span> }; <span class="preprocessor">#define DBG Q_UNLIKELY(m_window->isDebugEnabled())</span> <span class="keyword">const</span> <span class="type">int</span> MAX_INSTANCES <span class="operator">=</span> <span class="number">16384</span>; <span class="keyword">const</span> VkDeviceSize PER_INSTANCE_DATA_SIZE <span class="operator">=</span> <span class="number">6</span> <span class="operator">*</span> <span class="keyword">sizeof</span>(<span class="type">float</span>); <span class="comment">// instTranslate, instDiffuseAdjust</span> <span class="keyword">static</span> <span class="keyword">inline</span> VkDeviceSize aligned(VkDeviceSize v<span class="operator">,</span> VkDeviceSize byteAlign) { <span class="keyword">return</span> (v <span class="operator">+</span> byteAlign <span class="operator">-</span> <span class="number">1</span>) <span class="operator">&</span> <span class="operator">~</span>(byteAlign <span class="operator">-</span> <span class="number">1</span>); } Renderer<span class="operator">::</span>Renderer(VulkanWindow <span class="operator">*</span>w<span class="operator">,</span> <span class="type">int</span> initialCount) : m_window(w)<span class="operator">,</span> <span class="comment">// Have the light positioned just behind the default camera position, looking forward.</span> m_lightPos(<span class="number">0.0f</span><span class="operator">,</span> <span class="number">0.0f</span><span class="operator">,</span> <span class="number">25.0f</span>)<span class="operator">,</span> m_cam(QVector3D(<span class="number">0.0f</span><span class="operator">,</span> <span class="number">0.0f</span><span class="operator">,</span> <span class="number">20.0f</span>))<span class="operator">,</span> <span class="comment">// starting camera position</span> m_instCount(initialCount) { qsrand(<span class="type"><a href="../qtcore/qtime.html">QTime</a></span>(<span class="number">0</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="number">0</span>)<span class="operator">.</span>secsTo(<span class="type"><a href="../qtcore/qtime.html">QTime</a></span><span class="operator">::</span>currentTime())); m_floorModel<span class="operator">.</span>translate(<span class="number">0</span><span class="operator">,</span> <span class="operator">-</span><span class="number">5</span><span class="operator">,</span> <span class="number">0</span>); m_floorModel<span class="operator">.</span>rotate(<span class="operator">-</span><span class="number">90</span><span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="number">0</span>); m_floorModel<span class="operator">.</span>scale(<span class="number">20</span><span class="operator">,</span> <span class="number">100</span><span class="operator">,</span> <span class="number">1</span>); m_blockMesh<span class="operator">.</span>load(<span class="type"><a href="../qtcore/qstring.html#QStringLiteral">QStringLiteral</a></span>(<span class="string">":/block.buf"</span>)); m_logoMesh<span class="operator">.</span>load(<span class="type"><a href="../qtcore/qstring.html#QStringLiteral">QStringLiteral</a></span>(<span class="string">":/qt_logo.buf"</span>)); <span class="type"><a href="../qtcore/qobject.html">QObject</a></span><span class="operator">::</span>connect(<span class="operator">&</span>m_frameWatcher<span class="operator">,</span> <span class="operator">&</span><span class="type"><a href="../qtcore/qfuturewatcherbase.html">QFutureWatcherBase</a></span><span class="operator">::</span>finished<span class="operator">,</span> <span class="operator">[</span><span class="keyword">this</span><span class="operator">]</span> { <span class="keyword">if</span> (m_framePending) { m_framePending <span class="operator">=</span> <span class="keyword">false</span>; m_window<span class="operator">-</span><span class="operator">></span>frameReady(); m_window<span class="operator">-</span><span class="operator">></span>requestUpdate(); } }); } <span class="type">void</span> Renderer<span class="operator">::</span>preInitResources() { <span class="keyword">const</span> <span class="type"><a href="../qtcore/qvector.html">QVector</a></span><span class="operator"><</span><span class="type">int</span><span class="operator">></span> sampleCounts <span class="operator">=</span> m_window<span class="operator">-</span><span class="operator">></span>supportedSampleCounts(); <span class="keyword">if</span> (DBG) <a href="../qtcore/qtglobal.html#qDebug">qDebug</a>() <span class="operator"><</span><span class="operator"><</span> <span class="string">"Supported sample counts:"</span> <span class="operator"><</span><span class="operator"><</span> sampleCounts; <span class="keyword">if</span> (sampleCounts<span class="operator">.</span>contains(<span class="number">4</span>)) { <span class="keyword">if</span> (DBG) <a href="../qtcore/qtglobal.html#qDebug">qDebug</a>(<span class="string">"Requesting 4x MSAA"</span>); m_window<span class="operator">-</span><span class="operator">></span>setSampleCount(<span class="number">4</span>); } } <span class="type">void</span> Renderer<span class="operator">::</span>initResources() { <span class="keyword">if</span> (DBG) <a href="../qtcore/qtglobal.html#qDebug">qDebug</a>(<span class="string">"Renderer init"</span>); m_animating <span class="operator">=</span> <span class="keyword">true</span>; m_framePending <span class="operator">=</span> <span class="keyword">false</span>; <span class="type"><a href="qvulkaninstance.html">QVulkanInstance</a></span> <span class="operator">*</span>inst <span class="operator">=</span> m_window<span class="operator">-</span><span class="operator">></span>vulkanInstance(); VkDevice dev <span class="operator">=</span> m_window<span class="operator">-</span><span class="operator">></span>device(); <span class="keyword">const</span> VkPhysicalDeviceLimits <span class="operator">*</span>pdevLimits <span class="operator">=</span> <span class="operator">&</span>m_window<span class="operator">-</span><span class="operator">></span>physicalDeviceProperties()<span class="operator">-</span><span class="operator">></span>limits; <span class="keyword">const</span> VkDeviceSize uniAlign <span class="operator">=</span> pdevLimits<span class="operator">-</span><span class="operator">></span>minUniformBufferOffsetAlignment; m_devFuncs <span class="operator">=</span> inst<span class="operator">-</span><span class="operator">></span>deviceFunctions(dev); <span class="comment">// Note the std140 packing rules. A vec3 still has an alignment of 16,</span> <span class="comment">// while a mat3 is like 3 * vec3.</span> m_itemMaterial<span class="operator">.</span>vertUniSize <span class="operator">=</span> aligned(<span class="number">2</span> <span class="operator">*</span> <span class="number">64</span> <span class="operator">+</span> <span class="number">48</span><span class="operator">,</span> uniAlign); <span class="comment">// see color_phong.vert</span> m_itemMaterial<span class="operator">.</span>fragUniSize <span class="operator">=</span> aligned(<span class="number">6</span> <span class="operator">*</span> <span class="number">16</span> <span class="operator">+</span> <span class="number">12</span> <span class="operator">+</span> <span class="number">2</span> <span class="operator">*</span> <span class="number">4</span><span class="operator">,</span> uniAlign); <span class="comment">// see color_phong.frag</span> <span class="keyword">if</span> (<span class="operator">!</span>m_itemMaterial<span class="operator">.</span>vs<span class="operator">.</span>isValid()) m_itemMaterial<span class="operator">.</span>vs<span class="operator">.</span>load(inst<span class="operator">,</span> dev<span class="operator">,</span> <span class="type"><a href="../qtcore/qstring.html#QStringLiteral">QStringLiteral</a></span>(<span class="string">":/color_phong_vert.spv"</span>)); <span class="keyword">if</span> (<span class="operator">!</span>m_itemMaterial<span class="operator">.</span>fs<span class="operator">.</span>isValid()) m_itemMaterial<span class="operator">.</span>fs<span class="operator">.</span>load(inst<span class="operator">,</span> dev<span class="operator">,</span> <span class="type"><a href="../qtcore/qstring.html#QStringLiteral">QStringLiteral</a></span>(<span class="string">":/color_phong_frag.spv"</span>)); <span class="keyword">if</span> (<span class="operator">!</span>m_floorMaterial<span class="operator">.</span>vs<span class="operator">.</span>isValid()) m_floorMaterial<span class="operator">.</span>vs<span class="operator">.</span>load(inst<span class="operator">,</span> dev<span class="operator">,</span> <span class="type"><a href="../qtcore/qstring.html#QStringLiteral">QStringLiteral</a></span>(<span class="string">":/color_vert.spv"</span>)); <span class="keyword">if</span> (<span class="operator">!</span>m_floorMaterial<span class="operator">.</span>fs<span class="operator">.</span>isValid()) m_floorMaterial<span class="operator">.</span>fs<span class="operator">.</span>load(inst<span class="operator">,</span> dev<span class="operator">,</span> <span class="type"><a href="../qtcore/qstring.html#QStringLiteral">QStringLiteral</a></span>(<span class="string">":/color_frag.spv"</span>)); m_pipelinesFuture <span class="operator">=</span> <span class="type">QtConcurrent</span><span class="operator">::</span>run(<span class="keyword">this</span><span class="operator">,</span> <span class="operator">&</span>Renderer<span class="operator">::</span>createPipelines); } <span class="type">void</span> Renderer<span class="operator">::</span>createPipelines() { VkDevice dev <span class="operator">=</span> m_window<span class="operator">-</span><span class="operator">></span>device(); VkPipelineCacheCreateInfo pipelineCacheInfo; memset(<span class="operator">&</span>pipelineCacheInfo<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="keyword">sizeof</span>(pipelineCacheInfo)); pipelineCacheInfo<span class="operator">.</span>sType <span class="operator">=</span> VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; VkResult err <span class="operator">=</span> m_devFuncs<span class="operator">-</span><span class="operator">></span>vkCreatePipelineCache(dev<span class="operator">,</span> <span class="operator">&</span>pipelineCacheInfo<span class="operator">,</span> nullptr<span class="operator">,</span> <span class="operator">&</span>m_pipelineCache); <span class="keyword">if</span> (err <span class="operator">!</span><span class="operator">=</span> VK_SUCCESS) <a href="../qtcore/qtglobal.html#qFatal">qFatal</a>(<span class="string">"Failed to create pipeline cache: %d"</span><span class="operator">,</span> err); createItemPipeline(); createFloorPipeline(); } <span class="type">void</span> Renderer<span class="operator">::</span>createItemPipeline() { VkDevice dev <span class="operator">=</span> m_window<span class="operator">-</span><span class="operator">></span>device(); <span class="comment">// Vertex layout.</span> VkVertexInputBindingDescription vertexBindingDesc<span class="operator">[</span><span class="operator">]</span> <span class="operator">=</span> { { <span class="number">0</span><span class="operator">,</span> <span class="comment">// binding</span> <span class="number">8</span> <span class="operator">*</span> <span class="keyword">sizeof</span>(<span class="type">float</span>)<span class="operator">,</span> VK_VERTEX_INPUT_RATE_VERTEX }<span class="operator">,</span> { <span class="number">1</span><span class="operator">,</span> <span class="number">6</span> <span class="operator">*</span> <span class="keyword">sizeof</span>(<span class="type">float</span>)<span class="operator">,</span> VK_VERTEX_INPUT_RATE_INSTANCE } }; VkVertexInputAttributeDescription vertexAttrDesc<span class="operator">[</span><span class="operator">]</span> <span class="operator">=</span> { { <span class="comment">// position</span> <span class="number">0</span><span class="operator">,</span> <span class="comment">// location</span> <span class="number">0</span><span class="operator">,</span> <span class="comment">// binding</span> VK_FORMAT_R32G32B32_SFLOAT<span class="operator">,</span> <span class="number">0</span> <span class="comment">// offset</span> }<span class="operator">,</span> { <span class="comment">// normal</span> <span class="number">1</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> VK_FORMAT_R32G32B32_SFLOAT<span class="operator">,</span> <span class="number">5</span> <span class="operator">*</span> <span class="keyword">sizeof</span>(<span class="type">float</span>) }<span class="operator">,</span> { <span class="comment">// instTranslate</span> <span class="number">2</span><span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> VK_FORMAT_R32G32B32_SFLOAT<span class="operator">,</span> <span class="number">0</span> }<span class="operator">,</span> { <span class="comment">// instDiffuseAdjust</span> <span class="number">3</span><span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> VK_FORMAT_R32G32B32_SFLOAT<span class="operator">,</span> <span class="number">3</span> <span class="operator">*</span> <span class="keyword">sizeof</span>(<span class="type">float</span>) } }; VkPipelineVertexInputStateCreateInfo vertexInputInfo; vertexInputInfo<span class="operator">.</span>sType <span class="operator">=</span> VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; vertexInputInfo<span class="operator">.</span>pNext <span class="operator">=</span> nullptr; vertexInputInfo<span class="operator">.</span>flags <span class="operator">=</span> <span class="number">0</span>; vertexInputInfo<span class="operator">.</span>vertexBindingDescriptionCount <span class="operator">=</span> <span class="keyword">sizeof</span>(vertexBindingDesc) <span class="operator">/</span> <span class="keyword">sizeof</span>(vertexBindingDesc<span class="operator">[</span><span class="number">0</span><span class="operator">]</span>); vertexInputInfo<span class="operator">.</span>pVertexBindingDescriptions <span class="operator">=</span> vertexBindingDesc; vertexInputInfo<span class="operator">.</span>vertexAttributeDescriptionCount <span class="operator">=</span> <span class="keyword">sizeof</span>(vertexAttrDesc) <span class="operator">/</span> <span class="keyword">sizeof</span>(vertexAttrDesc<span class="operator">[</span><span class="number">0</span><span class="operator">]</span>); vertexInputInfo<span class="operator">.</span>pVertexAttributeDescriptions <span class="operator">=</span> vertexAttrDesc; <span class="comment">// Descriptor set layout.</span> VkDescriptorPoolSize descPoolSizes<span class="operator">[</span><span class="operator">]</span> <span class="operator">=</span> { { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC<span class="operator">,</span> <span class="number">2</span> } }; VkDescriptorPoolCreateInfo descPoolInfo; memset(<span class="operator">&</span>descPoolInfo<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="keyword">sizeof</span>(descPoolInfo)); descPoolInfo<span class="operator">.</span>sType <span class="operator">=</span> VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; descPoolInfo<span class="operator">.</span>maxSets <span class="operator">=</span> <span class="number">1</span>; <span class="comment">// a single set is enough due to the dynamic uniform buffer</span> descPoolInfo<span class="operator">.</span>poolSizeCount <span class="operator">=</span> <span class="keyword">sizeof</span>(descPoolSizes) <span class="operator">/</span> <span class="keyword">sizeof</span>(descPoolSizes<span class="operator">[</span><span class="number">0</span><span class="operator">]</span>); descPoolInfo<span class="operator">.</span>pPoolSizes <span class="operator">=</span> descPoolSizes; VkResult err <span class="operator">=</span> m_devFuncs<span class="operator">-</span><span class="operator">></span>vkCreateDescriptorPool(dev<span class="operator">,</span> <span class="operator">&</span>descPoolInfo<span class="operator">,</span> nullptr<span class="operator">,</span> <span class="operator">&</span>m_itemMaterial<span class="operator">.</span>descPool); <span class="keyword">if</span> (err <span class="operator">!</span><span class="operator">=</span> VK_SUCCESS) <a href="../qtcore/qtglobal.html#qFatal">qFatal</a>(<span class="string">"Failed to create descriptor pool: %d"</span><span class="operator">,</span> err); VkDescriptorSetLayoutBinding layoutBindings<span class="operator">[</span><span class="operator">]</span> <span class="operator">=</span> { { <span class="number">0</span><span class="operator">,</span> <span class="comment">// binding</span> VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC<span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="comment">// descriptorCount</span> VK_SHADER_STAGE_VERTEX_BIT<span class="operator">,</span> nullptr }<span class="operator">,</span> { <span class="number">1</span><span class="operator">,</span> VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC<span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> VK_SHADER_STAGE_FRAGMENT_BIT<span class="operator">,</span> nullptr } }; VkDescriptorSetLayoutCreateInfo descLayoutInfo <span class="operator">=</span> { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO<span class="operator">,</span> nullptr<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="keyword">sizeof</span>(layoutBindings) <span class="operator">/</span> <span class="keyword">sizeof</span>(layoutBindings<span class="operator">[</span><span class="number">0</span><span class="operator">]</span>)<span class="operator">,</span> layoutBindings }; err <span class="operator">=</span> m_devFuncs<span class="operator">-</span><span class="operator">></span>vkCreateDescriptorSetLayout(dev<span class="operator">,</span> <span class="operator">&</span>descLayoutInfo<span class="operator">,</span> nullptr<span class="operator">,</span> <span class="operator">&</span>m_itemMaterial<span class="operator">.</span>descSetLayout); <span class="keyword">if</span> (err <span class="operator">!</span><span class="operator">=</span> VK_SUCCESS) <a href="../qtcore/qtglobal.html#qFatal">qFatal</a>(<span class="string">"Failed to create descriptor set layout: %d"</span><span class="operator">,</span> err); VkDescriptorSetAllocateInfo descSetAllocInfo <span class="operator">=</span> { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO<span class="operator">,</span> nullptr<span class="operator">,</span> m_itemMaterial<span class="operator">.</span>descPool<span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="operator">&</span>m_itemMaterial<span class="operator">.</span>descSetLayout }; err <span class="operator">=</span> m_devFuncs<span class="operator">-</span><span class="operator">></span>vkAllocateDescriptorSets(dev<span class="operator">,</span> <span class="operator">&</span>descSetAllocInfo<span class="operator">,</span> <span class="operator">&</span>m_itemMaterial<span class="operator">.</span>descSet); <span class="keyword">if</span> (err <span class="operator">!</span><span class="operator">=</span> VK_SUCCESS) <a href="../qtcore/qtglobal.html#qFatal">qFatal</a>(<span class="string">"Failed to allocate descriptor set: %d"</span><span class="operator">,</span> err); <span class="comment">// Graphics pipeline.</span> VkPipelineLayoutCreateInfo pipelineLayoutInfo; memset(<span class="operator">&</span>pipelineLayoutInfo<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="keyword">sizeof</span>(pipelineLayoutInfo)); pipelineLayoutInfo<span class="operator">.</span>sType <span class="operator">=</span> VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; pipelineLayoutInfo<span class="operator">.</span>setLayoutCount <span class="operator">=</span> <span class="number">1</span>; pipelineLayoutInfo<span class="operator">.</span>pSetLayouts <span class="operator">=</span> <span class="operator">&</span>m_itemMaterial<span class="operator">.</span>descSetLayout; err <span class="operator">=</span> m_devFuncs<span class="operator">-</span><span class="operator">></span>vkCreatePipelineLayout(dev<span class="operator">,</span> <span class="operator">&</span>pipelineLayoutInfo<span class="operator">,</span> nullptr<span class="operator">,</span> <span class="operator">&</span>m_itemMaterial<span class="operator">.</span>pipelineLayout); <span class="keyword">if</span> (err <span class="operator">!</span><span class="operator">=</span> VK_SUCCESS) <a href="../qtcore/qtglobal.html#qFatal">qFatal</a>(<span class="string">"Failed to create pipeline layout: %d"</span><span class="operator">,</span> err); VkGraphicsPipelineCreateInfo pipelineInfo; memset(<span class="operator">&</span>pipelineInfo<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="keyword">sizeof</span>(pipelineInfo)); pipelineInfo<span class="operator">.</span>sType <span class="operator">=</span> VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; VkPipelineShaderStageCreateInfo shaderStages<span class="operator">[</span><span class="number">2</span><span class="operator">]</span> <span class="operator">=</span> { { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO<span class="operator">,</span> nullptr<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> VK_SHADER_STAGE_VERTEX_BIT<span class="operator">,</span> m_itemMaterial<span class="operator">.</span>vs<span class="operator">.</span>data()<span class="operator">-</span><span class="operator">></span>shaderModule<span class="operator">,</span> <span class="string">"main"</span><span class="operator">,</span> nullptr }<span class="operator">,</span> { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO<span class="operator">,</span> nullptr<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> VK_SHADER_STAGE_FRAGMENT_BIT<span class="operator">,</span> m_itemMaterial<span class="operator">.</span>fs<span class="operator">.</span>data()<span class="operator">-</span><span class="operator">></span>shaderModule<span class="operator">,</span> <span class="string">"main"</span><span class="operator">,</span> nullptr } }; pipelineInfo<span class="operator">.</span>stageCount <span class="operator">=</span> <span class="number">2</span>; pipelineInfo<span class="operator">.</span>pStages <span class="operator">=</span> shaderStages; pipelineInfo<span class="operator">.</span>pVertexInputState <span class="operator">=</span> <span class="operator">&</span>vertexInputInfo; VkPipelineInputAssemblyStateCreateInfo ia; memset(<span class="operator">&</span>ia<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="keyword">sizeof</span>(ia)); ia<span class="operator">.</span>sType <span class="operator">=</span> VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; ia<span class="operator">.</span>topology <span class="operator">=</span> VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; pipelineInfo<span class="operator">.</span>pInputAssemblyState <span class="operator">=</span> <span class="operator">&</span>ia; VkPipelineViewportStateCreateInfo vp; memset(<span class="operator">&</span>vp<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="keyword">sizeof</span>(vp)); vp<span class="operator">.</span>sType <span class="operator">=</span> VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; vp<span class="operator">.</span>viewportCount <span class="operator">=</span> <span class="number">1</span>; vp<span class="operator">.</span>scissorCount <span class="operator">=</span> <span class="number">1</span>; pipelineInfo<span class="operator">.</span>pViewportState <span class="operator">=</span> <span class="operator">&</span>vp; VkPipelineRasterizationStateCreateInfo rs; memset(<span class="operator">&</span>rs<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="keyword">sizeof</span>(rs)); rs<span class="operator">.</span>sType <span class="operator">=</span> VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; rs<span class="operator">.</span>polygonMode <span class="operator">=</span> VK_POLYGON_MODE_FILL; rs<span class="operator">.</span>cullMode <span class="operator">=</span> VK_CULL_MODE_BACK_BIT; rs<span class="operator">.</span>frontFace <span class="operator">=</span> VK_FRONT_FACE_COUNTER_CLOCKWISE; rs<span class="operator">.</span>lineWidth <span class="operator">=</span> <span class="number">1.0f</span>; pipelineInfo<span class="operator">.</span>pRasterizationState <span class="operator">=</span> <span class="operator">&</span>rs; VkPipelineMultisampleStateCreateInfo ms; memset(<span class="operator">&</span>ms<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="keyword">sizeof</span>(ms)); ms<span class="operator">.</span>sType <span class="operator">=</span> VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; ms<span class="operator">.</span>rasterizationSamples <span class="operator">=</span> m_window<span class="operator">-</span><span class="operator">></span>sampleCountFlagBits(); pipelineInfo<span class="operator">.</span>pMultisampleState <span class="operator">=</span> <span class="operator">&</span>ms; VkPipelineDepthStencilStateCreateInfo ds; memset(<span class="operator">&</span>ds<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="keyword">sizeof</span>(ds)); ds<span class="operator">.</span>sType <span class="operator">=</span> VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; ds<span class="operator">.</span>depthTestEnable <span class="operator">=</span> VK_TRUE; ds<span class="operator">.</span>depthWriteEnable <span class="operator">=</span> VK_TRUE; ds<span class="operator">.</span>depthCompareOp <span class="operator">=</span> VK_COMPARE_OP_LESS_OR_EQUAL; pipelineInfo<span class="operator">.</span>pDepthStencilState <span class="operator">=</span> <span class="operator">&</span>ds; VkPipelineColorBlendStateCreateInfo cb; memset(<span class="operator">&</span>cb<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="keyword">sizeof</span>(cb)); cb<span class="operator">.</span>sType <span class="operator">=</span> VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; VkPipelineColorBlendAttachmentState att; memset(<span class="operator">&</span>att<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="keyword">sizeof</span>(att)); att<span class="operator">.</span>colorWriteMask <span class="operator">=</span> <span class="number">0xF</span>; cb<span class="operator">.</span>attachmentCount <span class="operator">=</span> <span class="number">1</span>; cb<span class="operator">.</span>pAttachments <span class="operator">=</span> <span class="operator">&</span>att; pipelineInfo<span class="operator">.</span>pColorBlendState <span class="operator">=</span> <span class="operator">&</span>cb; VkDynamicState dynEnable<span class="operator">[</span><span class="operator">]</span> <span class="operator">=</span> { VK_DYNAMIC_STATE_VIEWPORT<span class="operator">,</span> VK_DYNAMIC_STATE_SCISSOR }; VkPipelineDynamicStateCreateInfo dyn; memset(<span class="operator">&</span>dyn<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="keyword">sizeof</span>(dyn)); dyn<span class="operator">.</span>sType <span class="operator">=</span> VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; dyn<span class="operator">.</span>dynamicStateCount <span class="operator">=</span> <span class="keyword">sizeof</span>(dynEnable) <span class="operator">/</span> <span class="keyword">sizeof</span>(VkDynamicState); dyn<span class="operator">.</span>pDynamicStates <span class="operator">=</span> dynEnable; pipelineInfo<span class="operator">.</span>pDynamicState <span class="operator">=</span> <span class="operator">&</span>dyn; pipelineInfo<span class="operator">.</span>layout <span class="operator">=</span> m_itemMaterial<span class="operator">.</span>pipelineLayout; pipelineInfo<span class="operator">.</span>renderPass <span class="operator">=</span> m_window<span class="operator">-</span><span class="operator">></span>defaultRenderPass(); err <span class="operator">=</span> m_devFuncs<span class="operator">-</span><span class="operator">></span>vkCreateGraphicsPipelines(dev<span class="operator">,</span> m_pipelineCache<span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="operator">&</span>pipelineInfo<span class="operator">,</span> nullptr<span class="operator">,</span> <span class="operator">&</span>m_itemMaterial<span class="operator">.</span>pipeline); <span class="keyword">if</span> (err <span class="operator">!</span><span class="operator">=</span> VK_SUCCESS) <a href="../qtcore/qtglobal.html#qFatal">qFatal</a>(<span class="string">"Failed to create graphics pipeline: %d"</span><span class="operator">,</span> err); } <span class="type">void</span> Renderer<span class="operator">::</span>createFloorPipeline() { VkDevice dev <span class="operator">=</span> m_window<span class="operator">-</span><span class="operator">></span>device(); <span class="comment">// Vertex layout.</span> VkVertexInputBindingDescription vertexBindingDesc <span class="operator">=</span> { <span class="number">0</span><span class="operator">,</span> <span class="comment">// binding</span> <span class="number">3</span> <span class="operator">*</span> <span class="keyword">sizeof</span>(<span class="type">float</span>)<span class="operator">,</span> VK_VERTEX_INPUT_RATE_VERTEX }; VkVertexInputAttributeDescription vertexAttrDesc<span class="operator">[</span><span class="operator">]</span> <span class="operator">=</span> { { <span class="comment">// position</span> <span class="number">0</span><span class="operator">,</span> <span class="comment">// location</span> <span class="number">0</span><span class="operator">,</span> <span class="comment">// binding</span> VK_FORMAT_R32G32B32_SFLOAT<span class="operator">,</span> <span class="number">0</span> <span class="comment">// offset</span> }<span class="operator">,</span> }; VkPipelineVertexInputStateCreateInfo vertexInputInfo; vertexInputInfo<span class="operator">.</span>sType <span class="operator">=</span> VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; vertexInputInfo<span class="operator">.</span>pNext <span class="operator">=</span> nullptr; vertexInputInfo<span class="operator">.</span>flags <span class="operator">=</span> <span class="number">0</span>; vertexInputInfo<span class="operator">.</span>vertexBindingDescriptionCount <span class="operator">=</span> <span class="number">1</span>; vertexInputInfo<span class="operator">.</span>pVertexBindingDescriptions <span class="operator">=</span> <span class="operator">&</span>vertexBindingDesc; vertexInputInfo<span class="operator">.</span>vertexAttributeDescriptionCount <span class="operator">=</span> <span class="keyword">sizeof</span>(vertexAttrDesc) <span class="operator">/</span> <span class="keyword">sizeof</span>(vertexAttrDesc<span class="operator">[</span><span class="number">0</span><span class="operator">]</span>); vertexInputInfo<span class="operator">.</span>pVertexAttributeDescriptions <span class="operator">=</span> vertexAttrDesc; <span class="comment">// Do not bother with uniform buffers and descriptors, all the data fits</span> <span class="comment">// into the spec mandated minimum of 128 bytes for push constants.</span> VkPushConstantRange pcr<span class="operator">[</span><span class="operator">]</span> <span class="operator">=</span> { <span class="comment">// mvp</span> { VK_SHADER_STAGE_VERTEX_BIT<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="number">64</span> }<span class="operator">,</span> <span class="comment">// color</span> { VK_SHADER_STAGE_FRAGMENT_BIT<span class="operator">,</span> <span class="number">64</span><span class="operator">,</span> <span class="number">12</span> } }; VkPipelineLayoutCreateInfo pipelineLayoutInfo; memset(<span class="operator">&</span>pipelineLayoutInfo<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="keyword">sizeof</span>(pipelineLayoutInfo)); pipelineLayoutInfo<span class="operator">.</span>sType <span class="operator">=</span> VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; pipelineLayoutInfo<span class="operator">.</span>pushConstantRangeCount <span class="operator">=</span> <span class="keyword">sizeof</span>(pcr) <span class="operator">/</span> <span class="keyword">sizeof</span>(pcr<span class="operator">[</span><span class="number">0</span><span class="operator">]</span>); pipelineLayoutInfo<span class="operator">.</span>pPushConstantRanges <span class="operator">=</span> pcr; VkResult err <span class="operator">=</span> m_devFuncs<span class="operator">-</span><span class="operator">></span>vkCreatePipelineLayout(dev<span class="operator">,</span> <span class="operator">&</span>pipelineLayoutInfo<span class="operator">,</span> nullptr<span class="operator">,</span> <span class="operator">&</span>m_floorMaterial<span class="operator">.</span>pipelineLayout); <span class="keyword">if</span> (err <span class="operator">!</span><span class="operator">=</span> VK_SUCCESS) <a href="../qtcore/qtglobal.html#qFatal">qFatal</a>(<span class="string">"Failed to create pipeline layout: %d"</span><span class="operator">,</span> err); VkGraphicsPipelineCreateInfo pipelineInfo; memset(<span class="operator">&</span>pipelineInfo<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="keyword">sizeof</span>(pipelineInfo)); pipelineInfo<span class="operator">.</span>sType <span class="operator">=</span> VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; VkPipelineShaderStageCreateInfo shaderStages<span class="operator">[</span><span class="number">2</span><span class="operator">]</span> <span class="operator">=</span> { { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO<span class="operator">,</span> nullptr<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> VK_SHADER_STAGE_VERTEX_BIT<span class="operator">,</span> m_floorMaterial<span class="operator">.</span>vs<span class="operator">.</span>data()<span class="operator">-</span><span class="operator">></span>shaderModule<span class="operator">,</span> <span class="string">"main"</span><span class="operator">,</span> nullptr }<span class="operator">,</span> { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO<span class="operator">,</span> nullptr<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> VK_SHADER_STAGE_FRAGMENT_BIT<span class="operator">,</span> m_floorMaterial<span class="operator">.</span>fs<span class="operator">.</span>data()<span class="operator">-</span><span class="operator">></span>shaderModule<span class="operator">,</span> <span class="string">"main"</span><span class="operator">,</span> nullptr } }; pipelineInfo<span class="operator">.</span>stageCount <span class="operator">=</span> <span class="number">2</span>; pipelineInfo<span class="operator">.</span>pStages <span class="operator">=</span> shaderStages; pipelineInfo<span class="operator">.</span>pVertexInputState <span class="operator">=</span> <span class="operator">&</span>vertexInputInfo; VkPipelineInputAssemblyStateCreateInfo ia; memset(<span class="operator">&</span>ia<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="keyword">sizeof</span>(ia)); ia<span class="operator">.</span>sType <span class="operator">=</span> VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; ia<span class="operator">.</span>topology <span class="operator">=</span> VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; pipelineInfo<span class="operator">.</span>pInputAssemblyState <span class="operator">=</span> <span class="operator">&</span>ia; VkPipelineViewportStateCreateInfo vp; memset(<span class="operator">&</span>vp<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="keyword">sizeof</span>(vp)); vp<span class="operator">.</span>sType <span class="operator">=</span> VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; vp<span class="operator">.</span>viewportCount <span class="operator">=</span> <span class="number">1</span>; vp<span class="operator">.</span>scissorCount <span class="operator">=</span> <span class="number">1</span>; pipelineInfo<span class="operator">.</span>pViewportState <span class="operator">=</span> <span class="operator">&</span>vp; VkPipelineRasterizationStateCreateInfo rs; memset(<span class="operator">&</span>rs<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="keyword">sizeof</span>(rs)); rs<span class="operator">.</span>sType <span class="operator">=</span> VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; rs<span class="operator">.</span>polygonMode <span class="operator">=</span> VK_POLYGON_MODE_FILL; rs<span class="operator">.</span>cullMode <span class="operator">=</span> VK_CULL_MODE_BACK_BIT; rs<span class="operator">.</span>frontFace <span class="operator">=</span> VK_FRONT_FACE_CLOCKWISE; rs<span class="operator">.</span>lineWidth <span class="operator">=</span> <span class="number">1.0f</span>; pipelineInfo<span class="operator">.</span>pRasterizationState <span class="operator">=</span> <span class="operator">&</span>rs; VkPipelineMultisampleStateCreateInfo ms; memset(<span class="operator">&</span>ms<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="keyword">sizeof</span>(ms)); ms<span class="operator">.</span>sType <span class="operator">=</span> VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; ms<span class="operator">.</span>rasterizationSamples <span class="operator">=</span> m_window<span class="operator">-</span><span class="operator">></span>sampleCountFlagBits(); pipelineInfo<span class="operator">.</span>pMultisampleState <span class="operator">=</span> <span class="operator">&</span>ms; VkPipelineDepthStencilStateCreateInfo ds; memset(<span class="operator">&</span>ds<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="keyword">sizeof</span>(ds)); ds<span class="operator">.</span>sType <span class="operator">=</span> VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; ds<span class="operator">.</span>depthTestEnable <span class="operator">=</span> VK_TRUE; ds<span class="operator">.</span>depthWriteEnable <span class="operator">=</span> VK_TRUE; ds<span class="operator">.</span>depthCompareOp <span class="operator">=</span> VK_COMPARE_OP_LESS_OR_EQUAL; pipelineInfo<span class="operator">.</span>pDepthStencilState <span class="operator">=</span> <span class="operator">&</span>ds; VkPipelineColorBlendStateCreateInfo cb; memset(<span class="operator">&</span>cb<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="keyword">sizeof</span>(cb)); cb<span class="operator">.</span>sType <span class="operator">=</span> VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; VkPipelineColorBlendAttachmentState att; memset(<span class="operator">&</span>att<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="keyword">sizeof</span>(att)); att<span class="operator">.</span>colorWriteMask <span class="operator">=</span> <span class="number">0xF</span>; cb<span class="operator">.</span>attachmentCount <span class="operator">=</span> <span class="number">1</span>; cb<span class="operator">.</span>pAttachments <span class="operator">=</span> <span class="operator">&</span>att; pipelineInfo<span class="operator">.</span>pColorBlendState <span class="operator">=</span> <span class="operator">&</span>cb; VkDynamicState dynEnable<span class="operator">[</span><span class="operator">]</span> <span class="operator">=</span> { VK_DYNAMIC_STATE_VIEWPORT<span class="operator">,</span> VK_DYNAMIC_STATE_SCISSOR }; VkPipelineDynamicStateCreateInfo dyn; memset(<span class="operator">&</span>dyn<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="keyword">sizeof</span>(dyn)); dyn<span class="operator">.</span>sType <span class="operator">=</span> VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; dyn<span class="operator">.</span>dynamicStateCount <span class="operator">=</span> <span class="keyword">sizeof</span>(dynEnable) <span class="operator">/</span> <span class="keyword">sizeof</span>(VkDynamicState); dyn<span class="operator">.</span>pDynamicStates <span class="operator">=</span> dynEnable; pipelineInfo<span class="operator">.</span>pDynamicState <span class="operator">=</span> <span class="operator">&</span>dyn; pipelineInfo<span class="operator">.</span>layout <span class="operator">=</span> m_floorMaterial<span class="operator">.</span>pipelineLayout; pipelineInfo<span class="operator">.</span>renderPass <span class="operator">=</span> m_window<span class="operator">-</span><span class="operator">></span>defaultRenderPass(); err <span class="operator">=</span> m_devFuncs<span class="operator">-</span><span class="operator">></span>vkCreateGraphicsPipelines(dev<span class="operator">,</span> m_pipelineCache<span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="operator">&</span>pipelineInfo<span class="operator">,</span> nullptr<span class="operator">,</span> <span class="operator">&</span>m_floorMaterial<span class="operator">.</span>pipeline); <span class="keyword">if</span> (err <span class="operator">!</span><span class="operator">=</span> VK_SUCCESS) <a href="../qtcore/qtglobal.html#qFatal">qFatal</a>(<span class="string">"Failed to create graphics pipeline: %d"</span><span class="operator">,</span> err); } <span class="type">void</span> Renderer<span class="operator">::</span>initSwapChainResources() { m_proj <span class="operator">=</span> m_window<span class="operator">-</span><span class="operator">></span>clipCorrectionMatrix(); <span class="keyword">const</span> <span class="type"><a href="../qtcore/qsize.html">QSize</a></span> sz <span class="operator">=</span> m_window<span class="operator">-</span><span class="operator">></span>swapChainImageSize(); m_proj<span class="operator">.</span>perspective(<span class="number">45.0f</span><span class="operator">,</span> sz<span class="operator">.</span>width() <span class="operator">/</span> (<span class="type">float</span>) sz<span class="operator">.</span>height()<span class="operator">,</span> <span class="number">0.01f</span><span class="operator">,</span> <span class="number">1000.0f</span>); markViewProjDirty(); } <span class="type">void</span> Renderer<span class="operator">::</span>releaseSwapChainResources() { <span class="comment">// It is important to finish the pending frame right here since this is the</span> <span class="comment">// last opportunity to act with all resources intact.</span> m_frameWatcher<span class="operator">.</span>waitForFinished(); <span class="comment">// Cannot count on the finished() signal being emitted before returning</span> <span class="comment">// from here.</span> <span class="keyword">if</span> (m_framePending) { m_framePending <span class="operator">=</span> <span class="keyword">false</span>; m_window<span class="operator">-</span><span class="operator">></span>frameReady(); } } <span class="type">void</span> Renderer<span class="operator">::</span>releaseResources() { <span class="keyword">if</span> (DBG) <a href="../qtcore/qtglobal.html#qDebug">qDebug</a>(<span class="string">"Renderer release"</span>); m_pipelinesFuture<span class="operator">.</span>waitForFinished(); VkDevice dev <span class="operator">=</span> m_window<span class="operator">-</span><span class="operator">></span>device(); <span class="keyword">if</span> (m_itemMaterial<span class="operator">.</span>descSetLayout) { m_devFuncs<span class="operator">-</span><span class="operator">></span>vkDestroyDescriptorSetLayout(dev<span class="operator">,</span> m_itemMaterial<span class="operator">.</span>descSetLayout<span class="operator">,</span> nullptr); m_itemMaterial<span class="operator">.</span>descSetLayout <span class="operator">=</span> VK_NULL_HANDLE; } <span class="keyword">if</span> (m_itemMaterial<span class="operator">.</span>descPool) { m_devFuncs<span class="operator">-</span><span class="operator">></span>vkDestroyDescriptorPool(dev<span class="operator">,</span> m_itemMaterial<span class="operator">.</span>descPool<span class="operator">,</span> nullptr); m_itemMaterial<span class="operator">.</span>descPool <span class="operator">=</span> VK_NULL_HANDLE; } <span class="keyword">if</span> (m_itemMaterial<span class="operator">.</span>pipeline) { m_devFuncs<span class="operator">-</span><span class="operator">></span>vkDestroyPipeline(dev<span class="operator">,</span> m_itemMaterial<span class="operator">.</span>pipeline<span class="operator">,</span> nullptr); m_itemMaterial<span class="operator">.</span>pipeline <span class="operator">=</span> VK_NULL_HANDLE; } <span class="keyword">if</span> (m_itemMaterial<span class="operator">.</span>pipelineLayout) { m_devFuncs<span class="operator">-</span><span class="operator">></span>vkDestroyPipelineLayout(dev<span class="operator">,</span> m_itemMaterial<span class="operator">.</span>pipelineLayout<span class="operator">,</span> nullptr); m_itemMaterial<span class="operator">.</span>pipelineLayout <span class="operator">=</span> VK_NULL_HANDLE; } <span class="keyword">if</span> (m_floorMaterial<span class="operator">.</span>pipeline) { m_devFuncs<span class="operator">-</span><span class="operator">></span>vkDestroyPipeline(dev<span class="operator">,</span> m_floorMaterial<span class="operator">.</span>pipeline<span class="operator">,</span> nullptr); m_floorMaterial<span class="operator">.</span>pipeline <span class="operator">=</span> VK_NULL_HANDLE; } <span class="keyword">if</span> (m_floorMaterial<span class="operator">.</span>pipelineLayout) { m_devFuncs<span class="operator">-</span><span class="operator">></span>vkDestroyPipelineLayout(dev<span class="operator">,</span> m_floorMaterial<span class="operator">.</span>pipelineLayout<span class="operator">,</span> nullptr); m_floorMaterial<span class="operator">.</span>pipelineLayout <span class="operator">=</span> VK_NULL_HANDLE; } <span class="keyword">if</span> (m_pipelineCache) { m_devFuncs<span class="operator">-</span><span class="operator">></span>vkDestroyPipelineCache(dev<span class="operator">,</span> m_pipelineCache<span class="operator">,</span> nullptr); m_pipelineCache <span class="operator">=</span> VK_NULL_HANDLE; } <span class="keyword">if</span> (m_blockVertexBuf) { m_devFuncs<span class="operator">-</span><span class="operator">></span>vkDestroyBuffer(dev<span class="operator">,</span> m_blockVertexBuf<span class="operator">,</span> nullptr); m_blockVertexBuf <span class="operator">=</span> VK_NULL_HANDLE; } <span class="keyword">if</span> (m_logoVertexBuf) { m_devFuncs<span class="operator">-</span><span class="operator">></span>vkDestroyBuffer(dev<span class="operator">,</span> m_logoVertexBuf<span class="operator">,</span> nullptr); m_logoVertexBuf <span class="operator">=</span> VK_NULL_HANDLE; } <span class="keyword">if</span> (m_floorVertexBuf) { m_devFuncs<span class="operator">-</span><span class="operator">></span>vkDestroyBuffer(dev<span class="operator">,</span> m_floorVertexBuf<span class="operator">,</span> nullptr); m_floorVertexBuf <span class="operator">=</span> VK_NULL_HANDLE; } <span class="keyword">if</span> (m_uniBuf) { m_devFuncs<span class="operator">-</span><span class="operator">></span>vkDestroyBuffer(dev<span class="operator">,</span> m_uniBuf<span class="operator">,</span> nullptr); m_uniBuf <span class="operator">=</span> VK_NULL_HANDLE; } <span class="keyword">if</span> (m_bufMem) { m_devFuncs<span class="operator">-</span><span class="operator">></span>vkFreeMemory(dev<span class="operator">,</span> m_bufMem<span class="operator">,</span> nullptr); m_bufMem <span class="operator">=</span> VK_NULL_HANDLE; } <span class="keyword">if</span> (m_instBuf) { m_devFuncs<span class="operator">-</span><span class="operator">></span>vkDestroyBuffer(dev<span class="operator">,</span> m_instBuf<span class="operator">,</span> nullptr); m_instBuf <span class="operator">=</span> VK_NULL_HANDLE; } <span class="keyword">if</span> (m_instBufMem) { m_devFuncs<span class="operator">-</span><span class="operator">></span>vkFreeMemory(dev<span class="operator">,</span> m_instBufMem<span class="operator">,</span> nullptr); m_instBufMem <span class="operator">=</span> VK_NULL_HANDLE; } <span class="keyword">if</span> (m_itemMaterial<span class="operator">.</span>vs<span class="operator">.</span>isValid()) { m_devFuncs<span class="operator">-</span><span class="operator">></span>vkDestroyShaderModule(dev<span class="operator">,</span> m_itemMaterial<span class="operator">.</span>vs<span class="operator">.</span>data()<span class="operator">-</span><span class="operator">></span>shaderModule<span class="operator">,</span> nullptr); m_itemMaterial<span class="operator">.</span>vs<span class="operator">.</span>reset(); } <span class="keyword">if</span> (m_itemMaterial<span class="operator">.</span>fs<span class="operator">.</span>isValid()) { m_devFuncs<span class="operator">-</span><span class="operator">></span>vkDestroyShaderModule(dev<span class="operator">,</span> m_itemMaterial<span class="operator">.</span>fs<span class="operator">.</span>data()<span class="operator">-</span><span class="operator">></span>shaderModule<span class="operator">,</span> nullptr); m_itemMaterial<span class="operator">.</span>fs<span class="operator">.</span>reset(); } <span class="keyword">if</span> (m_floorMaterial<span class="operator">.</span>vs<span class="operator">.</span>isValid()) { m_devFuncs<span class="operator">-</span><span class="operator">></span>vkDestroyShaderModule(dev<span class="operator">,</span> m_floorMaterial<span class="operator">.</span>vs<span class="operator">.</span>data()<span class="operator">-</span><span class="operator">></span>shaderModule<span class="operator">,</span> nullptr); m_floorMaterial<span class="operator">.</span>vs<span class="operator">.</span>reset(); } <span class="keyword">if</span> (m_floorMaterial<span class="operator">.</span>fs<span class="operator">.</span>isValid()) { m_devFuncs<span class="operator">-</span><span class="operator">></span>vkDestroyShaderModule(dev<span class="operator">,</span> m_floorMaterial<span class="operator">.</span>fs<span class="operator">.</span>data()<span class="operator">-</span><span class="operator">></span>shaderModule<span class="operator">,</span> nullptr); m_floorMaterial<span class="operator">.</span>fs<span class="operator">.</span>reset(); } } <span class="type">void</span> Renderer<span class="operator">::</span>ensureBuffers() { <span class="keyword">if</span> (m_blockVertexBuf) <span class="keyword">return</span>; VkDevice dev <span class="operator">=</span> m_window<span class="operator">-</span><span class="operator">></span>device(); <span class="keyword">const</span> <span class="type">int</span> concurrentFrameCount <span class="operator">=</span> m_window<span class="operator">-</span><span class="operator">></span>concurrentFrameCount(); <span class="comment">// Vertex buffer for the block.</span> VkBufferCreateInfo bufInfo; memset(<span class="operator">&</span>bufInfo<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="keyword">sizeof</span>(bufInfo)); bufInfo<span class="operator">.</span>sType <span class="operator">=</span> VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; <span class="keyword">const</span> <span class="type">int</span> blockMeshByteCount <span class="operator">=</span> m_blockMesh<span class="operator">.</span>data()<span class="operator">-</span><span class="operator">></span>vertexCount <span class="operator">*</span> <span class="number">8</span> <span class="operator">*</span> <span class="keyword">sizeof</span>(<span class="type">float</span>); bufInfo<span class="operator">.</span>size <span class="operator">=</span> blockMeshByteCount; bufInfo<span class="operator">.</span>usage <span class="operator">=</span> VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; VkResult err <span class="operator">=</span> m_devFuncs<span class="operator">-</span><span class="operator">></span>vkCreateBuffer(dev<span class="operator">,</span> <span class="operator">&</span>bufInfo<span class="operator">,</span> nullptr<span class="operator">,</span> <span class="operator">&</span>m_blockVertexBuf); <span class="keyword">if</span> (err <span class="operator">!</span><span class="operator">=</span> VK_SUCCESS) <a href="../qtcore/qtglobal.html#qFatal">qFatal</a>(<span class="string">"Failed to create vertex buffer: %d"</span><span class="operator">,</span> err); VkMemoryRequirements blockVertMemReq; m_devFuncs<span class="operator">-</span><span class="operator">></span>vkGetBufferMemoryRequirements(dev<span class="operator">,</span> m_blockVertexBuf<span class="operator">,</span> <span class="operator">&</span>blockVertMemReq); <span class="comment">// Vertex buffer for the logo.</span> <span class="keyword">const</span> <span class="type">int</span> logoMeshByteCount <span class="operator">=</span> m_logoMesh<span class="operator">.</span>data()<span class="operator">-</span><span class="operator">></span>vertexCount <span class="operator">*</span> <span class="number">8</span> <span class="operator">*</span> <span class="keyword">sizeof</span>(<span class="type">float</span>); bufInfo<span class="operator">.</span>size <span class="operator">=</span> logoMeshByteCount; bufInfo<span class="operator">.</span>usage <span class="operator">=</span> VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; err <span class="operator">=</span> m_devFuncs<span class="operator">-</span><span class="operator">></span>vkCreateBuffer(dev<span class="operator">,</span> <span class="operator">&</span>bufInfo<span class="operator">,</span> nullptr<span class="operator">,</span> <span class="operator">&</span>m_logoVertexBuf); <span class="keyword">if</span> (err <span class="operator">!</span><span class="operator">=</span> VK_SUCCESS) <a href="../qtcore/qtglobal.html#qFatal">qFatal</a>(<span class="string">"Failed to create vertex buffer: %d"</span><span class="operator">,</span> err); VkMemoryRequirements logoVertMemReq; m_devFuncs<span class="operator">-</span><span class="operator">></span>vkGetBufferMemoryRequirements(dev<span class="operator">,</span> m_logoVertexBuf<span class="operator">,</span> <span class="operator">&</span>logoVertMemReq); <span class="comment">// Vertex buffer for the floor.</span> bufInfo<span class="operator">.</span>size <span class="operator">=</span> <span class="keyword">sizeof</span>(quadVert); err <span class="operator">=</span> m_devFuncs<span class="operator">-</span><span class="operator">></span>vkCreateBuffer(dev<span class="operator">,</span> <span class="operator">&</span>bufInfo<span class="operator">,</span> nullptr<span class="operator">,</span> <span class="operator">&</span>m_floorVertexBuf); <span class="keyword">if</span> (err <span class="operator">!</span><span class="operator">=</span> VK_SUCCESS) <a href="../qtcore/qtglobal.html#qFatal">qFatal</a>(<span class="string">"Failed to create vertex buffer: %d"</span><span class="operator">,</span> err); VkMemoryRequirements floorVertMemReq; m_devFuncs<span class="operator">-</span><span class="operator">></span>vkGetBufferMemoryRequirements(dev<span class="operator">,</span> m_floorVertexBuf<span class="operator">,</span> <span class="operator">&</span>floorVertMemReq); <span class="comment">// Uniform buffer. Instead of using multiple descriptor sets, we take a</span> <span class="comment">// different approach: have a single dynamic uniform buffer and specify the</span> <span class="comment">// active-frame-specific offset at the time of binding the descriptor set.</span> bufInfo<span class="operator">.</span>size <span class="operator">=</span> (m_itemMaterial<span class="operator">.</span>vertUniSize <span class="operator">+</span> m_itemMaterial<span class="operator">.</span>fragUniSize) <span class="operator">*</span> concurrentFrameCount; bufInfo<span class="operator">.</span>usage <span class="operator">=</span> VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; err <span class="operator">=</span> m_devFuncs<span class="operator">-</span><span class="operator">></span>vkCreateBuffer(dev<span class="operator">,</span> <span class="operator">&</span>bufInfo<span class="operator">,</span> nullptr<span class="operator">,</span> <span class="operator">&</span>m_uniBuf); <span class="keyword">if</span> (err <span class="operator">!</span><span class="operator">=</span> VK_SUCCESS) <a href="../qtcore/qtglobal.html#qFatal">qFatal</a>(<span class="string">"Failed to create uniform buffer: %d"</span><span class="operator">,</span> err); VkMemoryRequirements uniMemReq; m_devFuncs<span class="operator">-</span><span class="operator">></span>vkGetBufferMemoryRequirements(dev<span class="operator">,</span> m_uniBuf<span class="operator">,</span> <span class="operator">&</span>uniMemReq); <span class="comment">// Allocate memory for everything at once.</span> VkDeviceSize logoVertStartOffset <span class="operator">=</span> aligned(<span class="number">0</span> <span class="operator">+</span> blockVertMemReq<span class="operator">.</span>size<span class="operator">,</span> logoVertMemReq<span class="operator">.</span>alignment); VkDeviceSize floorVertStartOffset <span class="operator">=</span> aligned(logoVertStartOffset <span class="operator">+</span> logoVertMemReq<span class="operator">.</span>size<span class="operator">,</span> floorVertMemReq<span class="operator">.</span>alignment); m_itemMaterial<span class="operator">.</span>uniMemStartOffset <span class="operator">=</span> aligned(floorVertStartOffset <span class="operator">+</span> floorVertMemReq<span class="operator">.</span>size<span class="operator">,</span> uniMemReq<span class="operator">.</span>alignment); VkMemoryAllocateInfo memAllocInfo <span class="operator">=</span> { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO<span class="operator">,</span> nullptr<span class="operator">,</span> m_itemMaterial<span class="operator">.</span>uniMemStartOffset <span class="operator">+</span> uniMemReq<span class="operator">.</span>size<span class="operator">,</span> m_window<span class="operator">-</span><span class="operator">></span>hostVisibleMemoryIndex() }; err <span class="operator">=</span> m_devFuncs<span class="operator">-</span><span class="operator">></span>vkAllocateMemory(dev<span class="operator">,</span> <span class="operator">&</span>memAllocInfo<span class="operator">,</span> nullptr<span class="operator">,</span> <span class="operator">&</span>m_bufMem); <span class="keyword">if</span> (err <span class="operator">!</span><span class="operator">=</span> VK_SUCCESS) <a href="../qtcore/qtglobal.html#qFatal">qFatal</a>(<span class="string">"Failed to allocate memory: %d"</span><span class="operator">,</span> err); err <span class="operator">=</span> m_devFuncs<span class="operator">-</span><span class="operator">></span>vkBindBufferMemory(dev<span class="operator">,</span> m_blockVertexBuf<span class="operator">,</span> m_bufMem<span class="operator">,</span> <span class="number">0</span>); <span class="keyword">if</span> (err <span class="operator">!</span><span class="operator">=</span> VK_SUCCESS) <a href="../qtcore/qtglobal.html#qFatal">qFatal</a>(<span class="string">"Failed to bind vertex buffer memory: %d"</span><span class="operator">,</span> err); err <span class="operator">=</span> m_devFuncs<span class="operator">-</span><span class="operator">></span>vkBindBufferMemory(dev<span class="operator">,</span> m_logoVertexBuf<span class="operator">,</span> m_bufMem<span class="operator">,</span> logoVertStartOffset); <span class="keyword">if</span> (err <span class="operator">!</span><span class="operator">=</span> VK_SUCCESS) <a href="../qtcore/qtglobal.html#qFatal">qFatal</a>(<span class="string">"Failed to bind vertex buffer memory: %d"</span><span class="operator">,</span> err); err <span class="operator">=</span> m_devFuncs<span class="operator">-</span><span class="operator">></span>vkBindBufferMemory(dev<span class="operator">,</span> m_floorVertexBuf<span class="operator">,</span> m_bufMem<span class="operator">,</span> floorVertStartOffset); <span class="keyword">if</span> (err <span class="operator">!</span><span class="operator">=</span> VK_SUCCESS) <a href="../qtcore/qtglobal.html#qFatal">qFatal</a>(<span class="string">"Failed to bind vertex buffer memory: %d"</span><span class="operator">,</span> err); err <span class="operator">=</span> m_devFuncs<span class="operator">-</span><span class="operator">></span>vkBindBufferMemory(dev<span class="operator">,</span> m_uniBuf<span class="operator">,</span> m_bufMem<span class="operator">,</span> m_itemMaterial<span class="operator">.</span>uniMemStartOffset); <span class="keyword">if</span> (err <span class="operator">!</span><span class="operator">=</span> VK_SUCCESS) <a href="../qtcore/qtglobal.html#qFatal">qFatal</a>(<span class="string">"Failed to bind uniform buffer memory: %d"</span><span class="operator">,</span> err); <span class="comment">// Copy vertex data.</span> <span class="type"><a href="../qtcore/qtglobal.html#quint8-typedef">quint8</a></span> <span class="operator">*</span>p; err <span class="operator">=</span> m_devFuncs<span class="operator">-</span><span class="operator">></span>vkMapMemory(dev<span class="operator">,</span> m_bufMem<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> m_itemMaterial<span class="operator">.</span>uniMemStartOffset<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="keyword">reinterpret_cast</span><span class="operator"><</span><span class="type">void</span> <span class="operator">*</span><span class="operator">*</span><span class="operator">></span>(<span class="operator">&</span>p)); <span class="keyword">if</span> (err <span class="operator">!</span><span class="operator">=</span> VK_SUCCESS) <a href="../qtcore/qtglobal.html#qFatal">qFatal</a>(<span class="string">"Failed to map memory: %d"</span><span class="operator">,</span> err); memcpy(p<span class="operator">,</span> m_blockMesh<span class="operator">.</span>data()<span class="operator">-</span><span class="operator">></span>geom<span class="operator">.</span>constData()<span class="operator">,</span> blockMeshByteCount); memcpy(p <span class="operator">+</span> logoVertStartOffset<span class="operator">,</span> m_logoMesh<span class="operator">.</span>data()<span class="operator">-</span><span class="operator">></span>geom<span class="operator">.</span>constData()<span class="operator">,</span> logoMeshByteCount); memcpy(p <span class="operator">+</span> floorVertStartOffset<span class="operator">,</span> quadVert<span class="operator">,</span> <span class="keyword">sizeof</span>(quadVert)); m_devFuncs<span class="operator">-</span><span class="operator">></span>vkUnmapMemory(dev<span class="operator">,</span> m_bufMem); <span class="comment">// Write descriptors for the uniform buffers in the vertex and fragment shaders.</span> VkDescriptorBufferInfo vertUni <span class="operator">=</span> { m_uniBuf<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> m_itemMaterial<span class="operator">.</span>vertUniSize }; VkDescriptorBufferInfo fragUni <span class="operator">=</span> { m_uniBuf<span class="operator">,</span> m_itemMaterial<span class="operator">.</span>vertUniSize<span class="operator">,</span> m_itemMaterial<span class="operator">.</span>fragUniSize }; VkWriteDescriptorSet descWrite<span class="operator">[</span><span class="number">2</span><span class="operator">]</span>; memset(descWrite<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="keyword">sizeof</span>(descWrite)); descWrite<span class="operator">[</span><span class="number">0</span><span class="operator">]</span><span class="operator">.</span>sType <span class="operator">=</span> VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; descWrite<span class="operator">[</span><span class="number">0</span><span class="operator">]</span><span class="operator">.</span>dstSet <span class="operator">=</span> m_itemMaterial<span class="operator">.</span>descSet; descWrite<span class="operator">[</span><span class="number">0</span><span class="operator">]</span><span class="operator">.</span>dstBinding <span class="operator">=</span> <span class="number">0</span>; descWrite<span class="operator">[</span><span class="number">0</span><span class="operator">]</span><span class="operator">.</span>descriptorCount <span class="operator">=</span> <span class="number">1</span>; descWrite<span class="operator">[</span><span class="number">0</span><span class="operator">]</span><span class="operator">.</span>descriptorType <span class="operator">=</span> VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; descWrite<span class="operator">[</span><span class="number">0</span><span class="operator">]</span><span class="operator">.</span>pBufferInfo <span class="operator">=</span> <span class="operator">&</span>vertUni; descWrite<span class="operator">[</span><span class="number">1</span><span class="operator">]</span><span class="operator">.</span>sType <span class="operator">=</span> VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; descWrite<span class="operator">[</span><span class="number">1</span><span class="operator">]</span><span class="operator">.</span>dstSet <span class="operator">=</span> m_itemMaterial<span class="operator">.</span>descSet; descWrite<span class="operator">[</span><span class="number">1</span><span class="operator">]</span><span class="operator">.</span>dstBinding <span class="operator">=</span> <span class="number">1</span>; descWrite<span class="operator">[</span><span class="number">1</span><span class="operator">]</span><span class="operator">.</span>descriptorCount <span class="operator">=</span> <span class="number">1</span>; descWrite<span class="operator">[</span><span class="number">1</span><span class="operator">]</span><span class="operator">.</span>descriptorType <span class="operator">=</span> VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; descWrite<span class="operator">[</span><span class="number">1</span><span class="operator">]</span><span class="operator">.</span>pBufferInfo <span class="operator">=</span> <span class="operator">&</span>fragUni; m_devFuncs<span class="operator">-</span><span class="operator">></span>vkUpdateDescriptorSets(dev<span class="operator">,</span> <span class="number">2</span><span class="operator">,</span> descWrite<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> nullptr); } <span class="type">void</span> Renderer<span class="operator">::</span>ensureInstanceBuffer() { <span class="keyword">if</span> (m_instCount <span class="operator">=</span><span class="operator">=</span> m_preparedInstCount <span class="operator">&</span><span class="operator">&</span> m_instBuf) <span class="keyword">return</span>; Q_ASSERT(m_instCount <span class="operator"><</span><span class="operator">=</span> MAX_INSTANCES); VkDevice dev <span class="operator">=</span> m_window<span class="operator">-</span><span class="operator">></span>device(); <span class="comment">// allocate only once, for the maximum instance count</span> <span class="keyword">if</span> (<span class="operator">!</span>m_instBuf) { VkBufferCreateInfo bufInfo; memset(<span class="operator">&</span>bufInfo<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="keyword">sizeof</span>(bufInfo)); bufInfo<span class="operator">.</span>sType <span class="operator">=</span> VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; bufInfo<span class="operator">.</span>size <span class="operator">=</span> MAX_INSTANCES <span class="operator">*</span> PER_INSTANCE_DATA_SIZE; bufInfo<span class="operator">.</span>usage <span class="operator">=</span> VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; <span class="comment">// Keep a copy of the data since we may lose all graphics resources on</span> <span class="comment">// unexpose, and reinitializing to new random positions afterwards</span> <span class="comment">// would not be nice.</span> m_instData<span class="operator">.</span>resize(bufInfo<span class="operator">.</span>size); VkResult err <span class="operator">=</span> m_devFuncs<span class="operator">-</span><span class="operator">></span>vkCreateBuffer(dev<span class="operator">,</span> <span class="operator">&</span>bufInfo<span class="operator">,</span> nullptr<span class="operator">,</span> <span class="operator">&</span>m_instBuf); <span class="keyword">if</span> (err <span class="operator">!</span><span class="operator">=</span> VK_SUCCESS) <a href="../qtcore/qtglobal.html#qFatal">qFatal</a>(<span class="string">"Failed to create instance buffer: %d"</span><span class="operator">,</span> err); VkMemoryRequirements memReq; m_devFuncs<span class="operator">-</span><span class="operator">></span>vkGetBufferMemoryRequirements(dev<span class="operator">,</span> m_instBuf<span class="operator">,</span> <span class="operator">&</span>memReq); <span class="keyword">if</span> (DBG) <a href="../qtcore/qtglobal.html#qDebug">qDebug</a>(<span class="string">"Allocating %u bytes for instance data"</span><span class="operator">,</span> uint32_t(memReq<span class="operator">.</span>size)); VkMemoryAllocateInfo memAllocInfo <span class="operator">=</span> { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO<span class="operator">,</span> nullptr<span class="operator">,</span> memReq<span class="operator">.</span>size<span class="operator">,</span> m_window<span class="operator">-</span><span class="operator">></span>hostVisibleMemoryIndex() }; err <span class="operator">=</span> m_devFuncs<span class="operator">-</span><span class="operator">></span>vkAllocateMemory(dev<span class="operator">,</span> <span class="operator">&</span>memAllocInfo<span class="operator">,</span> nullptr<span class="operator">,</span> <span class="operator">&</span>m_instBufMem); <span class="keyword">if</span> (err <span class="operator">!</span><span class="operator">=</span> VK_SUCCESS) <a href="../qtcore/qtglobal.html#qFatal">qFatal</a>(<span class="string">"Failed to allocate memory: %d"</span><span class="operator">,</span> err); err <span class="operator">=</span> m_devFuncs<span class="operator">-</span><span class="operator">></span>vkBindBufferMemory(dev<span class="operator">,</span> m_instBuf<span class="operator">,</span> m_instBufMem<span class="operator">,</span> <span class="number">0</span>); <span class="keyword">if</span> (err <span class="operator">!</span><span class="operator">=</span> VK_SUCCESS) <a href="../qtcore/qtglobal.html#qFatal">qFatal</a>(<span class="string">"Failed to bind instance buffer memory: %d"</span><span class="operator">,</span> err); } <span class="keyword">if</span> (m_instCount <span class="operator">!</span><span class="operator">=</span> m_preparedInstCount) { <span class="keyword">if</span> (DBG) <a href="../qtcore/qtglobal.html#qDebug">qDebug</a>(<span class="string">"Preparing instances %d..%d"</span><span class="operator">,</span> m_preparedInstCount<span class="operator">,</span> m_instCount <span class="operator">-</span> <span class="number">1</span>); <span class="type">char</span> <span class="operator">*</span>p <span class="operator">=</span> m_instData<span class="operator">.</span>data(); p <span class="operator">+</span><span class="operator">=</span> m_preparedInstCount <span class="operator">*</span> PER_INSTANCE_DATA_SIZE; <span class="keyword">auto</span> gen <span class="operator">=</span> <span class="operator">[</span><span class="operator">]</span>(<span class="type">float</span> a<span class="operator">,</span> <span class="type">float</span> b) { <span class="keyword">return</span> <span class="type">float</span>((qrand() <span class="operator">%</span> <span class="type">int</span>(b <span class="operator">-</span> a <span class="operator">+</span> <span class="number">1</span>)) <span class="operator">+</span> a); }; <span class="keyword">for</span> (<span class="type">int</span> i <span class="operator">=</span> m_preparedInstCount; i <span class="operator"><</span> m_instCount; <span class="operator">+</span><span class="operator">+</span>i) { <span class="comment">// Apply a random translation to each instance of the mesh.</span> <span class="type">float</span> t<span class="operator">[</span><span class="operator">]</span> <span class="operator">=</span> { gen(<span class="operator">-</span><span class="number">5</span><span class="operator">,</span> <span class="number">5</span>)<span class="operator">,</span> gen(<span class="operator">-</span><span class="number">4</span><span class="operator">,</span> <span class="number">6</span>)<span class="operator">,</span> gen(<span class="operator">-</span><span class="number">30</span><span class="operator">,</span> <span class="number">5</span>) }; memcpy(p<span class="operator">,</span> t<span class="operator">,</span> <span class="number">12</span>); <span class="comment">// Apply a random adjustment to the diffuse color for each instance. (default is 0.7)</span> <span class="type">float</span> d<span class="operator">[</span><span class="operator">]</span> <span class="operator">=</span> { gen(<span class="operator">-</span><span class="number">6</span><span class="operator">,</span> <span class="number">3</span>) <span class="operator">/</span> <span class="number">10.0f</span><span class="operator">,</span> gen(<span class="operator">-</span><span class="number">6</span><span class="operator">,</span> <span class="number">3</span>) <span class="operator">/</span> <span class="number">10.0f</span><span class="operator">,</span> gen(<span class="operator">-</span><span class="number">6</span><span class="operator">,</span> <span class="number">3</span>) <span class="operator">/</span> <span class="number">10.0f</span> }; memcpy(p <span class="operator">+</span> <span class="number">12</span><span class="operator">,</span> d<span class="operator">,</span> <span class="number">12</span>); p <span class="operator">+</span><span class="operator">=</span> PER_INSTANCE_DATA_SIZE; } m_preparedInstCount <span class="operator">=</span> m_instCount; } <span class="type"><a href="../qtcore/qtglobal.html#quint8-typedef">quint8</a></span> <span class="operator">*</span>p; VkResult err <span class="operator">=</span> m_devFuncs<span class="operator">-</span><span class="operator">></span>vkMapMemory(dev<span class="operator">,</span> m_instBufMem<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> m_instCount <span class="operator">*</span> PER_INSTANCE_DATA_SIZE<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="keyword">reinterpret_cast</span><span class="operator"><</span><span class="type">void</span> <span class="operator">*</span><span class="operator">*</span><span class="operator">></span>(<span class="operator">&</span>p)); <span class="keyword">if</span> (err <span class="operator">!</span><span class="operator">=</span> VK_SUCCESS) <a href="../qtcore/qtglobal.html#qFatal">qFatal</a>(<span class="string">"Failed to map memory: %d"</span><span class="operator">,</span> err); memcpy(p<span class="operator">,</span> m_instData<span class="operator">.</span>constData()<span class="operator">,</span> m_instData<span class="operator">.</span>size()); m_devFuncs<span class="operator">-</span><span class="operator">></span>vkUnmapMemory(dev<span class="operator">,</span> m_instBufMem); } <span class="type">void</span> Renderer<span class="operator">::</span>getMatrices(QMatrix4x4 <span class="operator">*</span>vp<span class="operator">,</span> QMatrix4x4 <span class="operator">*</span>model<span class="operator">,</span> QMatrix3x3 <span class="operator">*</span>modelNormal<span class="operator">,</span> QVector3D <span class="operator">*</span>eyePos) { model<span class="operator">-</span><span class="operator">></span>setToIdentity(); <span class="keyword">if</span> (m_useLogo) model<span class="operator">-</span><span class="operator">></span>rotate(<span class="number">90</span><span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="number">0</span>); model<span class="operator">-</span><span class="operator">></span>rotate(m_rotation<span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="number">0</span>); <span class="operator">*</span>modelNormal <span class="operator">=</span> model<span class="operator">-</span><span class="operator">></span>normalMatrix(); QMatrix4x4 view <span class="operator">=</span> m_cam<span class="operator">.</span>viewMatrix(); <span class="operator">*</span>vp <span class="operator">=</span> m_proj <span class="operator">*</span> view; <span class="operator">*</span>eyePos <span class="operator">=</span> view<span class="operator">.</span>inverted()<span class="operator">.</span>column(<span class="number">3</span>)<span class="operator">.</span>toVector3D(); } <span class="type">void</span> Renderer<span class="operator">::</span>writeFragUni(<span class="type"><a href="../qtcore/qtglobal.html#quint8-typedef">quint8</a></span> <span class="operator">*</span>p<span class="operator">,</span> <span class="keyword">const</span> QVector3D <span class="operator">&</span>eyePos) { <span class="type">float</span> ECCameraPosition<span class="operator">[</span><span class="operator">]</span> <span class="operator">=</span> { eyePos<span class="operator">.</span>x()<span class="operator">,</span> eyePos<span class="operator">.</span>y()<span class="operator">,</span> eyePos<span class="operator">.</span>z() }; memcpy(p<span class="operator">,</span> ECCameraPosition<span class="operator">,</span> <span class="number">12</span>); p <span class="operator">+</span><span class="operator">=</span> <span class="number">16</span>; <span class="comment">// Material</span> <span class="type">float</span> ka<span class="operator">[</span><span class="operator">]</span> <span class="operator">=</span> { <span class="number">0.05f</span><span class="operator">,</span> <span class="number">0.05f</span><span class="operator">,</span> <span class="number">0.05f</span> }; memcpy(p<span class="operator">,</span> ka<span class="operator">,</span> <span class="number">12</span>); p <span class="operator">+</span><span class="operator">=</span> <span class="number">16</span>; <span class="type">float</span> kd<span class="operator">[</span><span class="operator">]</span> <span class="operator">=</span> { <span class="number">0.7f</span><span class="operator">,</span> <span class="number">0.7f</span><span class="operator">,</span> <span class="number">0.7f</span> }; memcpy(p<span class="operator">,</span> kd<span class="operator">,</span> <span class="number">12</span>); p <span class="operator">+</span><span class="operator">=</span> <span class="number">16</span>; <span class="type">float</span> ks<span class="operator">[</span><span class="operator">]</span> <span class="operator">=</span> { <span class="number">0.66f</span><span class="operator">,</span> <span class="number">0.66f</span><span class="operator">,</span> <span class="number">0.66f</span> }; memcpy(p<span class="operator">,</span> ks<span class="operator">,</span> <span class="number">12</span>); p <span class="operator">+</span><span class="operator">=</span> <span class="number">16</span>; <span class="comment">// Light parameters</span> <span class="type">float</span> ECLightPosition<span class="operator">[</span><span class="operator">]</span> <span class="operator">=</span> { m_lightPos<span class="operator">.</span>x()<span class="operator">,</span> m_lightPos<span class="operator">.</span>y()<span class="operator">,</span> m_lightPos<span class="operator">.</span>z() }; memcpy(p<span class="operator">,</span> ECLightPosition<span class="operator">,</span> <span class="number">12</span>); p <span class="operator">+</span><span class="operator">=</span> <span class="number">16</span>; <span class="type">float</span> att<span class="operator">[</span><span class="operator">]</span> <span class="operator">=</span> { <span class="number">1</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="number">0</span> }; memcpy(p<span class="operator">,</span> att<span class="operator">,</span> <span class="number">12</span>); p <span class="operator">+</span><span class="operator">=</span> <span class="number">16</span>; <span class="type">float</span> color<span class="operator">[</span><span class="operator">]</span> <span class="operator">=</span> { <span class="number">1.0f</span><span class="operator">,</span> <span class="number">1.0f</span><span class="operator">,</span> <span class="number">1.0f</span> }; memcpy(p<span class="operator">,</span> color<span class="operator">,</span> <span class="number">12</span>); p <span class="operator">+</span><span class="operator">=</span> <span class="number">12</span>; <span class="comment">// next we have two floats which have an alignment of 4, hence 12 only</span> <span class="type">float</span> intensity <span class="operator">=</span> <span class="number">0.8f</span>; memcpy(p<span class="operator">,</span> <span class="operator">&</span>intensity<span class="operator">,</span> <span class="number">4</span>); p <span class="operator">+</span><span class="operator">=</span> <span class="number">4</span>; <span class="type">float</span> specularExp <span class="operator">=</span> <span class="number">150.0f</span>; memcpy(p<span class="operator">,</span> <span class="operator">&</span>specularExp<span class="operator">,</span> <span class="number">4</span>); p <span class="operator">+</span><span class="operator">=</span> <span class="number">4</span>; } <span class="type">void</span> Renderer<span class="operator">::</span>startNextFrame() { <span class="comment">// For demonstration purposes offload the command buffer generation onto a</span> <span class="comment">// worker thread and continue with the frame submission only when it has</span> <span class="comment">// finished.</span> Q_ASSERT(<span class="operator">!</span>m_framePending); m_framePending <span class="operator">=</span> <span class="keyword">true</span>; <span class="type"><a href="../qtcore/qfuture.html">QFuture</a></span><span class="operator"><</span><span class="type">void</span><span class="operator">></span> future <span class="operator">=</span> <span class="type">QtConcurrent</span><span class="operator">::</span>run(<span class="keyword">this</span><span class="operator">,</span> <span class="operator">&</span>Renderer<span class="operator">::</span>buildFrame); m_frameWatcher<span class="operator">.</span>setFuture(future); } <span class="type">void</span> Renderer<span class="operator">::</span>buildFrame() { <span class="type"><a href="../qtcore/qmutexlocker.html">QMutexLocker</a></span> locker(<span class="operator">&</span>m_guiMutex); ensureBuffers(); ensureInstanceBuffer(); m_pipelinesFuture<span class="operator">.</span>waitForFinished(); VkCommandBuffer cb <span class="operator">=</span> m_window<span class="operator">-</span><span class="operator">></span>currentCommandBuffer(); <span class="keyword">const</span> <span class="type"><a href="../qtcore/qsize.html">QSize</a></span> sz <span class="operator">=</span> m_window<span class="operator">-</span><span class="operator">></span>swapChainImageSize(); VkClearColorValue clearColor <span class="operator">=</span> {{ <span class="number">0.67f</span><span class="operator">,</span> <span class="number">0.84f</span><span class="operator">,</span> <span class="number">0.9f</span><span class="operator">,</span> <span class="number">1.0f</span> }}; VkClearDepthStencilValue clearDS <span class="operator">=</span> { <span class="number">1</span><span class="operator">,</span> <span class="number">0</span> }; VkClearValue clearValues<span class="operator">[</span><span class="number">3</span><span class="operator">]</span>; memset(clearValues<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="keyword">sizeof</span>(clearValues)); clearValues<span class="operator">[</span><span class="number">0</span><span class="operator">]</span><span class="operator">.</span>color <span class="operator">=</span> clearValues<span class="operator">[</span><span class="number">2</span><span class="operator">]</span><span class="operator">.</span>color <span class="operator">=</span> clearColor; clearValues<span class="operator">[</span><span class="number">1</span><span class="operator">]</span><span class="operator">.</span>depthStencil <span class="operator">=</span> clearDS; VkRenderPassBeginInfo rpBeginInfo; memset(<span class="operator">&</span>rpBeginInfo<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="keyword">sizeof</span>(rpBeginInfo)); rpBeginInfo<span class="operator">.</span>sType <span class="operator">=</span> VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; rpBeginInfo<span class="operator">.</span>renderPass <span class="operator">=</span> m_window<span class="operator">-</span><span class="operator">></span>defaultRenderPass(); rpBeginInfo<span class="operator">.</span>framebuffer <span class="operator">=</span> m_window<span class="operator">-</span><span class="operator">></span>currentFramebuffer(); rpBeginInfo<span class="operator">.</span>renderArea<span class="operator">.</span>extent<span class="operator">.</span>width <span class="operator">=</span> sz<span class="operator">.</span>width(); rpBeginInfo<span class="operator">.</span>renderArea<span class="operator">.</span>extent<span class="operator">.</span>height <span class="operator">=</span> sz<span class="operator">.</span>height(); rpBeginInfo<span class="operator">.</span>clearValueCount <span class="operator">=</span> m_window<span class="operator">-</span><span class="operator">></span>sampleCountFlagBits() <span class="operator">></span> VK_SAMPLE_COUNT_1_BIT <span class="operator">?</span> <span class="number">3</span> : <span class="number">2</span>; rpBeginInfo<span class="operator">.</span>pClearValues <span class="operator">=</span> clearValues; VkCommandBuffer cmdBuf <span class="operator">=</span> m_window<span class="operator">-</span><span class="operator">></span>currentCommandBuffer(); m_devFuncs<span class="operator">-</span><span class="operator">></span>vkCmdBeginRenderPass(cmdBuf<span class="operator">,</span> <span class="operator">&</span>rpBeginInfo<span class="operator">,</span> VK_SUBPASS_CONTENTS_INLINE); VkViewport viewport <span class="operator">=</span> { <span class="number">0</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="type">float</span>(sz<span class="operator">.</span>width())<span class="operator">,</span> <span class="type">float</span>(sz<span class="operator">.</span>height())<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="number">1</span> }; m_devFuncs<span class="operator">-</span><span class="operator">></span>vkCmdSetViewport(cb<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="operator">&</span>viewport); VkRect2D scissor <span class="operator">=</span> { { <span class="number">0</span><span class="operator">,</span> <span class="number">0</span> }<span class="operator">,</span> { uint32_t(sz<span class="operator">.</span>width())<span class="operator">,</span> uint32_t(sz<span class="operator">.</span>height()) } }; m_devFuncs<span class="operator">-</span><span class="operator">></span>vkCmdSetScissor(cb<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="operator">&</span>scissor); buildDrawCallsForFloor(); buildDrawCallsForItems(); m_devFuncs<span class="operator">-</span><span class="operator">></span>vkCmdEndRenderPass(cmdBuf); } <span class="type">void</span> Renderer<span class="operator">::</span>buildDrawCallsForItems() { VkDevice dev <span class="operator">=</span> m_window<span class="operator">-</span><span class="operator">></span>device(); VkCommandBuffer cb <span class="operator">=</span> m_window<span class="operator">-</span><span class="operator">></span>currentCommandBuffer(); m_devFuncs<span class="operator">-</span><span class="operator">></span>vkCmdBindPipeline(cb<span class="operator">,</span> VK_PIPELINE_BIND_POINT_GRAPHICS<span class="operator">,</span> m_itemMaterial<span class="operator">.</span>pipeline); VkDeviceSize vbOffset <span class="operator">=</span> <span class="number">0</span>; m_devFuncs<span class="operator">-</span><span class="operator">></span>vkCmdBindVertexBuffers(cb<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> m_useLogo <span class="operator">?</span> <span class="operator">&</span>m_logoVertexBuf : <span class="operator">&</span>m_blockVertexBuf<span class="operator">,</span> <span class="operator">&</span>vbOffset); m_devFuncs<span class="operator">-</span><span class="operator">></span>vkCmdBindVertexBuffers(cb<span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="operator">&</span>m_instBuf<span class="operator">,</span> <span class="operator">&</span>vbOffset); <span class="comment">// Now provide offsets so that the two dynamic buffers point to the</span> <span class="comment">// beginning of the vertex and fragment uniform data for the current frame.</span> uint32_t frameUniOffset <span class="operator">=</span> m_window<span class="operator">-</span><span class="operator">></span>currentFrame() <span class="operator">*</span> (m_itemMaterial<span class="operator">.</span>vertUniSize <span class="operator">+</span> m_itemMaterial<span class="operator">.</span>fragUniSize); uint32_t frameUniOffsets<span class="operator">[</span><span class="operator">]</span> <span class="operator">=</span> { frameUniOffset<span class="operator">,</span> frameUniOffset }; m_devFuncs<span class="operator">-</span><span class="operator">></span>vkCmdBindDescriptorSets(cb<span class="operator">,</span> VK_PIPELINE_BIND_POINT_GRAPHICS<span class="operator">,</span> m_itemMaterial<span class="operator">.</span>pipelineLayout<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="operator">&</span>m_itemMaterial<span class="operator">.</span>descSet<span class="operator">,</span> <span class="number">2</span><span class="operator">,</span> frameUniOffsets); <span class="keyword">if</span> (m_animating) m_rotation <span class="operator">+</span><span class="operator">=</span> <span class="number">0.5</span>; <span class="keyword">if</span> (m_animating <span class="operator">|</span><span class="operator">|</span> m_vpDirty) { <span class="keyword">if</span> (m_vpDirty) <span class="operator">-</span><span class="operator">-</span>m_vpDirty; QMatrix4x4 vp<span class="operator">,</span> model; QMatrix3x3 modelNormal; QVector3D eyePos; getMatrices(<span class="operator">&</span>vp<span class="operator">,</span> <span class="operator">&</span>model<span class="operator">,</span> <span class="operator">&</span>modelNormal<span class="operator">,</span> <span class="operator">&</span>eyePos); <span class="comment">// Map the uniform data for the current frame, ignore the geometry data at</span> <span class="comment">// the beginning and the uniforms for other frames.</span> <span class="type"><a href="../qtcore/qtglobal.html#quint8-typedef">quint8</a></span> <span class="operator">*</span>p; VkResult err <span class="operator">=</span> m_devFuncs<span class="operator">-</span><span class="operator">></span>vkMapMemory(dev<span class="operator">,</span> m_bufMem<span class="operator">,</span> m_itemMaterial<span class="operator">.</span>uniMemStartOffset <span class="operator">+</span> frameUniOffset<span class="operator">,</span> m_itemMaterial<span class="operator">.</span>vertUniSize <span class="operator">+</span> m_itemMaterial<span class="operator">.</span>fragUniSize<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="keyword">reinterpret_cast</span><span class="operator"><</span><span class="type">void</span> <span class="operator">*</span><span class="operator">*</span><span class="operator">></span>(<span class="operator">&</span>p)); <span class="keyword">if</span> (err <span class="operator">!</span><span class="operator">=</span> VK_SUCCESS) <a href="../qtcore/qtglobal.html#qFatal">qFatal</a>(<span class="string">"Failed to map memory: %d"</span><span class="operator">,</span> err); <span class="comment">// Vertex shader uniforms</span> memcpy(p<span class="operator">,</span> vp<span class="operator">.</span>constData()<span class="operator">,</span> <span class="number">64</span>); memcpy(p <span class="operator">+</span> <span class="number">64</span><span class="operator">,</span> model<span class="operator">.</span>constData()<span class="operator">,</span> <span class="number">64</span>); <span class="keyword">const</span> <span class="type">float</span> <span class="operator">*</span>mnp <span class="operator">=</span> modelNormal<span class="operator">.</span>constData(); memcpy(p <span class="operator">+</span> <span class="number">128</span><span class="operator">,</span> mnp<span class="operator">,</span> <span class="number">12</span>); memcpy(p <span class="operator">+</span> <span class="number">128</span> <span class="operator">+</span> <span class="number">16</span><span class="operator">,</span> mnp <span class="operator">+</span> <span class="number">3</span><span class="operator">,</span> <span class="number">12</span>); memcpy(p <span class="operator">+</span> <span class="number">128</span> <span class="operator">+</span> <span class="number">32</span><span class="operator">,</span> mnp <span class="operator">+</span> <span class="number">6</span><span class="operator">,</span> <span class="number">12</span>); <span class="comment">// Fragment shader uniforms</span> p <span class="operator">+</span><span class="operator">=</span> m_itemMaterial<span class="operator">.</span>vertUniSize; writeFragUni(p<span class="operator">,</span> eyePos); m_devFuncs<span class="operator">-</span><span class="operator">></span>vkUnmapMemory(dev<span class="operator">,</span> m_bufMem); } m_devFuncs<span class="operator">-</span><span class="operator">></span>vkCmdDraw(cb<span class="operator">,</span> (m_useLogo <span class="operator">?</span> m_logoMesh<span class="operator">.</span>data() : m_blockMesh<span class="operator">.</span>data())<span class="operator">-</span><span class="operator">></span>vertexCount<span class="operator">,</span> m_instCount<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="number">0</span>); } <span class="type">void</span> Renderer<span class="operator">::</span>buildDrawCallsForFloor() { VkCommandBuffer cb <span class="operator">=</span> m_window<span class="operator">-</span><span class="operator">></span>currentCommandBuffer(); m_devFuncs<span class="operator">-</span><span class="operator">></span>vkCmdBindPipeline(cb<span class="operator">,</span> VK_PIPELINE_BIND_POINT_GRAPHICS<span class="operator">,</span> m_floorMaterial<span class="operator">.</span>pipeline); VkDeviceSize vbOffset <span class="operator">=</span> <span class="number">0</span>; m_devFuncs<span class="operator">-</span><span class="operator">></span>vkCmdBindVertexBuffers(cb<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="operator">&</span>m_floorVertexBuf<span class="operator">,</span> <span class="operator">&</span>vbOffset); QMatrix4x4 mvp <span class="operator">=</span> m_proj <span class="operator">*</span> m_cam<span class="operator">.</span>viewMatrix() <span class="operator">*</span> m_floorModel; m_devFuncs<span class="operator">-</span><span class="operator">></span>vkCmdPushConstants(cb<span class="operator">,</span> m_floorMaterial<span class="operator">.</span>pipelineLayout<span class="operator">,</span> VK_SHADER_STAGE_VERTEX_BIT<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="number">64</span><span class="operator">,</span> mvp<span class="operator">.</span>constData()); <span class="type">float</span> color<span class="operator">[</span><span class="operator">]</span> <span class="operator">=</span> { <span class="number">0.67f</span><span class="operator">,</span> <span class="number">1.0f</span><span class="operator">,</span> <span class="number">0.2f</span> }; m_devFuncs<span class="operator">-</span><span class="operator">></span>vkCmdPushConstants(cb<span class="operator">,</span> m_floorMaterial<span class="operator">.</span>pipelineLayout<span class="operator">,</span> VK_SHADER_STAGE_FRAGMENT_BIT<span class="operator">,</span> <span class="number">64</span><span class="operator">,</span> <span class="number">12</span><span class="operator">,</span> color); m_devFuncs<span class="operator">-</span><span class="operator">></span>vkCmdDraw(cb<span class="operator">,</span> <span class="number">4</span><span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="number">0</span>); } <span class="type">void</span> Renderer<span class="operator">::</span>addNew() { <span class="type"><a href="../qtcore/qmutexlocker.html">QMutexLocker</a></span> locker(<span class="operator">&</span>m_guiMutex); m_instCount <span class="operator">=</span> <a href="../qtcore/qtglobal.html#qMin">qMin</a>(m_instCount <span class="operator">+</span> <span class="number">16</span><span class="operator">,</span> MAX_INSTANCES); } <span class="type">void</span> Renderer<span class="operator">::</span>yaw(<span class="type">float</span> degrees) { <span class="type"><a href="../qtcore/qmutexlocker.html">QMutexLocker</a></span> locker(<span class="operator">&</span>m_guiMutex); m_cam<span class="operator">.</span>yaw(degrees); markViewProjDirty(); } <span class="type">void</span> Renderer<span class="operator">::</span>pitch(<span class="type">float</span> degrees) { <span class="type"><a href="../qtcore/qmutexlocker.html">QMutexLocker</a></span> locker(<span class="operator">&</span>m_guiMutex); m_cam<span class="operator">.</span>pitch(degrees); markViewProjDirty(); } <span class="type">void</span> Renderer<span class="operator">::</span>walk(<span class="type">float</span> amount) { <span class="type"><a href="../qtcore/qmutexlocker.html">QMutexLocker</a></span> locker(<span class="operator">&</span>m_guiMutex); m_cam<span class="operator">.</span>walk(amount); markViewProjDirty(); } <span class="type">void</span> Renderer<span class="operator">::</span>strafe(<span class="type">float</span> amount) { <span class="type"><a href="../qtcore/qmutexlocker.html">QMutexLocker</a></span> locker(<span class="operator">&</span>m_guiMutex); m_cam<span class="operator">.</span>strafe(amount); markViewProjDirty(); } <span class="type">void</span> Renderer<span class="operator">::</span>setUseLogo(bool b) { <span class="type"><a href="../qtcore/qmutexlocker.html">QMutexLocker</a></span> locker(<span class="operator">&</span>m_guiMutex); m_useLogo <span class="operator">=</span> b; <span class="keyword">if</span> (<span class="operator">!</span>m_animating) m_window<span class="operator">-</span><span class="operator">></span>requestUpdate(); } </pre> </div> <!-- @@@hellovulkancubes/renderer.cpp --> </div> </div> </div> </div> </div> <div class="footer"> <p> <acronym title="Copyright">©</acronym> 2019 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners.<br/> The documentation provided herein is licensed under the terms of the <a href="http://www.gnu.org/licenses/fdl.html">GNU Free Documentation License version 1.3</a> as published by the Free Software Foundation.<br/> Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners. </p> </div> </body> </html>