Vulkan-Hpp
SharedHandles.cpp
Go to the documentation of this file.
1 // Copyright(c) 2023, Ilya Doroshenko. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 // VulkanHpp Samples : SharedHandles
16 // Draw a textured cube using shared handles for resource management and correct order of destruction
17 
18 #define VULKAN_HPP_SMART_HANDLE_IMPLICIT_CAST
19 
20 #include "../utils/geometries.hpp"
21 #include "../utils/math.hpp"
22 #include "../utils/shaders.hpp"
23 #include "../utils/utils.hpp"
24 #include "SPIRV/GlslangToSpv.h"
25 
26 #include <iostream>
27 #include <thread>
28 #include <vulkan/vulkan_shared.hpp>
29 
30 static char const * AppName = "SharedHandles";
31 static char const * EngineName = "Vulkan.hpp";
32 
33 std::vector<vk::SharedFramebuffer> makeSharedFramebuffers( const vk::SharedDevice & device,
34  const vk::SharedRenderPass & renderPass,
35  const std::vector<vk::ImageView> & imageViews,
36  const vk::SharedImageView & depthImageView,
37  const vk::Extent2D & extent )
38 {
39  // show the simplified usage with VULKAN_HPP_SMART_HANDLE_IMPLICIT_CAST defined
40 #if defined( VULKAN_HPP_SMART_HANDLE_IMPLICIT_CAST )
41  auto renderPassHandle = renderPass.get(); // lvalue reference is required for the capture below
42  std::vector<vk::SharedFramebuffer> sharedFramebuffers;
43  std::vector<vk::Framebuffer> framebuffers = vk::su::createFramebuffers( device, renderPassHandle, imageViews, depthImageView, extent );
44 #else
45  auto renderPassHandle = renderPass.get(); // lvalue reference is required for the capture below
46  std::vector<vk::SharedFramebuffer> sharedFramebuffers;
47  std::vector<vk::Framebuffer> framebuffers = vk::su::createFramebuffers( device.get(), renderPassHandle, imageViews, depthImageView.get(), extent );
48 #endif
49  sharedFramebuffers.reserve( framebuffers.size() );
50  for ( auto & framebuffer : framebuffers )
51  {
52  sharedFramebuffers.emplace_back( framebuffer, device );
53  }
54 
55  return sharedFramebuffers;
56 }
57 
58 class Window
59 {
60 public:
61  Window( const char * windowName, vk::Extent2D extent ) : window( vk::su::createWindow( windowName, extent ) ) {}
62 
63 public:
65 };
66 
67 class Engine
68 {
69 public:
70  Engine( const vk::su::WindowData & window )
71  {
72  instance = vk::SharedInstance{ vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() ) };
73 #if !defined( NDEBUG )
75  vk::SharedDebugUtilsMessengerEXT{ instance->createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() ), instance };
76 #endif
77  physicalDevice = instance->enumeratePhysicalDevices().front();
78 
79  createDeviceAndSwapChain( window );
80  initialize();
81  }
82 
84  {
85  VkSurfaceKHR surface;
86  VkResult err = glfwCreateWindowSurface( static_cast<VkInstance>( instance.get() ), window.handle, nullptr, &surface );
87  if ( err != VK_SUCCESS )
88  throw std::runtime_error( "Failed to create window!" );
89  vk::SharedSurfaceKHR sharedSurface{ surface, instance };
90 
91  auto graphicsAndPresentQueueFamilyIndex = vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, sharedSurface.get() );
92  device = vk::SharedDevice{ vk::su::createDevice( physicalDevice, graphicsAndPresentQueueFamilyIndex.first, vk::su::getDeviceExtensions() ) };
93 
95  device.get(),
96  sharedSurface.get(),
97  window.extent,
99  {},
100  graphicsAndPresentQueueFamilyIndex.first,
101  graphicsAndPresentQueueFamilyIndex.second );
102  swapChain = vk::SharedSwapchainKHR{ swapChainData.swapChain, device, sharedSurface };
103 
104  imageViews.reserve( swapChainData.images.size() );
105  images.reserve( swapChainData.images.size() );
106 
107  // we don't want to destroy the images, since they are owned by the swapchain,
108  // but for the consistent representation we might want shared textures
109  std::transform( swapChainData.images.begin(),
110  swapChainData.images.end(),
111  std::back_inserter( images ),
112  [this]( vk::Image image ) {
113  return vk::SharedImage{ image, device, vk::SwapchainOwns::yes };
114  } );
115 
116  std::transform( swapChainData.imageViews.begin(),
117  swapChainData.imageViews.end(),
118  std::back_inserter( imageViews ),
119  [this]( vk::ImageView imageView ) {
120  return vk::SharedImageView{ imageView, device };
121  } );
122  commandPool =
123  vk::SharedCommandPool{ device->createCommandPool( { vk::CommandPoolCreateFlagBits::eResetCommandBuffer, graphicsAndPresentQueueFamilyIndex.first } ),
124  device };
125  graphicsQueue = vk::SharedQueue{ device->getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 ), device };
126 
127  presentQueue = vk::SharedQueue{ device->getQueue( graphicsAndPresentQueueFamilyIndex.second, 0 ), device };
128 
129  depthFormat = vk::Format::eD16Unorm;
130  vk::su::DepthBufferData depthBufferData( physicalDevice, device.get(), depthFormat, window.extent );
131  depthImage = vk::SharedImage{ depthBufferData.image, device };
132  depthImageView = vk::SharedImageView{ depthBufferData.imageView, device };
133  depthMemory = vk::SharedDeviceMemory{ depthBufferData.deviceMemory, device };
134 
135  renderPass =
136  vk::SharedRenderPass{ vk::su::createRenderPass( device.get(),
137  vk::su::pickSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( swapChain.getSurface().get() ) ).format,
138  depthFormat ),
139  device };
140 
141  framebuffers = makeSharedFramebuffers( device, renderPass, swapChainData.imageViews, depthImageView, window.extent );
142  imageAcquiredSemaphore = vk::SharedSemaphore{ device->createSemaphore( vk::SemaphoreCreateInfo() ), device };
143  drawFence = vk::SharedFence{ device->createFence( vk::FenceCreateInfo() ), device };
144  // We don't need to explicitly keep sharedSurface anymore, it is owned by swapChain now.
145  }
146 
147  void initialize()
148  {
149  commandBuffer = vk::SharedCommandBuffer{
150  device->allocateCommandBuffers( vk::CommandBufferAllocateInfo( commandPool.get(), vk::CommandBufferLevel::ePrimary, 1 ) ).front(), device, commandPool
151  };
152 
153  auto device_handle = device.get();
154  descriptorSetLayout = vk::SharedDescriptorSetLayout{ vk::su::createDescriptorSetLayout(
155  device_handle,
158  device };
159 
160  auto dsl = descriptorSetLayout.get();
161 
162  pipelineLayout = vk::SharedPipelineLayout{ device->createPipelineLayout( vk::PipelineLayoutCreateInfo( vk::PipelineLayoutCreateFlags(), dsl ) ), device };
163 
164  glslang::InitializeProcess();
165  vertexShaderModule = vk::SharedShaderModule{ vk::su::createShaderModule( device_handle, vk::ShaderStageFlagBits::eVertex, vertexShaderText_PT_T ), device };
166  fragmentShaderModule =
167  vk::SharedShaderModule{ vk::su::createShaderModule( device_handle, vk::ShaderStageFlagBits::eFragment, fragmentShaderText_T_C ), device };
168  glslang::FinalizeProcess();
169 
170  descriptorPool = vk::SharedDescriptorPool{
172  };
173 
174  descriptorSetAllocateInfo = vk::DescriptorSetAllocateInfo( descriptorPool.get(), dsl );
175  descriptorSet = vk::SharedDescriptorSet{ device->allocateDescriptorSets( descriptorSetAllocateInfo ).front(), device, descriptorPool };
176 
177  pipelineCache = vk::SharedPipelineCache{ device->createPipelineCache( vk::PipelineCacheCreateInfo() ), device };
178  graphicsPipeline = vk::SharedPipeline{ vk::su::createGraphicsPipeline( device_handle,
179  pipelineCache.get(),
180  std::make_pair( vertexShaderModule.get(), nullptr ),
181  std::make_pair( fragmentShaderModule.get(), nullptr ),
182  sizeof( texturedCubeData[0] ),
183  { { vk::Format::eR32G32B32A32Sfloat, 0 }, { vk::Format::eR32G32Sfloat, 16 } },
185  true,
186  pipelineLayout.get(),
187  renderPass.get() ),
188  device };
189 
190  // Get the index of the next available swapchain image:
191  vk::ResultValue<uint32_t> currentBufferR = device->acquireNextImageKHR( swapChain.get(), vk::su::FenceTimeout, imageAcquiredSemaphore.get(), nullptr );
192  assert( currentBufferR.result == vk::Result::eSuccess );
193  assert( currentBufferR.value < framebuffers.size() );
194  currentBuffer = currentBufferR.value;
195  }
196 
197  void beginFrame( vk::Extent2D extent )
198  {
199  std::array<vk::ClearValue, 2> clearValues;
200  clearValues[0].color = vk::ClearColorValue( 0.2f, 0.2f, 0.2f, 0.2f );
201  clearValues[1].depthStencil = vk::ClearDepthStencilValue( 1.0f, 0 );
202  vk::RenderPassBeginInfo renderPassBeginInfo( renderPass.get(), framebuffers[currentBuffer].get(), vk::Rect2D( vk::Offset2D( 0, 0 ), extent ), clearValues );
203 
204  commandBuffer->begin( vk::CommandBufferBeginInfo() );
205  commandBuffer->beginRenderPass( renderPassBeginInfo, vk::SubpassContents::eInline );
206  commandBuffer->bindPipeline( vk::PipelineBindPoint::eGraphics, graphicsPipeline.get() );
207  commandBuffer->bindDescriptorSets( vk::PipelineBindPoint::eGraphics, pipelineLayout.get(), 0, descriptorSet.get(), nullptr );
208 
209  commandBuffer->setViewport( 0, vk::Viewport( 0.0f, 0.0f, static_cast<float>( extent.width ), static_cast<float>( extent.height ), 0.0f, 1.0f ) );
210  commandBuffer->setScissor( 0, vk::Rect2D( vk::Offset2D( 0, 0 ), extent ) );
211  }
212 
213  void endFrame()
214  {
215  commandBuffer->endRenderPass();
216  commandBuffer->end();
217 
219 
220  auto ias = imageAcquiredSemaphore.get();
221  auto comBuf = commandBuffer.get();
222 
223  vk::SubmitInfo submitInfo( ias, waitDestinationStageMask, comBuf );
224  graphicsQueue->submit( submitInfo, drawFence.get() );
225 
226  while ( vk::Result::eTimeout == device->waitForFences( drawFence.get(), VK_TRUE, vk::su::FenceTimeout ) )
227  ;
228 
229  auto swap = swapChain.get();
230  vk::Result result = presentQueue->presentKHR( vk::PresentInfoKHR( {}, swap, currentBuffer ) );
231  switch ( result )
232  {
233  case vk::Result::eSuccess: break;
234  case vk::Result::eSuboptimalKHR: std::cout << "vk::Queue::presentKHR returned vk::Result::eSuboptimalKHR !\n"; break;
235  default: assert( false ); // an unexpected result is returned !
236  }
237  std::this_thread::sleep_for( std::chrono::milliseconds( 1000 ) );
238 
239  /* VULKAN_KEY_END */
240  device->waitIdle();
241  }
242 
243 public:
244  vk::SharedSwapchainKHR swapChain; // swapchain owns surface, that owns Instance, which should be destroyed last
245  vk::PhysicalDevice physicalDevice; // physical device does not have a shared handle since it is not destroyed
246  vk::SharedDevice device;
247  vk::SharedInstance instance; // we don't need to keep the instance, this is just for convenience
248  vk::SharedDebugUtilsMessengerEXT debugUtilsMessenger;
249 
250  std::vector<vk::SharedImageView> imageViews;
251  std::vector<vk::SharedImage> images;
252 
253  uint32_t currentBuffer = 0;
254  vk::SharedSemaphore imageAcquiredSemaphore;
255 
256  // memory still needs to be before the resources that use it in order to get a proper destruction sequence.
257  vk::SharedDeviceMemory depthMemory;
258  vk::SharedImage depthImage;
259  vk::SharedImageView depthImageView;
261 
262  vk::SharedCommandPool commandPool;
263  vk::SharedCommandBuffer commandBuffer;
264 
265  vk::SharedQueue graphicsQueue; // queue is not destroyed, shared handle is purely for consistency
266  vk::SharedQueue presentQueue;
267 
268  vk::SharedPipelineCache pipelineCache;
269  vk::SharedPipelineLayout pipelineLayout;
270  vk::SharedRenderPass renderPass;
271  vk::SharedPipeline graphicsPipeline;
272  vk::SharedDescriptorPool descriptorPool;
274  vk::SharedDescriptorSet descriptorSet;
275  vk::SharedDescriptorSetLayout descriptorSetLayout;
276 
277  vk::SharedShaderModule vertexShaderModule;
278  vk::SharedShaderModule fragmentShaderModule;
279 
280  std::vector<vk::SharedFramebuffer> framebuffers;
281 
282  vk::SharedFence drawFence;
283 };
284 
285 class Asset
286 {
287 public:
288  Asset( const Engine & engine, vk::Extent2D extent )
289  {
290  auto device_handle = engine.device.get();
291  vk::su::BufferData vertexBufferData( engine.physicalDevice, device_handle, sizeof( texturedCubeData ), vk::BufferUsageFlagBits::eVertexBuffer );
292  vk::su::copyToDevice( device_handle, vertexBufferData.deviceMemory, texturedCubeData, sizeof( texturedCubeData ) / sizeof( texturedCubeData[0] ) );
293 
294  vertexBuffer = vk::SharedBuffer{ vertexBufferData.buffer, engine.device };
295  vertexBufferMemory = vk::SharedDeviceMemory{ vertexBufferData.deviceMemory, engine.device };
296 
297  engine.commandBuffer->begin( vk::CommandBufferBeginInfo() );
298 
299  vk::su::BufferData uniformBufferData( engine.physicalDevice, device_handle, sizeof( glm::mat4x4 ), vk::BufferUsageFlagBits::eUniformBuffer );
300  glm::mat4x4 mvpcMatrix = vk::su::createModelViewProjectionClipMatrix( extent );
301  vk::su::copyToDevice( device_handle, uniformBufferData.deviceMemory, mvpcMatrix );
302 
303  uniformBufferMemory = vk::SharedDeviceMemory{ uniformBufferData.deviceMemory, engine.device };
304  uniformBuffer = vk::SharedBuffer{ uniformBufferData.buffer, engine.device };
305 
306  vk::su::TextureData textureData( engine.physicalDevice, device_handle );
307  textureData.setImage( device_handle, engine.commandBuffer.get(), vk::su::CheckerboardImageGenerator() );
308 
309  textureImage = vk::SharedImage{ textureData.imageData->image, engine.device };
310  textureImageMemory = vk::SharedDeviceMemory{ textureData.imageData->deviceMemory, engine.device };
311  textureImageView = vk::SharedImageView{ textureData.imageData->imageView, engine.device };
312  textureSampler = vk::SharedSampler{ textureData.sampler, engine.device };
313 
315  device_handle, engine.descriptorSet.get(), { { vk::DescriptorType::eUniformBuffer, uniformBufferData.buffer, VK_WHOLE_SIZE, {} } }, textureData );
316  engine.commandBuffer->end();
317 
318  vk::su::submitAndWait( device_handle, engine.graphicsQueue.get(), engine.commandBuffer.get() );
319  }
320 
321  void draw( vk::CommandBuffer commandBuffer )
322  {
323  commandBuffer.bindVertexBuffers( 0, vertexBuffer.get(), { 0 } );
324  commandBuffer.draw( 12 * 3, 1, 0, 0 );
325  }
326 
327  vk::SharedDeviceMemory vertexBufferMemory;
328  vk::SharedBuffer vertexBuffer;
329 
330  vk::SharedDeviceMemory uniformBufferMemory;
331  vk::SharedBuffer uniformBuffer;
332 
333  vk::SharedDeviceMemory textureImageMemory;
334  vk::SharedImage textureImage;
335  vk::SharedImageView textureImageView;
336  vk::SharedSampler textureSampler;
337 };
338 
340 {
341 public:
342  Application() : window( AppName, vk::Extent2D( 500, 500 ) ), engine( window.window ), asset( engine, vk::Extent2D( 500, 500 ) ) {}
343 
344  void renderFrame()
345  {
346  engine.beginFrame( vk::Extent2D( 500, 500 ) );
347  asset.draw( engine.commandBuffer.get() );
348  engine.endFrame();
349  }
350 
351  int start()
352  {
353  renderFrame();
354  return 0;
355  }
356 
357 private:
358  // order of window, engine and asset variables is important !
359  Window window;
360  Engine engine;
361  Asset asset;
362 };
363 
364 int main( int /*argc*/, char ** /*argv*/ )
365 {
366  try
367  {
368  return Application{}.start();
369  }
370  catch ( vk::SystemError & err )
371  {
372  std::cout << "vk::SystemError: " << err.what() << std::endl;
373  exit( -1 );
374  }
375  catch ( std::exception & err )
376  {
377  std::cout << "std::exception: " << err.what() << std::endl;
378  exit( -1 );
379  }
380  catch ( ... )
381  {
382  std::cout << "unknown error\n";
383  exit( -1 );
384  }
385 }
std::vector< vk::SharedFramebuffer > makeSharedFramebuffers(const vk::SharedDevice &device, const vk::SharedRenderPass &renderPass, const std::vector< vk::ImageView > &imageViews, const vk::SharedImageView &depthImageView, const vk::Extent2D &extent)
int main(int, char **)
void cout(vk::SurfaceCapabilitiesKHR const &surfaceCapabilities)
void renderFrame()
vk::SharedDeviceMemory uniformBufferMemory
vk::SharedImage textureImage
vk::SharedSampler textureSampler
vk::SharedImageView textureImageView
vk::SharedDeviceMemory textureImageMemory
vk::SharedBuffer uniformBuffer
void draw(vk::CommandBuffer commandBuffer)
Asset(const Engine &engine, vk::Extent2D extent)
vk::SharedBuffer vertexBuffer
vk::SharedDeviceMemory vertexBufferMemory
void endFrame()
vk::SharedDescriptorPool descriptorPool
vk::SharedInstance instance
vk::DescriptorSetAllocateInfo descriptorSetAllocateInfo
vk::SharedCommandPool commandPool
std::vector< vk::SharedImage > images
vk::SharedDescriptorSetLayout descriptorSetLayout
vk::PhysicalDevice physicalDevice
vk::SharedRenderPass renderPass
vk::SharedSemaphore imageAcquiredSemaphore
vk::SharedQueue presentQueue
vk::SharedImageView depthImageView
vk::SharedQueue graphicsQueue
void initialize()
Engine(const vk::su::WindowData &window)
vk::Format depthFormat
std::vector< vk::SharedFramebuffer > framebuffers
void createDeviceAndSwapChain(const vk::su::WindowData &window)
vk::SharedDeviceMemory depthMemory
vk::SharedPipelineCache pipelineCache
vk::SharedSwapchainKHR swapChain
vk::SharedPipeline graphicsPipeline
void beginFrame(vk::Extent2D extent)
vk::SharedPipelineLayout pipelineLayout
vk::SharedDescriptorSet descriptorSet
vk::SharedFence drawFence
vk::SharedDevice device
vk::SharedCommandBuffer commandBuffer
vk::SharedDebugUtilsMessengerEXT debugUtilsMessenger
vk::SharedShaderModule fragmentShaderModule
std::vector< vk::SharedImageView > imageViews
vk::SharedShaderModule vertexShaderModule
vk::SharedImage depthImage
Window(const char *windowName, vk::Extent2D extent)
vk::su::WindowData window
void draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
void bindVertexBuffers(uint32_t firstBinding, uint32_t bindingCount, const vk::Buffer *pBuffers, const vk::DeviceSize *pOffsets, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
virtual const char * what() const VULKAN_HPP_NOEXCEPT
Definition: vulkan.hpp:6206
std::vector< vk::Framebuffer > createFramebuffers(vk::Device const &device, vk::RenderPass &renderPass, std::vector< vk::ImageView > const &imageViews, vk::ImageView const &depthImageView, vk::Extent2D const &extent)
Definition: utils.cpp:111
vk::DebugUtilsMessengerCreateInfoEXT makeDebugUtilsMessengerCreateInfoEXT()
Definition: utils.cpp:1025
void copyToDevice(vk::Device const &device, vk::DeviceMemory const &deviceMemory, T const *pData, size_t count, vk::DeviceSize stride=sizeof(T))
Definition: utils.hpp:46
vk::ShaderModule createShaderModule(vk::Device const &device, vk::ShaderStageFlagBits shaderStage, std::string const &shaderText)
Definition: shaders.cpp:88
vk::RenderPass createRenderPass(vk::Device const &device, vk::Format colorFormat, vk::Format depthFormat, vk::AttachmentLoadOp loadOp, vk::ImageLayout colorFinalLayout)
Definition: utils.cpp:314
vk::Pipeline createGraphicsPipeline(vk::Device const &device, vk::PipelineCache const &pipelineCache, std::pair< vk::ShaderModule, vk::SpecializationInfo const * > const &vertexShaderData, std::pair< vk::ShaderModule, vk::SpecializationInfo const * > const &fragmentShaderData, uint32_t vertexStride, std::vector< std::pair< vk::Format, uint32_t >> const &vertexInputAttributeFormatOffset, vk::FrontFace frontFace, bool depthBuffered, vk::PipelineLayout const &pipelineLayout, vk::RenderPass const &renderPass)
Definition: utils.cpp:133
vk::Instance createInstance(std::string const &appName, std::string const &engineName, std::vector< std::string > const &layers, std::vector< std::string > const &extensions, uint32_t apiVersion)
Definition: utils.cpp:279
const uint64_t FenceTimeout
Definition: utils.hpp:31
vk::Device createDevice(vk::PhysicalDevice const &physicalDevice, uint32_t queueFamilyIndex, std::vector< std::string > const &extensions, vk::PhysicalDeviceFeatures const *physicalDeviceFeatures, void const *pNext)
Definition: utils.cpp:86
vk::DescriptorSetLayout createDescriptorSetLayout(vk::Device const &device, std::vector< std::tuple< vk::DescriptorType, uint32_t, vk::ShaderStageFlags >> const &bindingData, vk::DescriptorSetLayoutCreateFlags flags)
Definition: utils.cpp:73
WindowData createWindow(std::string const &windowName, vk::Extent2D const &extent)
Definition: utils.cpp:996
std::pair< uint32_t, uint32_t > findGraphicsAndPresentQueueFamilyIndex(vk::PhysicalDevice physicalDevice, vk::SurfaceKHR const &surface)
Definition: utils.cpp:420
void submitAndWait(vk::Device const &device, vk::Queue const &queue, vk::CommandBuffer const &commandBuffer)
Definition: utils.cpp:651
std::vector< std::string > getInstanceExtensions()
Definition: utils.cpp:477
void updateDescriptorSets(vk::Device const &device, vk::DescriptorSet const &descriptorSet, std::vector< std::tuple< vk::DescriptorType, vk::Buffer const &, vk::DeviceSize, vk::BufferView const & >> const &bufferData, vk::su::TextureData const &textureData, uint32_t bindingOffset)
Definition: utils.cpp:660
glm::mat4x4 createModelViewProjectionClipMatrix(vk::Extent2D const &extent)
Definition: math.cpp:31
vk::DescriptorPool createDescriptorPool(vk::Device const &device, std::vector< vk::DescriptorPoolSize > const &poolSizes)
Definition: utils.cpp:62
vk::SurfaceFormatKHR pickSurfaceFormat(std::vector< vk::SurfaceFormatKHR > const &formats)
Definition: utils.cpp:539
std::vector< std::string > getDeviceExtensions()
Definition: utils.cpp:472
Definition: vulkan.cppm:23
VULKAN_HPP_INLINE void swap(UniqueHandle< Type, Dispatch > &lhs, UniqueHandle< Type, Dispatch > &rhs) VULKAN_HPP_NOEXCEPT
Definition: vulkan.hpp:997
const std::string fragmentShaderText_T_C
Definition: shaders.hpp:96
const std::string vertexShaderText_PT_T
Definition: shaders.hpp:55
vk::DeviceMemory deviceMemory
Definition: utils.hpp:160
vk::Buffer buffer
Definition: utils.hpp:159
vk::SwapchainKHR swapChain
Definition: utils.hpp:231
std::vector< vk::Image > images
Definition: utils.hpp:232
void setImage(vk::Device const &device, vk::CommandBuffer const &commandBuffer, ImageGenerator const &imageGenerator)
Definition: utils.hpp:293
vk::Sampler sampler
Definition: utils.hpp:329
std::unique_ptr< ImageData > imageData
Definition: utils.hpp:328
GLFWwindow * handle
Definition: utils.hpp:87
vk::Extent2D extent
Definition: utils.hpp:89
uint64_t VkSurfaceKHR
Definition: vulkan_core.h:7513
#define VK_TRUE
Definition: vulkan_core.h:131
struct VkInstance_T * VkInstance
Definition: vulkan_core.h:101
VkResult
Definition: vulkan_core.h:140
@ VK_SUCCESS
Definition: vulkan_core.h:141