<?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>hellovulkantexture.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-hellovulkantexture-example.html">Hello Vulkan Texture Vulkan Example</a></td><td >hellovulkantexture.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">hellovulkantexture.cpp Example File</h1> <span class="subtitle">hellovulkantexture/hellovulkantexture.cpp</span> <!-- $$$hellovulkantexture/hellovulkantexture.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 "hellovulkantexture.h"</span> <span class="preprocessor">#include <QVulkanFunctions></span> <span class="preprocessor">#include <QCoreApplication></span> <span class="preprocessor">#include <QFile></span> <span class="comment">// Use a triangle strip to get a quad.</span> <span class="comment">//</span> <span class="comment">// Note that the vertex data and the projection matrix assume OpenGL. With</span> <span class="comment">// Vulkan Y is negated in clip space and the near/far plane is at 0/1 instead</span> <span class="comment">// of -1/1. These will be corrected for by an extra transformation when</span> <span class="comment">// calculating the modelview-projection matrix.</span> <span class="keyword">static</span> <span class="type">float</span> vertexData<span class="operator">[</span><span class="operator">]</span> <span class="operator">=</span> { <span class="comment">// Y up, front = CW</span> <span class="comment">// x, y, z, u, v</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">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">1</span><span class="operator">,</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> <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">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="number">0</span> }; <span class="keyword">static</span> <span class="keyword">const</span> <span class="type">int</span> UNIFORM_DATA_SIZE <span class="operator">=</span> <span class="number">16</span> <span class="operator">*</span> <span class="keyword">sizeof</span>(<span class="type">float</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>); } <span class="type"><a href="qvulkanwindowrenderer.html">QVulkanWindowRenderer</a></span> <span class="operator">*</span>VulkanWindow<span class="operator">::</span>createRenderer() { <span class="keyword">return</span> <span class="keyword">new</span> VulkanRenderer(<span class="keyword">this</span>); } VulkanRenderer<span class="operator">::</span>VulkanRenderer(<span class="type"><a href="qvulkanwindow.html">QVulkanWindow</a></span> <span class="operator">*</span>w) : m_window(w) { } VkShaderModule VulkanRenderer<span class="operator">::</span>createShader(<span class="keyword">const</span> <span class="type"><a href="../qtcore/qstring.html">QString</a></span> <span class="operator">&</span>name) { <span class="type"><a href="../qtcore/qfile.html">QFile</a></span> file(name); <span class="keyword">if</span> (<span class="operator">!</span>file<span class="operator">.</span>open(<span class="type"><a href="../qtcore/qiodevice.html">QIODevice</a></span><span class="operator">::</span>ReadOnly)) { <a href="../qtcore/qtglobal.html#qWarning">qWarning</a>(<span class="string">"Failed to read shader %s"</span><span class="operator">,</span> <a href="../qtcore/qtglobal.html#qPrintable">qPrintable</a>(name)); <span class="keyword">return</span> VK_NULL_HANDLE; } <span class="type"><a href="../qtcore/qbytearray.html">QByteArray</a></span> blob <span class="operator">=</span> file<span class="operator">.</span>readAll(); file<span class="operator">.</span>close(); VkShaderModuleCreateInfo shaderInfo; memset(<span class="operator">&</span>shaderInfo<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="keyword">sizeof</span>(shaderInfo)); shaderInfo<span class="operator">.</span>sType <span class="operator">=</span> VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; shaderInfo<span class="operator">.</span>codeSize <span class="operator">=</span> blob<span class="operator">.</span>size(); shaderInfo<span class="operator">.</span>pCode <span class="operator">=</span> <span class="keyword">reinterpret_cast</span><span class="operator"><</span><span class="keyword">const</span> uint32_t <span class="operator">*</span><span class="operator">></span>(blob<span class="operator">.</span>constData()); VkShaderModule shaderModule; VkResult err <span class="operator">=</span> m_devFuncs<span class="operator">-</span><span class="operator">></span>vkCreateShaderModule(m_window<span class="operator">-</span><span class="operator">></span>device()<span class="operator">,</span> <span class="operator">&</span>shaderInfo<span class="operator">,</span> nullptr<span class="operator">,</span> <span class="operator">&</span>shaderModule); <span class="keyword">if</span> (err <span class="operator">!</span><span class="operator">=</span> VK_SUCCESS) { <a href="../qtcore/qtglobal.html#qWarning">qWarning</a>(<span class="string">"Failed to create shader module: %d"</span><span class="operator">,</span> err); <span class="keyword">return</span> VK_NULL_HANDLE; } <span class="keyword">return</span> shaderModule; } bool VulkanRenderer<span class="operator">::</span>createTexture(<span class="keyword">const</span> <span class="type"><a href="../qtcore/qstring.html">QString</a></span> <span class="operator">&</span>name) { <span class="type"><a href="qimage.html">QImage</a></span> img(name); <span class="keyword">if</span> (img<span class="operator">.</span>isNull()) { <a href="../qtcore/qtglobal.html#qWarning">qWarning</a>(<span class="string">"Failed to load image %s"</span><span class="operator">,</span> <a href="../qtcore/qtglobal.html#qPrintable">qPrintable</a>(name)); <span class="keyword">return</span> <span class="keyword">false</span>; } <span class="comment">// Convert to byte ordered RGBA8. Use premultiplied alpha, see pColorBlendState in the pipeline.</span> img <span class="operator">=</span> img<span class="operator">.</span>convertToFormat(<span class="type"><a href="qimage.html">QImage</a></span><span class="operator">::</span>Format_RGBA8888_Premultiplied); <span class="type"><a href="qvulkanfunctions.html">QVulkanFunctions</a></span> <span class="operator">*</span>f <span class="operator">=</span> m_window<span class="operator">-</span><span class="operator">></span>vulkanInstance()<span class="operator">-</span><span class="operator">></span>functions(); VkDevice dev <span class="operator">=</span> m_window<span class="operator">-</span><span class="operator">></span>device(); <span class="keyword">const</span> bool srgb <span class="operator">=</span> <span class="type"><a href="../qtcore/qcoreapplication.html">QCoreApplication</a></span><span class="operator">::</span>arguments()<span class="operator">.</span>contains(<span class="type"><a href="../qtcore/qstring.html#QStringLiteral">QStringLiteral</a></span>(<span class="string">"--srgb"</span>)); <span class="keyword">if</span> (srgb) <a href="../qtcore/qtglobal.html#qDebug">qDebug</a>(<span class="string">"sRGB swapchain was requested, making texture sRGB too"</span>); m_texFormat <span class="operator">=</span> srgb <span class="operator">?</span> VK_FORMAT_R8G8B8A8_SRGB : VK_FORMAT_R8G8B8A8_UNORM; <span class="comment">// Now we can either map and copy the image data directly, or have to go</span> <span class="comment">// through a staging buffer to copy and convert into the internal optimal</span> <span class="comment">// tiling format.</span> VkFormatProperties props; f<span class="operator">-</span><span class="operator">></span>vkGetPhysicalDeviceFormatProperties(m_window<span class="operator">-</span><span class="operator">></span>physicalDevice()<span class="operator">,</span> m_texFormat<span class="operator">,</span> <span class="operator">&</span>props); <span class="keyword">const</span> bool canSampleLinear <span class="operator">=</span> (props<span class="operator">.</span>linearTilingFeatures <span class="operator">&</span> VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT); <span class="keyword">const</span> bool canSampleOptimal <span class="operator">=</span> (props<span class="operator">.</span>optimalTilingFeatures <span class="operator">&</span> VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT); <span class="keyword">if</span> (<span class="operator">!</span>canSampleLinear <span class="operator">&</span><span class="operator">&</span> <span class="operator">!</span>canSampleOptimal) { <a href="../qtcore/qtglobal.html#qWarning">qWarning</a>(<span class="string">"Neither linear nor optimal image sampling is supported for RGBA8"</span>); <span class="keyword">return</span> <span class="keyword">false</span>; } <span class="keyword">static</span> bool alwaysStage <span class="operator">=</span> <a href="../qtcore/qtglobal.html#qEnvironmentVariableIntValue">qEnvironmentVariableIntValue</a>(<span class="string">"QT_VK_FORCE_STAGE_TEX"</span>); <span class="keyword">if</span> (canSampleLinear <span class="operator">&</span><span class="operator">&</span> <span class="operator">!</span>alwaysStage) { <span class="keyword">if</span> (<span class="operator">!</span>createTextureImage(img<span class="operator">.</span>size()<span class="operator">,</span> <span class="operator">&</span>m_texImage<span class="operator">,</span> <span class="operator">&</span>m_texMem<span class="operator">,</span> VK_IMAGE_TILING_LINEAR<span class="operator">,</span> VK_IMAGE_USAGE_SAMPLED_BIT<span class="operator">,</span> m_window<span class="operator">-</span><span class="operator">></span>hostVisibleMemoryIndex())) <span class="keyword">return</span> <span class="keyword">false</span>; <span class="keyword">if</span> (<span class="operator">!</span>writeLinearImage(img<span class="operator">,</span> m_texImage<span class="operator">,</span> m_texMem)) <span class="keyword">return</span> <span class="keyword">false</span>; m_texLayoutPending <span class="operator">=</span> <span class="keyword">true</span>; } <span class="keyword">else</span> { <span class="keyword">if</span> (<span class="operator">!</span>createTextureImage(img<span class="operator">.</span>size()<span class="operator">,</span> <span class="operator">&</span>m_texStaging<span class="operator">,</span> <span class="operator">&</span>m_texStagingMem<span class="operator">,</span> VK_IMAGE_TILING_LINEAR<span class="operator">,</span> VK_IMAGE_USAGE_TRANSFER_SRC_BIT<span class="operator">,</span> m_window<span class="operator">-</span><span class="operator">></span>hostVisibleMemoryIndex())) <span class="keyword">return</span> <span class="keyword">false</span>; <span class="keyword">if</span> (<span class="operator">!</span>createTextureImage(img<span class="operator">.</span>size()<span class="operator">,</span> <span class="operator">&</span>m_texImage<span class="operator">,</span> <span class="operator">&</span>m_texMem<span class="operator">,</span> VK_IMAGE_TILING_OPTIMAL<span class="operator">,</span> VK_IMAGE_USAGE_TRANSFER_DST_BIT <span class="operator">|</span> VK_IMAGE_USAGE_SAMPLED_BIT<span class="operator">,</span> m_window<span class="operator">-</span><span class="operator">></span>deviceLocalMemoryIndex())) <span class="keyword">return</span> <span class="keyword">false</span>; <span class="keyword">if</span> (<span class="operator">!</span>writeLinearImage(img<span class="operator">,</span> m_texStaging<span class="operator">,</span> m_texStagingMem)) <span class="keyword">return</span> <span class="keyword">false</span>; m_texStagingPending <span class="operator">=</span> <span class="keyword">true</span>; } VkImageViewCreateInfo viewInfo; memset(<span class="operator">&</span>viewInfo<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="keyword">sizeof</span>(viewInfo)); viewInfo<span class="operator">.</span>sType <span class="operator">=</span> VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; viewInfo<span class="operator">.</span>image <span class="operator">=</span> m_texImage; viewInfo<span class="operator">.</span>viewType <span class="operator">=</span> VK_IMAGE_VIEW_TYPE_2D; viewInfo<span class="operator">.</span>format <span class="operator">=</span> m_texFormat; viewInfo<span class="operator">.</span>components<span class="operator">.</span>r <span class="operator">=</span> VK_COMPONENT_SWIZZLE_R; viewInfo<span class="operator">.</span>components<span class="operator">.</span>g <span class="operator">=</span> VK_COMPONENT_SWIZZLE_G; viewInfo<span class="operator">.</span>components<span class="operator">.</span>b <span class="operator">=</span> VK_COMPONENT_SWIZZLE_B; viewInfo<span class="operator">.</span>components<span class="operator">.</span>a <span class="operator">=</span> VK_COMPONENT_SWIZZLE_A; viewInfo<span class="operator">.</span>subresourceRange<span class="operator">.</span>aspectMask <span class="operator">=</span> VK_IMAGE_ASPECT_COLOR_BIT; viewInfo<span class="operator">.</span>subresourceRange<span class="operator">.</span>levelCount <span class="operator">=</span> viewInfo<span class="operator">.</span>subresourceRange<span class="operator">.</span>layerCount <span class="operator">=</span> <span class="number">1</span>; VkResult err <span class="operator">=</span> m_devFuncs<span class="operator">-</span><span class="operator">></span>vkCreateImageView(dev<span class="operator">,</span> <span class="operator">&</span>viewInfo<span class="operator">,</span> nullptr<span class="operator">,</span> <span class="operator">&</span>m_texView); <span class="keyword">if</span> (err <span class="operator">!</span><span class="operator">=</span> VK_SUCCESS) { <a href="../qtcore/qtglobal.html#qWarning">qWarning</a>(<span class="string">"Failed to create image view for texture: %d"</span><span class="operator">,</span> err); <span class="keyword">return</span> <span class="keyword">false</span>; } m_texSize <span class="operator">=</span> img<span class="operator">.</span>size(); <span class="keyword">return</span> <span class="keyword">true</span>; } bool VulkanRenderer<span class="operator">::</span>createTextureImage(<span class="keyword">const</span> <span class="type"><a href="../qtcore/qsize.html">QSize</a></span> <span class="operator">&</span>size<span class="operator">,</span> VkImage <span class="operator">*</span>image<span class="operator">,</span> VkDeviceMemory <span class="operator">*</span>mem<span class="operator">,</span> VkImageTiling tiling<span class="operator">,</span> VkImageUsageFlags usage<span class="operator">,</span> uint32_t memIndex) { VkDevice dev <span class="operator">=</span> m_window<span class="operator">-</span><span class="operator">></span>device(); VkImageCreateInfo imageInfo; memset(<span class="operator">&</span>imageInfo<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="keyword">sizeof</span>(imageInfo)); imageInfo<span class="operator">.</span>sType <span class="operator">=</span> VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; imageInfo<span class="operator">.</span>imageType <span class="operator">=</span> VK_IMAGE_TYPE_2D; imageInfo<span class="operator">.</span>format <span class="operator">=</span> m_texFormat; imageInfo<span class="operator">.</span>extent<span class="operator">.</span>width <span class="operator">=</span> size<span class="operator">.</span>width(); imageInfo<span class="operator">.</span>extent<span class="operator">.</span>height <span class="operator">=</span> size<span class="operator">.</span>height(); imageInfo<span class="operator">.</span>extent<span class="operator">.</span>depth <span class="operator">=</span> <span class="number">1</span>; imageInfo<span class="operator">.</span>mipLevels <span class="operator">=</span> <span class="number">1</span>; imageInfo<span class="operator">.</span>arrayLayers <span class="operator">=</span> <span class="number">1</span>; imageInfo<span class="operator">.</span>samples <span class="operator">=</span> VK_SAMPLE_COUNT_1_BIT; imageInfo<span class="operator">.</span>tiling <span class="operator">=</span> tiling; imageInfo<span class="operator">.</span>usage <span class="operator">=</span> usage; imageInfo<span class="operator">.</span>initialLayout <span class="operator">=</span> VK_IMAGE_LAYOUT_PREINITIALIZED; VkResult err <span class="operator">=</span> m_devFuncs<span class="operator">-</span><span class="operator">></span>vkCreateImage(dev<span class="operator">,</span> <span class="operator">&</span>imageInfo<span class="operator">,</span> nullptr<span class="operator">,</span> image); <span class="keyword">if</span> (err <span class="operator">!</span><span class="operator">=</span> VK_SUCCESS) { <a href="../qtcore/qtglobal.html#qWarning">qWarning</a>(<span class="string">"Failed to create linear image for texture: %d"</span><span class="operator">,</span> err); <span class="keyword">return</span> <span class="keyword">false</span>; } VkMemoryRequirements memReq; m_devFuncs<span class="operator">-</span><span class="operator">></span>vkGetImageMemoryRequirements(dev<span class="operator">,</span> <span class="operator">*</span>image<span class="operator">,</span> <span class="operator">&</span>memReq); <span class="keyword">if</span> (<span class="operator">!</span>(memReq<span class="operator">.</span>memoryTypeBits <span class="operator">&</span> (<span class="number">1</span> <span class="operator"><</span><span class="operator"><</span> memIndex))) { VkPhysicalDeviceMemoryProperties physDevMemProps; m_window<span class="operator">-</span><span class="operator">></span>vulkanInstance()<span class="operator">-</span><span class="operator">></span>functions()<span class="operator">-</span><span class="operator">></span>vkGetPhysicalDeviceMemoryProperties(m_window<span class="operator">-</span><span class="operator">></span>physicalDevice()<span class="operator">,</span> <span class="operator">&</span>physDevMemProps); <span class="keyword">for</span> (uint32_t i <span class="operator">=</span> <span class="number">0</span>; i <span class="operator"><</span> physDevMemProps<span class="operator">.</span>memoryTypeCount; <span class="operator">+</span><span class="operator">+</span>i) { <span class="keyword">if</span> (<span class="operator">!</span>(memReq<span class="operator">.</span>memoryTypeBits <span class="operator">&</span> (<span class="number">1</span> <span class="operator"><</span><span class="operator"><</span> i))) <span class="keyword">continue</span>; memIndex <span class="operator">=</span> i; } } VkMemoryAllocateInfo allocInfo <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> memIndex }; <a href="../qtcore/qtglobal.html#qDebug">qDebug</a>(<span class="string">"allocating %u bytes for texture image"</span><span class="operator">,</span> uint32_t(memReq<span class="operator">.</span>size)); 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>allocInfo<span class="operator">,</span> nullptr<span class="operator">,</span> mem); <span class="keyword">if</span> (err <span class="operator">!</span><span class="operator">=</span> VK_SUCCESS) { <a href="../qtcore/qtglobal.html#qWarning">qWarning</a>(<span class="string">"Failed to allocate memory for linear image: %d"</span><span class="operator">,</span> err); <span class="keyword">return</span> <span class="keyword">false</span>; } err <span class="operator">=</span> m_devFuncs<span class="operator">-</span><span class="operator">></span>vkBindImageMemory(dev<span class="operator">,</span> <span class="operator">*</span>image<span class="operator">,</span> <span class="operator">*</span>mem<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#qWarning">qWarning</a>(<span class="string">"Failed to bind linear image memory: %d"</span><span class="operator">,</span> err); <span class="keyword">return</span> <span class="keyword">false</span>; } <span class="keyword">return</span> <span class="keyword">true</span>; } bool VulkanRenderer<span class="operator">::</span>writeLinearImage(<span class="keyword">const</span> <span class="type"><a href="qimage.html">QImage</a></span> <span class="operator">&</span>img<span class="operator">,</span> VkImage image<span class="operator">,</span> VkDeviceMemory memory) { VkDevice dev <span class="operator">=</span> m_window<span class="operator">-</span><span class="operator">></span>device(); VkImageSubresource subres <span class="operator">=</span> { VK_IMAGE_ASPECT_COLOR_BIT<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="comment">// mip level</span> <span class="number">0</span> }; VkSubresourceLayout layout; m_devFuncs<span class="operator">-</span><span class="operator">></span>vkGetImageSubresourceLayout(dev<span class="operator">,</span> image<span class="operator">,</span> <span class="operator">&</span>subres<span class="operator">,</span> <span class="operator">&</span>layout); <span class="type"><a href="../qtcore/qtglobal.html#uchar-typedef">uchar</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> memory<span class="operator">,</span> layout<span class="operator">.</span>offset<span class="operator">,</span> layout<span class="operator">.</span>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#qWarning">qWarning</a>(<span class="string">"Failed to map memory for linear image: %d"</span><span class="operator">,</span> err); <span class="keyword">return</span> <span class="keyword">false</span>; } <span class="keyword">for</span> (<span class="type">int</span> y <span class="operator">=</span> <span class="number">0</span>; y <span class="operator"><</span> img<span class="operator">.</span>height(); <span class="operator">+</span><span class="operator">+</span>y) { <span class="keyword">const</span> <span class="type"><a href="../qtcore/qtglobal.html#uchar-typedef">uchar</a></span> <span class="operator">*</span>line <span class="operator">=</span> img<span class="operator">.</span>constScanLine(y); memcpy(p<span class="operator">,</span> line<span class="operator">,</span> img<span class="operator">.</span>width() <span class="operator">*</span> <span class="number">4</span>); p <span class="operator">+</span><span class="operator">=</span> layout<span class="operator">.</span>rowPitch; } m_devFuncs<span class="operator">-</span><span class="operator">></span>vkUnmapMemory(dev<span class="operator">,</span> memory); <span class="keyword">return</span> <span class="keyword">true</span>; } <span class="type">void</span> VulkanRenderer<span class="operator">::</span>ensureTexture() { <span class="keyword">if</span> (<span class="operator">!</span>m_texLayoutPending <span class="operator">&</span><span class="operator">&</span> <span class="operator">!</span>m_texStagingPending) <span class="keyword">return</span>; Q_ASSERT(m_texLayoutPending <span class="operator">!</span><span class="operator">=</span> m_texStagingPending); VkCommandBuffer cb <span class="operator">=</span> m_window<span class="operator">-</span><span class="operator">></span>currentCommandBuffer(); VkImageMemoryBarrier barrier; memset(<span class="operator">&</span>barrier<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="keyword">sizeof</span>(barrier)); barrier<span class="operator">.</span>sType <span class="operator">=</span> VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; barrier<span class="operator">.</span>subresourceRange<span class="operator">.</span>aspectMask <span class="operator">=</span> VK_IMAGE_ASPECT_COLOR_BIT; barrier<span class="operator">.</span>subresourceRange<span class="operator">.</span>levelCount <span class="operator">=</span> barrier<span class="operator">.</span>subresourceRange<span class="operator">.</span>layerCount <span class="operator">=</span> <span class="number">1</span>; <span class="keyword">if</span> (m_texLayoutPending) { m_texLayoutPending <span class="operator">=</span> <span class="keyword">false</span>; barrier<span class="operator">.</span>oldLayout <span class="operator">=</span> VK_IMAGE_LAYOUT_PREINITIALIZED; barrier<span class="operator">.</span>newLayout <span class="operator">=</span> VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; barrier<span class="operator">.</span>srcAccessMask <span class="operator">=</span> VK_ACCESS_HOST_WRITE_BIT; barrier<span class="operator">.</span>dstAccessMask <span class="operator">=</span> VK_ACCESS_SHADER_READ_BIT; barrier<span class="operator">.</span>image <span class="operator">=</span> m_texImage; m_devFuncs<span class="operator">-</span><span class="operator">></span>vkCmdPipelineBarrier(cb<span class="operator">,</span> VK_PIPELINE_STAGE_HOST_BIT<span class="operator">,</span> VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> nullptr<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> nullptr<span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="operator">&</span>barrier); } <span class="keyword">else</span> { m_texStagingPending <span class="operator">=</span> <span class="keyword">false</span>; barrier<span class="operator">.</span>oldLayout <span class="operator">=</span> VK_IMAGE_LAYOUT_PREINITIALIZED; barrier<span class="operator">.</span>newLayout <span class="operator">=</span> VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; barrier<span class="operator">.</span>srcAccessMask <span class="operator">=</span> VK_ACCESS_HOST_WRITE_BIT; barrier<span class="operator">.</span>dstAccessMask <span class="operator">=</span> VK_ACCESS_TRANSFER_READ_BIT; barrier<span class="operator">.</span>image <span class="operator">=</span> m_texStaging; m_devFuncs<span class="operator">-</span><span class="operator">></span>vkCmdPipelineBarrier(cb<span class="operator">,</span> VK_PIPELINE_STAGE_HOST_BIT<span class="operator">,</span> VK_PIPELINE_STAGE_TRANSFER_BIT<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> nullptr<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> nullptr<span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="operator">&</span>barrier); barrier<span class="operator">.</span>oldLayout <span class="operator">=</span> VK_IMAGE_LAYOUT_PREINITIALIZED; barrier<span class="operator">.</span>newLayout <span class="operator">=</span> VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; barrier<span class="operator">.</span>srcAccessMask <span class="operator">=</span> <span class="number">0</span>; barrier<span class="operator">.</span>dstAccessMask <span class="operator">=</span> VK_ACCESS_TRANSFER_WRITE_BIT; barrier<span class="operator">.</span>image <span class="operator">=</span> m_texImage; m_devFuncs<span class="operator">-</span><span class="operator">></span>vkCmdPipelineBarrier(cb<span class="operator">,</span> VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT<span class="operator">,</span> VK_PIPELINE_STAGE_TRANSFER_BIT<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> nullptr<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> nullptr<span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="operator">&</span>barrier); VkImageCopy copyInfo; memset(<span class="operator">&</span>copyInfo<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="keyword">sizeof</span>(copyInfo)); copyInfo<span class="operator">.</span>srcSubresource<span class="operator">.</span>aspectMask <span class="operator">=</span> VK_IMAGE_ASPECT_COLOR_BIT; copyInfo<span class="operator">.</span>srcSubresource<span class="operator">.</span>layerCount <span class="operator">=</span> <span class="number">1</span>; copyInfo<span class="operator">.</span>dstSubresource<span class="operator">.</span>aspectMask <span class="operator">=</span> VK_IMAGE_ASPECT_COLOR_BIT; copyInfo<span class="operator">.</span>dstSubresource<span class="operator">.</span>layerCount <span class="operator">=</span> <span class="number">1</span>; copyInfo<span class="operator">.</span>extent<span class="operator">.</span>width <span class="operator">=</span> m_texSize<span class="operator">.</span>width(); copyInfo<span class="operator">.</span>extent<span class="operator">.</span>height <span class="operator">=</span> m_texSize<span class="operator">.</span>height(); copyInfo<span class="operator">.</span>extent<span class="operator">.</span>depth <span class="operator">=</span> <span class="number">1</span>; m_devFuncs<span class="operator">-</span><span class="operator">></span>vkCmdCopyImage(cb<span class="operator">,</span> m_texStaging<span class="operator">,</span> VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL<span class="operator">,</span> m_texImage<span class="operator">,</span> VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL<span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="operator">&</span>copyInfo); barrier<span class="operator">.</span>oldLayout <span class="operator">=</span> VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; barrier<span class="operator">.</span>newLayout <span class="operator">=</span> VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; barrier<span class="operator">.</span>srcAccessMask <span class="operator">=</span> VK_ACCESS_TRANSFER_WRITE_BIT; barrier<span class="operator">.</span>dstAccessMask <span class="operator">=</span> VK_ACCESS_SHADER_READ_BIT; barrier<span class="operator">.</span>image <span class="operator">=</span> m_texImage; m_devFuncs<span class="operator">-</span><span class="operator">></span>vkCmdPipelineBarrier(cb<span class="operator">,</span> VK_PIPELINE_STAGE_TRANSFER_BIT<span class="operator">,</span> VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> nullptr<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> nullptr<span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="operator">&</span>barrier); } } <span class="type">void</span> VulkanRenderer<span class="operator">::</span>initResources() { <a href="../qtcore/qtglobal.html#qDebug">qDebug</a>(<span class="string">"initResources"</span>); VkDevice dev <span class="operator">=</span> m_window<span class="operator">-</span><span class="operator">></span>device(); m_devFuncs <span class="operator">=</span> m_window<span class="operator">-</span><span class="operator">></span>vulkanInstance()<span class="operator">-</span><span class="operator">></span>deviceFunctions(dev); <span class="comment">// The setup is similar to hellovulkantriangle. The difference is the</span> <span class="comment">// presence of a second vertex attribute (texcoord), a sampler, and that we</span> <span class="comment">// need blending.</span> <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="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; <a href="../qtcore/qtglobal.html#qDebug">qDebug</a>(<span class="string">"uniform buffer offset alignment is %u"</span><span class="operator">,</span> (<span class="type"><a href="../qtcore/qtglobal.html#uint-typedef">uint</a></span>) uniAlign); 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="comment">// Our internal layout is vertex, uniform, uniform, ... with each uniform buffer start offset aligned to uniAlign.</span> <span class="keyword">const</span> VkDeviceSize vertexAllocSize <span class="operator">=</span> aligned(<span class="keyword">sizeof</span>(vertexData)<span class="operator">,</span> uniAlign); <span class="keyword">const</span> VkDeviceSize uniformAllocSize <span class="operator">=</span> aligned(UNIFORM_DATA_SIZE<span class="operator">,</span> uniAlign); bufInfo<span class="operator">.</span>size <span class="operator">=</span> vertexAllocSize <span class="operator">+</span> concurrentFrameCount <span class="operator">*</span> uniformAllocSize; bufInfo<span class="operator">.</span>usage <span class="operator">=</span> VK_BUFFER_USAGE_VERTEX_BUFFER_BIT <span class="operator">|</span> VK_BUFFER_USAGE_UNIFORM_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_buf); <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 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_buf<span class="operator">,</span> <span class="operator">&</span>memReq); 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_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_buf<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 buffer memory: %d"</span><span class="operator">,</span> err); <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> memReq<span class="operator">.</span>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> vertexData<span class="operator">,</span> <span class="keyword">sizeof</span>(vertexData)); QMatrix4x4 ident; memset(m_uniformBufInfo<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="keyword">sizeof</span>(m_uniformBufInfo)); <span class="keyword">for</span> (<span class="type">int</span> i <span class="operator">=</span> <span class="number">0</span>; i <span class="operator"><</span> concurrentFrameCount; <span class="operator">+</span><span class="operator">+</span>i) { <span class="keyword">const</span> VkDeviceSize offset <span class="operator">=</span> vertexAllocSize <span class="operator">+</span> i <span class="operator">*</span> uniformAllocSize; memcpy(p <span class="operator">+</span> offset<span class="operator">,</span> ident<span class="operator">.</span>constData()<span class="operator">,</span> <span class="number">16</span> <span class="operator">*</span> <span class="keyword">sizeof</span>(<span class="type">float</span>)); m_uniformBufInfo<span class="operator">[</span>i<span class="operator">]</span><span class="operator">.</span>buffer <span class="operator">=</span> m_buf; m_uniformBufInfo<span class="operator">[</span>i<span class="operator">]</span><span class="operator">.</span>offset <span class="operator">=</span> offset; m_uniformBufInfo<span class="operator">[</span>i<span class="operator">]</span><span class="operator">.</span>range <span class="operator">=</span> uniformAllocSize; } m_devFuncs<span class="operator">-</span><span class="operator">></span>vkUnmapMemory(dev<span class="operator">,</span> m_bufMem); VkVertexInputBindingDescription vertexBindingDesc <span class="operator">=</span> { <span class="number">0</span><span class="operator">,</span> <span class="comment">// binding</span> <span class="number">5</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="operator">,</span> { <span class="comment">// texcoord</span> <span class="number">1</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> VK_FORMAT_R32G32_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="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="number">2</span>; vertexInputInfo<span class="operator">.</span>pVertexAttributeDescriptions <span class="operator">=</span> vertexAttrDesc; <span class="comment">// Sampler.</span> VkSamplerCreateInfo samplerInfo; memset(<span class="operator">&</span>samplerInfo<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="keyword">sizeof</span>(samplerInfo)); samplerInfo<span class="operator">.</span>sType <span class="operator">=</span> VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; samplerInfo<span class="operator">.</span>magFilter <span class="operator">=</span> VK_FILTER_NEAREST; samplerInfo<span class="operator">.</span>minFilter <span class="operator">=</span> VK_FILTER_NEAREST; samplerInfo<span class="operator">.</span>addressModeU <span class="operator">=</span> VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; samplerInfo<span class="operator">.</span>addressModeV <span class="operator">=</span> VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; samplerInfo<span class="operator">.</span>addressModeW <span class="operator">=</span> VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; samplerInfo<span class="operator">.</span>maxAnisotropy <span class="operator">=</span> <span class="number">1.0f</span>; err <span class="operator">=</span> m_devFuncs<span class="operator">-</span><span class="operator">></span>vkCreateSampler(dev<span class="operator">,</span> <span class="operator">&</span>samplerInfo<span class="operator">,</span> nullptr<span class="operator">,</span> <span class="operator">&</span>m_sampler); <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 sampler: %d"</span><span class="operator">,</span> err); <span class="comment">// Texture.</span> <span class="keyword">if</span> (<span class="operator">!</span>createTexture(<span class="type"><a href="../qtcore/qstring.html#QStringLiteral">QStringLiteral</a></span>(<span class="string">":/qt256.png"</span>))) <a href="../qtcore/qtglobal.html#qFatal">qFatal</a>(<span class="string">"Failed to create texture"</span>); <span class="comment">// Set up descriptor set and its layout.</span> VkDescriptorPoolSize descPoolSizes<span class="operator">[</span><span class="number">2</span><span class="operator">]</span> <span class="operator">=</span> { { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER<span class="operator">,</span> uint32_t(concurrentFrameCount) }<span class="operator">,</span> { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER<span class="operator">,</span> uint32_t(concurrentFrameCount) } }; 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> concurrentFrameCount; descPoolInfo<span class="operator">.</span>poolSizeCount <span class="operator">=</span> <span class="number">2</span>; descPoolInfo<span class="operator">.</span>pPoolSizes <span class="operator">=</span> descPoolSizes; 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_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 layoutBinding<span class="operator">[</span><span class="number">2</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<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> <span class="comment">// binding</span> VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER<span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="comment">// descriptorCount</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="number">2</span><span class="operator">,</span> <span class="comment">// bindingCount</span> layoutBinding }; 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_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); <span class="keyword">for</span> (<span class="type">int</span> i <span class="operator">=</span> <span class="number">0</span>; i <span class="operator"><</span> concurrentFrameCount; <span class="operator">+</span><span class="operator">+</span>i) { VkDescriptorSetAllocateInfo descSetAllocInfo <span class="operator">=</span> { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO<span class="operator">,</span> nullptr<span class="operator">,</span> m_descPool<span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="operator">&</span>m_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_descSet<span class="operator">[</span>i<span class="operator">]</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 allocate descriptor set: %d"</span><span class="operator">,</span> err); 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_descSet<span class="operator">[</span>i<span class="operator">]</span>; 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; 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>m_uniformBufInfo<span class="operator">[</span>i<span class="operator">]</span>; VkDescriptorImageInfo descImageInfo <span class="operator">=</span> { m_sampler<span class="operator">,</span> m_texView<span class="operator">,</span> VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }; 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_descSet<span class="operator">[</span>i<span class="operator">]</span>; 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_COMBINED_IMAGE_SAMPLER; descWrite<span class="operator">[</span><span class="number">1</span><span class="operator">]</span><span class="operator">.</span>pImageInfo <span class="operator">=</span> <span class="operator">&</span>descImageInfo; 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="comment">// Pipeline cache</span> 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; 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); <span class="comment">// Pipeline layout</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_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_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); <span class="comment">// Shaders</span> VkShaderModule vertShaderModule <span class="operator">=</span> createShader(<span class="type"><a href="../qtcore/qstring.html#QStringLiteral">QStringLiteral</a></span>(<span class="string">":/texture_vert.spv"</span>)); VkShaderModule fragShaderModule <span class="operator">=</span> createShader(<span class="type"><a href="../qtcore/qstring.html#QStringLiteral">QStringLiteral</a></span>(<span class="string">":/texture_frag.spv"</span>)); <span class="comment">// Graphics pipeline</span> 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> vertShaderModule<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> fragShaderModule<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; <span class="comment">// The viewport and scissor will be set dynamically via vkCmdSetViewport/Scissor.</span> <span class="comment">// This way the pipeline does not need to be touched when resizing the window.</span> 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> VK_SAMPLE_COUNT_1_BIT; 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; <span class="comment">// assume pre-multiplied alpha, blend, write out all of rgba</span> 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>; att<span class="operator">.</span>blendEnable <span class="operator">=</span> VK_TRUE; att<span class="operator">.</span>srcColorBlendFactor <span class="operator">=</span> VK_BLEND_FACTOR_ONE; att<span class="operator">.</span>dstColorBlendFactor <span class="operator">=</span> VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; att<span class="operator">.</span>colorBlendOp <span class="operator">=</span> VK_BLEND_OP_ADD; att<span class="operator">.</span>srcAlphaBlendFactor <span class="operator">=</span> VK_BLEND_FACTOR_ONE; att<span class="operator">.</span>dstAlphaBlendFactor <span class="operator">=</span> VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; att<span class="operator">.</span>alphaBlendOp <span class="operator">=</span> VK_BLEND_OP_ADD; 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_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_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="keyword">if</span> (vertShaderModule) m_devFuncs<span class="operator">-</span><span class="operator">></span>vkDestroyShaderModule(dev<span class="operator">,</span> vertShaderModule<span class="operator">,</span> nullptr); <span class="keyword">if</span> (fragShaderModule) m_devFuncs<span class="operator">-</span><span class="operator">></span>vkDestroyShaderModule(dev<span class="operator">,</span> fragShaderModule<span class="operator">,</span> nullptr); } <span class="type">void</span> VulkanRenderer<span class="operator">::</span>initSwapChainResources() { <a href="../qtcore/qtglobal.html#qDebug">qDebug</a>(<span class="string">"initSwapChainResources"</span>); <span class="comment">// Projection matrix</span> m_proj <span class="operator">=</span> m_window<span class="operator">-</span><span class="operator">></span>clipCorrectionMatrix(); <span class="comment">// adjust for Vulkan-OpenGL clip space differences</span> <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">100.0f</span>); m_proj<span class="operator">.</span>translate(<span class="number">0</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="operator">-</span><span class="number">4</span>); } <span class="type">void</span> VulkanRenderer<span class="operator">::</span>releaseSwapChainResources() { <a href="../qtcore/qtglobal.html#qDebug">qDebug</a>(<span class="string">"releaseSwapChainResources"</span>); } <span class="type">void</span> VulkanRenderer<span class="operator">::</span>releaseResources() { <a href="../qtcore/qtglobal.html#qDebug">qDebug</a>(<span class="string">"releaseResources"</span>); VkDevice dev <span class="operator">=</span> m_window<span class="operator">-</span><span class="operator">></span>device(); <span class="keyword">if</span> (m_sampler) { m_devFuncs<span class="operator">-</span><span class="operator">></span>vkDestroySampler(dev<span class="operator">,</span> m_sampler<span class="operator">,</span> nullptr); m_sampler <span class="operator">=</span> VK_NULL_HANDLE; } <span class="keyword">if</span> (m_texStaging) { m_devFuncs<span class="operator">-</span><span class="operator">></span>vkDestroyImage(dev<span class="operator">,</span> m_texStaging<span class="operator">,</span> nullptr); m_texStaging <span class="operator">=</span> VK_NULL_HANDLE; } <span class="keyword">if</span> (m_texStagingMem) { m_devFuncs<span class="operator">-</span><span class="operator">></span>vkFreeMemory(dev<span class="operator">,</span> m_texStagingMem<span class="operator">,</span> nullptr); m_texStagingMem <span class="operator">=</span> VK_NULL_HANDLE; } <span class="keyword">if</span> (m_texView) { m_devFuncs<span class="operator">-</span><span class="operator">></span>vkDestroyImageView(dev<span class="operator">,</span> m_texView<span class="operator">,</span> nullptr); m_texView <span class="operator">=</span> VK_NULL_HANDLE; } <span class="keyword">if</span> (m_texImage) { m_devFuncs<span class="operator">-</span><span class="operator">></span>vkDestroyImage(dev<span class="operator">,</span> m_texImage<span class="operator">,</span> nullptr); m_texImage <span class="operator">=</span> VK_NULL_HANDLE; } <span class="keyword">if</span> (m_texMem) { m_devFuncs<span class="operator">-</span><span class="operator">></span>vkFreeMemory(dev<span class="operator">,</span> m_texMem<span class="operator">,</span> nullptr); m_texMem <span class="operator">=</span> VK_NULL_HANDLE; } <span class="keyword">if</span> (m_pipeline) { m_devFuncs<span class="operator">-</span><span class="operator">></span>vkDestroyPipeline(dev<span class="operator">,</span> m_pipeline<span class="operator">,</span> nullptr); m_pipeline <span class="operator">=</span> VK_NULL_HANDLE; } <span class="keyword">if</span> (m_pipelineLayout) { m_devFuncs<span class="operator">-</span><span class="operator">></span>vkDestroyPipelineLayout(dev<span class="operator">,</span> m_pipelineLayout<span class="operator">,</span> nullptr); m_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_descSetLayout) { m_devFuncs<span class="operator">-</span><span class="operator">></span>vkDestroyDescriptorSetLayout(dev<span class="operator">,</span> m_descSetLayout<span class="operator">,</span> nullptr); m_descSetLayout <span class="operator">=</span> VK_NULL_HANDLE; } <span class="keyword">if</span> (m_descPool) { m_devFuncs<span class="operator">-</span><span class="operator">></span>vkDestroyDescriptorPool(dev<span class="operator">,</span> m_descPool<span class="operator">,</span> nullptr); m_descPool <span class="operator">=</span> VK_NULL_HANDLE; } <span class="keyword">if</span> (m_buf) { m_devFuncs<span class="operator">-</span><span class="operator">></span>vkDestroyBuffer(dev<span class="operator">,</span> m_buf<span class="operator">,</span> nullptr); m_buf <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="type">void</span> VulkanRenderer<span class="operator">::</span>startNextFrame() { 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(); <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(); <span class="comment">// Add the necessary barriers and do the host-linear -> device-optimal copy, if not yet done.</span> ensureTexture(); VkClearColorValue clearColor <span class="operator">=</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> <span class="number">1</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">2</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> 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> <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); <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_uniformBufInfo<span class="operator">[</span>m_window<span class="operator">-</span><span class="operator">></span>currentFrame()<span class="operator">]</span><span class="operator">.</span>offset<span class="operator">,</span> UNIFORM_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); QMatrix4x4 m <span class="operator">=</span> m_proj; m<span class="operator">.</span>rotate(m_rotation<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="number">1</span>); memcpy(p<span class="operator">,</span> m<span class="operator">.</span>constData()<span class="operator">,</span> <span class="number">16</span> <span class="operator">*</span> <span class="keyword">sizeof</span>(<span class="type">float</span>)); m_devFuncs<span class="operator">-</span><span class="operator">></span>vkUnmapMemory(dev<span class="operator">,</span> m_bufMem); <span class="comment">// Not exactly a real animation system, just advance on every frame for now.</span> m_rotation <span class="operator">+</span><span class="operator">=</span> <span class="number">1.0f</span>; 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_pipeline); 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_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_descSet<span class="operator">[</span>m_window<span class="operator">-</span><span class="operator">></span>currentFrame()<span class="operator">]</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> nullptr); 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_buf<span class="operator">,</span> <span class="operator">&</span>vbOffset); VkViewport viewport; viewport<span class="operator">.</span>x <span class="operator">=</span> viewport<span class="operator">.</span>y <span class="operator">=</span> <span class="number">0</span>; viewport<span class="operator">.</span>width <span class="operator">=</span> sz<span class="operator">.</span>width(); viewport<span class="operator">.</span>height <span class="operator">=</span> sz<span class="operator">.</span>height(); viewport<span class="operator">.</span>minDepth <span class="operator">=</span> <span class="number">0</span>; viewport<span class="operator">.</span>maxDepth <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; scissor<span class="operator">.</span>offset<span class="operator">.</span>x <span class="operator">=</span> scissor<span class="operator">.</span>offset<span class="operator">.</span>y <span class="operator">=</span> <span class="number">0</span>; scissor<span class="operator">.</span>extent<span class="operator">.</span>width <span class="operator">=</span> viewport<span class="operator">.</span>width; scissor<span class="operator">.</span>extent<span class="operator">.</span>height <span class="operator">=</span> viewport<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); 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>); m_devFuncs<span class="operator">-</span><span class="operator">></span>vkCmdEndRenderPass(cmdBuf); m_window<span class="operator">-</span><span class="operator">></span>frameReady(); m_window<span class="operator">-</span><span class="operator">></span>requestUpdate(); <span class="comment">// render continuously, throttled by the presentation rate</span> } </pre> </div> <!-- @@@hellovulkantexture/hellovulkantexture.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>