Vulkan-Hpp
InitTexture.cpp
Go to the documentation of this file.
1 // Copyright(c) 2019, NVIDIA CORPORATION. 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 : InitTexture
16 // Initialize texture
17 
18 #if defined( _MSC_VER )
19 // no need to ignore any warnings with MSVC
20 #elif defined( __clang__ )
21 # pragma clang diagnostic ignored "-Wunused-variable"
22 #elif defined( __GNUC__ )
23 # pragma GCC diagnostic ignored "-Wunused-but-set-variable"
24 #else
25 // unknow compiler... just ignore the warnings for yourselves ;)
26 #endif
27 
28 #include "../utils/geometries.hpp"
29 #include "../utils/math.hpp"
30 #include "../utils/shaders.hpp"
31 #include "../utils/utils.hpp"
32 #include "SPIRV/GlslangToSpv.h"
33 
34 #include <iostream>
35 
36 static char const * AppName = "InitTexture";
37 static char const * EngineName = "Vulkan.hpp";
38 
39 int main( int /*argc*/, char ** /*argv*/ )
40 {
41  try
42  {
43  vk::Instance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
44 #if !defined( NDEBUG )
46 #endif
47 
48  vk::PhysicalDevice physicalDevice = instance.enumeratePhysicalDevices().front();
49 
50  vk::su::SurfaceData surfaceData( instance, AppName, vk::Extent2D( 50, 50 ) );
51 
52  std::pair<uint32_t, uint32_t> graphicsAndPresentQueueFamilyIndex = vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, surfaceData.surface );
53  vk::Device device = vk::su::createDevice( physicalDevice, graphicsAndPresentQueueFamilyIndex.first, vk::su::getDeviceExtensions() );
54 
55  vk::CommandPool commandPool = device.createCommandPool( { {}, graphicsAndPresentQueueFamilyIndex.first } );
56  vk::CommandBuffer commandBuffer =
58 
59  vk::Queue graphicsQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
60  vk::Queue presentQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.second, 0 );
61 
62  /* VULKAN_KEY_START */
63 
65  vk::FormatProperties formatProperties = physicalDevice.getFormatProperties( format );
66 
67  // See if we can use a linear tiled image for a texture, if not, we will need a staging buffer for the texture data
68  bool needsStaging = !( formatProperties.linearTilingFeatures & vk::FormatFeatureFlagBits::eSampledImage );
69 
70  vk::ImageCreateInfo imageCreateInfo( vk::ImageCreateFlags(),
72  format,
73  vk::Extent3D( surfaceData.extent, 1 ),
74  1,
75  1,
80  {},
82  vk::Image image = device.createImage( imageCreateInfo );
83 
84  vk::MemoryRequirements memoryRequirements = device.getImageMemoryRequirements( image );
85  uint32_t memoryTypeIndex = vk::su::findMemoryType(
86  physicalDevice.getMemoryProperties(),
87  memoryRequirements.memoryTypeBits,
89 
90  // allocate memory
91  vk::DeviceMemory imageMemory = device.allocateMemory( vk::MemoryAllocateInfo( memoryRequirements.size, memoryTypeIndex ) );
92 
93  // bind memory
94  device.bindImageMemory( image, imageMemory, 0 );
95 
96  vk::Buffer textureBuffer;
97  vk::DeviceMemory textureBufferMemory;
98  if ( needsStaging )
99  {
100  // Need a staging buffer to map and copy texture into
101  textureBuffer = device.createBuffer(
103 
104  memoryRequirements = device.getBufferMemoryRequirements( textureBuffer );
105  memoryTypeIndex = vk::su::findMemoryType( physicalDevice.getMemoryProperties(),
106  memoryRequirements.memoryTypeBits,
108 
109  // allocate memory
110  textureBufferMemory = device.allocateMemory( vk::MemoryAllocateInfo( memoryRequirements.size, memoryTypeIndex ) );
111 
112  // bind memory
113  device.bindBufferMemory( textureBuffer, textureBufferMemory, 0 );
114  }
115  else
116  {
118  }
119 
120  void * data = device.mapMemory( needsStaging ? textureBufferMemory : imageMemory, 0, memoryRequirements.size, vk::MemoryMapFlags() );
121 
122  // Checkerboard of 16x16 pixel squares
123  unsigned char * pImageMemory = static_cast<unsigned char *>( data );
124  for ( uint32_t row = 0; row < surfaceData.extent.height; row++ )
125  {
126  for ( uint32_t col = 0; col < surfaceData.extent.width; col++ )
127  {
128  unsigned char rgb = ( ( ( row & 0x10 ) == 0 ) ^ ( ( col & 0x10 ) == 0 ) ) * 255;
129  pImageMemory[0] = rgb;
130  pImageMemory[1] = rgb;
131  pImageMemory[2] = rgb;
132  pImageMemory[3] = 255;
133  pImageMemory += 4;
134  }
135  }
136 
137  device.unmapMemory( needsStaging ? textureBufferMemory : imageMemory );
138 
139  commandBuffer.begin( vk::CommandBufferBeginInfo() );
140  if ( needsStaging )
141  {
142  // Since we're going to blit to the texture image, set its layout to eTransferDstOptimal
144  vk::BufferImageCopy copyRegion( 0,
145  surfaceData.extent.width,
146  surfaceData.extent.height,
148  vk::Offset3D( 0, 0, 0 ),
149  vk::Extent3D( surfaceData.extent, 1 ) );
150  commandBuffer.copyBufferToImage( textureBuffer, image, vk::ImageLayout::eTransferDstOptimal, copyRegion );
151  // Set the layout for the texture image from eTransferDstOptimal to SHADER_READ_ONLY
153  }
154  else
155  {
156  // If we can use the linear tiled image as a texture, just do it
158  }
159 
160  commandBuffer.end();
161  vk::su::submitAndWait( device, graphicsQueue, commandBuffer );
162 
163  vk::SamplerCreateInfo samplerCreateInfo( vk::SamplerCreateFlags(),
170  0.0f,
171  false,
172  1.0f,
173  false,
175  0.0f,
176  0.0f,
178  vk::Sampler sampler = device.createSampler( samplerCreateInfo );
179 
180  vk::ImageViewCreateInfo imageViewCreateInfo( {}, image, vk::ImageViewType::e2D, format, {}, { vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 } );
181  vk::ImageView imageView = device.createImageView( imageViewCreateInfo );
182 
183  /* VULKAN_KEY_END */
184 
185  device.destroyImageView( imageView );
186  device.destroySampler( sampler );
187  device.freeMemory( textureBufferMemory );
188  device.destroyBuffer( textureBuffer );
189  device.destroyImage( image ); // destroy the image before the bound device memory to prevent some validation layer warning
190  device.freeMemory( imageMemory );
191  device.freeCommandBuffers( commandPool, commandBuffer );
192  device.destroyCommandPool( commandPool );
193  device.destroy();
194  instance.destroySurfaceKHR( surfaceData.surface );
195 #if !defined( NDEBUG )
196  instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
197 #endif
198  instance.destroy();
199  }
200  catch ( vk::SystemError & err )
201  {
202  std::cout << "vk::SystemError: " << err.what() << std::endl;
203  exit( -1 );
204  }
205  catch ( std::exception & err )
206  {
207  std::cout << "std::exception: " << err.what() << std::endl;
208  exit( -1 );
209  }
210  catch ( ... )
211  {
212  std::cout << "unknown error\n";
213  exit( -1 );
214  }
215  return 0;
216 }
int main(int, char **)
Definition: InitTexture.cpp:39
void cout(vk::SurfaceCapabilitiesKHR const &surfaceCapabilities)
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS ResultValueType< void >::type end(Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const
void copyBufferToImage(vk::Buffer srcBuffer, vk::Image dstImage, vk::ImageLayout dstImageLayout, uint32_t regionCount, const vk::BufferImageCopy *pRegions, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
VULKAN_HPP_NODISCARD Result begin(const vk::CommandBufferBeginInfo *pBeginInfo, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
void getImageMemoryRequirements(vk::Image image, vk::MemoryRequirements *pMemoryRequirements, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
VULKAN_HPP_NODISCARD Result allocateMemory(const vk::MemoryAllocateInfo *pAllocateInfo, const vk::AllocationCallbacks *pAllocator, vk::DeviceMemory *pMemory, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
void destroy(const vk::AllocationCallbacks *pAllocator, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
void unmapMemory(vk::DeviceMemory memory, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
void freeCommandBuffers(vk::CommandPool commandPool, uint32_t commandBufferCount, const vk::CommandBuffer *pCommandBuffers, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
void destroyImageView(vk::ImageView imageView, const vk::AllocationCallbacks *pAllocator, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
void destroyCommandPool(vk::CommandPool commandPool, const vk::AllocationCallbacks *pAllocator, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
VULKAN_HPP_NODISCARD Result mapMemory(vk::DeviceMemory memory, vk::DeviceSize offset, vk::DeviceSize size, vk::MemoryMapFlags flags, void **ppData, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
VULKAN_HPP_NODISCARD Result createImageView(const vk::ImageViewCreateInfo *pCreateInfo, const vk::AllocationCallbacks *pAllocator, vk::ImageView *pView, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS ResultValueType< void >::type bindBufferMemory(vk::Buffer buffer, vk::DeviceMemory memory, vk::DeviceSize memoryOffset, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const
void destroySampler(vk::Sampler sampler, const vk::AllocationCallbacks *pAllocator, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS ResultValueType< void >::type bindImageMemory(vk::Image image, vk::DeviceMemory memory, vk::DeviceSize memoryOffset, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const
void freeMemory(vk::DeviceMemory memory, const vk::AllocationCallbacks *pAllocator, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
void destroyBuffer(vk::Buffer buffer, const vk::AllocationCallbacks *pAllocator, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
VULKAN_HPP_NODISCARD Result createSampler(const vk::SamplerCreateInfo *pCreateInfo, const vk::AllocationCallbacks *pAllocator, vk::Sampler *pSampler, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
VULKAN_HPP_NODISCARD Result createImage(const vk::ImageCreateInfo *pCreateInfo, const vk::AllocationCallbacks *pAllocator, vk::Image *pImage, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
void getImageSubresourceLayout(vk::Image image, const vk::ImageSubresource *pSubresource, vk::SubresourceLayout *pLayout, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
VULKAN_HPP_NODISCARD Result createBuffer(const vk::BufferCreateInfo *pCreateInfo, const vk::AllocationCallbacks *pAllocator, vk::Buffer *pBuffer, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
VULKAN_HPP_NODISCARD Result createCommandPool(const vk::CommandPoolCreateInfo *pCreateInfo, const vk::AllocationCallbacks *pAllocator, vk::CommandPool *pCommandPool, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
void destroyImage(vk::Image image, const vk::AllocationCallbacks *pAllocator, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
void getQueue(uint32_t queueFamilyIndex, uint32_t queueIndex, vk::Queue *pQueue, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
VULKAN_HPP_NODISCARD Result allocateCommandBuffers(const vk::CommandBufferAllocateInfo *pAllocateInfo, vk::CommandBuffer *pCommandBuffers, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
void getBufferMemoryRequirements(vk::Buffer buffer, vk::MemoryRequirements *pMemoryRequirements, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
VULKAN_HPP_NODISCARD Result createDebugUtilsMessengerEXT(const vk::DebugUtilsMessengerCreateInfoEXT *pCreateInfo, const vk::AllocationCallbacks *pAllocator, vk::DebugUtilsMessengerEXT *pMessenger, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
void destroy(const vk::AllocationCallbacks *pAllocator, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
VULKAN_HPP_NODISCARD Result enumeratePhysicalDevices(uint32_t *pPhysicalDeviceCount, vk::PhysicalDevice *pPhysicalDevices, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
void destroySurfaceKHR(vk::SurfaceKHR surface, const vk::AllocationCallbacks *pAllocator, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
void destroyDebugUtilsMessengerEXT(vk::DebugUtilsMessengerEXT messenger, const vk::AllocationCallbacks *pAllocator, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
void getFormatProperties(vk::Format format, vk::FormatProperties *pFormatProperties, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
void getMemoryProperties(vk::PhysicalDeviceMemoryProperties *pMemoryProperties, Dispatch const &d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) const VULKAN_HPP_NOEXCEPT
virtual const char * what() const VULKAN_HPP_NOEXCEPT
Definition: vulkan.hpp:6206
vk::DebugUtilsMessengerCreateInfoEXT makeDebugUtilsMessengerCreateInfoEXT()
Definition: utils.cpp:1025
uint32_t findMemoryType(vk::PhysicalDeviceMemoryProperties const &memoryProperties, uint32_t typeBits, vk::MemoryPropertyFlags requirementsMask)
Definition: utils.cpp:456
void setImageLayout(vk::CommandBuffer const &commandBuffer, vk::Image image, vk::Format format, vk::ImageLayout oldImageLayout, vk::ImageLayout newImageLayout)
Definition: utils.cpp:574
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
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
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
std::vector< std::string > getDeviceExtensions()
Definition: utils.cpp:472
ImageUsageFlagBits
vk::FormatFeatureFlags linearTilingFeatures
vk::Extent2D extent
Definition: utils.hpp:203
vk::SurfaceKHR surface
Definition: utils.hpp:205