Introduce raii-compliant handle wrapper classes.

This commit is contained in:
asuessenbach
2021-02-17 10:49:59 +01:00
parent 8dc12ba963
commit 2cb1c19c7f
165 changed files with 32669 additions and 2892 deletions

View File

@@ -13,14 +13,14 @@
// limitations under the License.
//
// VulkanHpp Samples : 01_InitInstance
// Create and destroy a vk::UniqueInstance
// Create and destroy a vk::Instance
#include "vulkan/vulkan.hpp"
#include <iostream>
static char const * AppName = "01_InitInstance";
static char const * EngineName = "Vulkan.hpp";
static std::string AppName = "01_InitInstance";
static std::string EngineName = "Vulkan.hpp";
int main( int /*argc*/, char ** /*argv*/ )
{
@@ -29,16 +29,16 @@ int main( int /*argc*/, char ** /*argv*/ )
try
{
// initialize the vk::ApplicationInfo structure
vk::ApplicationInfo applicationInfo( AppName, 1, EngineName, 1, VK_API_VERSION_1_1 );
vk::ApplicationInfo applicationInfo( AppName.c_str(), 1, EngineName.c_str(), 1, VK_API_VERSION_1_1 );
// initialize the vk::InstanceCreateInfo
vk::InstanceCreateInfo instanceCreateInfo( {}, &applicationInfo );
// create a UniqueInstance
vk::UniqueInstance instance = vk::createInstanceUnique( instanceCreateInfo );
// create an Instance
vk::Instance instance = vk::createInstance( instanceCreateInfo );
// Note: No need to explicitly destroy the instance, as the corresponding destroy function is
// called by the destructor of the UniqueInstance on leaving this scope.
// destroy it again
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -30,27 +30,27 @@
#include <iostream>
static char const * AppName = "02_EnumerateDevices";
static char const * EngineName = "Vulkan.hpp";
static std::string AppName = "02_EnumerateDevices";
static std::string EngineName = "Vulkan.hpp";
int main( int /*argc*/, char ** /*argv*/ )
{
try
{
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName );
vk::Instance instance = vk::su::createInstance( AppName, EngineName );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessengerEXT( instance );
#endif
/* VULKAN_HPP_KEY_START */
// enumerate the physicalDevices
vk::PhysicalDevice physicalDevice = instance->enumeratePhysicalDevices().front();
// Note: PhysicalDevices are not created, but just enumerated. Therefore, there is nothing like a
// UniquePhysicalDevice. A PhysicalDevice is unique by definition, and there's no need to destroy it.
vk::PhysicalDevice physicalDevice = instance.enumeratePhysicalDevices().front();
/* VULKAN_HPP_KEY_END */
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -27,12 +27,13 @@ int main( int /*argc*/, char ** /*argv*/ )
{
try
{
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName );
vk::Instance instance = vk::su::createInstance( AppName, EngineName );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
vk::PhysicalDevice physicalDevice = instance->enumeratePhysicalDevices().front();
vk::PhysicalDevice physicalDevice = instance.enumeratePhysicalDevices().front();
/* VULKAN_HPP_KEY_START */
@@ -40,25 +41,26 @@ int main( int /*argc*/, char ** /*argv*/ )
std::vector<vk::QueueFamilyProperties> queueFamilyProperties = physicalDevice.getQueueFamilyProperties();
// get the first index into queueFamiliyProperties which supports graphics
size_t graphicsQueueFamilyIndex = std::distance(
queueFamilyProperties.begin(),
std::find_if(
queueFamilyProperties.begin(), queueFamilyProperties.end(), []( vk::QueueFamilyProperties const & qfp ) {
return qfp.queueFlags & vk::QueueFlagBits::eGraphics;
} ) );
auto propertyIterator = std::find_if(
queueFamilyProperties.begin(), queueFamilyProperties.end(), []( vk::QueueFamilyProperties const & qfp ) {
return qfp.queueFlags & vk::QueueFlagBits::eGraphics;
} );
size_t graphicsQueueFamilyIndex = std::distance( queueFamilyProperties.begin(), propertyIterator );
assert( graphicsQueueFamilyIndex < queueFamilyProperties.size() );
// create a UniqueDevice
// create a Device
float queuePriority = 0.0f;
vk::DeviceQueueCreateInfo deviceQueueCreateInfo(
vk::DeviceQueueCreateFlags(), static_cast<uint32_t>( graphicsQueueFamilyIndex ), 1, &queuePriority );
vk::UniqueDevice device =
physicalDevice.createDeviceUnique( vk::DeviceCreateInfo( vk::DeviceCreateFlags(), deviceQueueCreateInfo ) );
vk::Device device =
physicalDevice.createDevice( vk::DeviceCreateInfo( vk::DeviceCreateFlags(), deviceQueueCreateInfo ) );
// Note: No need to explicitly destroy the device, as the corresponding destroy function is
// called by the destructor of the UniqueDevice on leaving this scope.
// destroy the device
device.destroy();
/* VULKAN_HPP_KEY_END */
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -27,34 +27,41 @@ int main( int /*argc*/, char ** /*argv*/ )
{
try
{
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName );
vk::Instance instance = vk::su::createInstance( AppName, EngineName );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
vk::PhysicalDevice physicalDevice = instance->enumeratePhysicalDevices().front();
vk::PhysicalDevice physicalDevice = instance.enumeratePhysicalDevices().front();
uint32_t graphicsQueueFamilyIndex =
vk::su::findGraphicsQueueFamilyIndex( physicalDevice.getQueueFamilyProperties() );
vk::UniqueDevice device = vk::su::createDevice( physicalDevice, graphicsQueueFamilyIndex );
vk::Device device = vk::su::createDevice( physicalDevice, graphicsQueueFamilyIndex );
/* VULKAN_HPP_KEY_START */
// create a UniqueCommandPool to allocate a CommandBuffer from
vk::UniqueCommandPool commandPool = device->createCommandPoolUnique(
vk::CommandPoolCreateInfo( vk::CommandPoolCreateFlags(), graphicsQueueFamilyIndex ) );
// create a CommandPool to allocate a CommandBuffer from
vk::CommandPool commandPool =
device.createCommandPool( vk::CommandPoolCreateInfo( vk::CommandPoolCreateFlags(), graphicsQueueFamilyIndex ) );
// allocate a CommandBuffer from the CommandPool
vk::UniqueCommandBuffer commandBuffer = std::move( device
->allocateCommandBuffersUnique( vk::CommandBufferAllocateInfo(
commandPool.get(), vk::CommandBufferLevel::ePrimary, 1 ) )
.front() );
vk::CommandBuffer commandBuffer =
device.allocateCommandBuffers( vk::CommandBufferAllocateInfo( commandPool, vk::CommandBufferLevel::ePrimary, 1 ) )
.front();
// Note: No need to explicitly free the CommandBuffer or destroy the CommandPool, as the corresponding free and
// destroy functions are called by the destructor of the UniqueCommandBuffer and the UniqueCommandPool on leaving
// this scope.
// freeing the commandBuffer is optional, as it will automatically freed when the corresponding CommandPool is
// destroyed.
device.freeCommandBuffers( commandPool, commandBuffer );
// destroy the commandPool
device.destroyCommandPool( commandPool );
/* VULKAN_HPP_KEY_END */
device.destroy();
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -27,33 +27,33 @@ int main( int /*argc*/, char ** /*argv*/ )
{
try
{
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
vk::Instance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
vk::PhysicalDevice physicalDevice = instance->enumeratePhysicalDevices().front();
vk::PhysicalDevice physicalDevice = instance.enumeratePhysicalDevices().front();
std::vector<vk::QueueFamilyProperties> queueFamilyProperties = physicalDevice.getQueueFamilyProperties();
uint32_t graphicsQueueFamilyIndex = vk::su::findGraphicsQueueFamilyIndex( queueFamilyProperties );
/* VULKAN_HPP_KEY_START */
uint32_t width = 64;
uint32_t height = 64;
vk::su::WindowData window = vk::su::createWindow( AppName, { width, height } );
vk::UniqueSurfaceKHR surface;
uint32_t width = 64;
uint32_t height = 64;
vk::su::WindowData window = vk::su::createWindow( AppName, { width, height } );
vk::SurfaceKHR surface;
{
VkSurfaceKHR _surface;
glfwCreateWindowSurface( VkInstance( instance.get() ), window.handle, nullptr, &_surface );
vk::ObjectDestroy<vk::Instance, VULKAN_HPP_DEFAULT_DISPATCHER_TYPE> _deleter( instance.get() );
surface = vk::UniqueSurfaceKHR( vk::SurfaceKHR( _surface ), _deleter );
glfwCreateWindowSurface( static_cast<VkInstance>( instance ), window.handle, nullptr, &_surface );
surface = vk::SurfaceKHR( _surface );
}
// determine a queueFamilyIndex that suports present
// first check if the graphicsQueueFamiliyIndex is good enough
size_t presentQueueFamilyIndex =
physicalDevice.getSurfaceSupportKHR( static_cast<uint32_t>( graphicsQueueFamilyIndex ), surface.get() )
physicalDevice.getSurfaceSupportKHR( static_cast<uint32_t>( graphicsQueueFamilyIndex ), surface )
? graphicsQueueFamilyIndex
: queueFamilyProperties.size();
if ( presentQueueFamilyIndex == queueFamilyProperties.size() )
@@ -63,7 +63,7 @@ int main( int /*argc*/, char ** /*argv*/ )
for ( size_t i = 0; i < queueFamilyProperties.size(); i++ )
{
if ( ( queueFamilyProperties[i].queueFlags & vk::QueueFlagBits::eGraphics ) &&
physicalDevice.getSurfaceSupportKHR( static_cast<uint32_t>( i ), surface.get() ) )
physicalDevice.getSurfaceSupportKHR( static_cast<uint32_t>( i ), surface ) )
{
graphicsQueueFamilyIndex = vk::su::checked_cast<uint32_t>( i );
presentQueueFamilyIndex = i;
@@ -76,7 +76,7 @@ int main( int /*argc*/, char ** /*argv*/ )
// family index that supports present
for ( size_t i = 0; i < queueFamilyProperties.size(); i++ )
{
if ( physicalDevice.getSurfaceSupportKHR( static_cast<uint32_t>( i ), surface.get() ) )
if ( physicalDevice.getSurfaceSupportKHR( static_cast<uint32_t>( i ), surface ) )
{
presentQueueFamilyIndex = i;
break;
@@ -91,16 +91,15 @@ int main( int /*argc*/, char ** /*argv*/ )
}
// create a device
vk::UniqueDevice device =
vk::su::createDevice( physicalDevice, graphicsQueueFamilyIndex, vk::su::getDeviceExtensions() );
vk::Device device = vk::su::createDevice( physicalDevice, graphicsQueueFamilyIndex, vk::su::getDeviceExtensions() );
// get the supported VkFormats
std::vector<vk::SurfaceFormatKHR> formats = physicalDevice.getSurfaceFormatsKHR( surface.get() );
std::vector<vk::SurfaceFormatKHR> formats = physicalDevice.getSurfaceFormatsKHR( surface );
assert( !formats.empty() );
vk::Format format =
( formats[0].format == vk::Format::eUndefined ) ? vk::Format::eB8G8R8A8Unorm : formats[0].format;
vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR( surface.get() );
vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR( surface );
VkExtent2D swapchainExtent;
if ( surfaceCapabilities.currentExtent.width == std::numeric_limits<uint32_t>::max() )
{
@@ -127,14 +126,14 @@ int main( int /*argc*/, char ** /*argv*/ )
vk::CompositeAlphaFlagBitsKHR compositeAlpha =
( surfaceCapabilities.supportedCompositeAlpha & vk::CompositeAlphaFlagBitsKHR::ePreMultiplied )
? vk::CompositeAlphaFlagBitsKHR::ePreMultiplied
: ( surfaceCapabilities.supportedCompositeAlpha & vk::CompositeAlphaFlagBitsKHR::ePostMultiplied )
? vk::CompositeAlphaFlagBitsKHR::ePostMultiplied
: ( surfaceCapabilities.supportedCompositeAlpha & vk::CompositeAlphaFlagBitsKHR::eInherit )
? vk::CompositeAlphaFlagBitsKHR::eInherit
: vk::CompositeAlphaFlagBitsKHR::eOpaque;
: ( surfaceCapabilities.supportedCompositeAlpha & vk::CompositeAlphaFlagBitsKHR::ePostMultiplied )
? vk::CompositeAlphaFlagBitsKHR::ePostMultiplied
: ( surfaceCapabilities.supportedCompositeAlpha & vk::CompositeAlphaFlagBitsKHR::eInherit )
? vk::CompositeAlphaFlagBitsKHR::eInherit
: vk::CompositeAlphaFlagBitsKHR::eOpaque;
vk::SwapchainCreateInfoKHR swapChainCreateInfo( vk::SwapchainCreateFlagsKHR(),
surface.get(),
surface,
surfaceCapabilities.minImageCount,
format,
vk::ColorSpaceKHR::eSrgbNonlinear,
@@ -161,11 +160,11 @@ int main( int /*argc*/, char ** /*argv*/ )
swapChainCreateInfo.pQueueFamilyIndices = queueFamilyIndices;
}
vk::UniqueSwapchainKHR swapChain = device->createSwapchainKHRUnique( swapChainCreateInfo );
vk::SwapchainKHR swapChain = device.createSwapchainKHR( swapChainCreateInfo );
std::vector<vk::Image> swapChainImages = device->getSwapchainImagesKHR( swapChain.get() );
std::vector<vk::Image> swapChainImages = device.getSwapchainImagesKHR( swapChain );
std::vector<vk::UniqueImageView> imageViews;
std::vector<vk::ImageView> imageViews;
imageViews.reserve( swapChainImages.size() );
vk::ComponentMapping componentMapping(
vk::ComponentSwizzle::eR, vk::ComponentSwizzle::eG, vk::ComponentSwizzle::eB, vk::ComponentSwizzle::eA );
@@ -174,13 +173,22 @@ int main( int /*argc*/, char ** /*argv*/ )
{
vk::ImageViewCreateInfo imageViewCreateInfo(
vk::ImageViewCreateFlags(), image, vk::ImageViewType::e2D, format, componentMapping, subResourceRange );
imageViews.push_back( device->createImageViewUnique( imageViewCreateInfo ) );
imageViews.push_back( device.createImageView( imageViewCreateInfo ) );
}
// Note: No need to explicitly destroy the ImageViews or the swapChain, as the corresponding destroy
// functions are called by the destructor of the UniqueImageView and the UniqueSwapChainKHR on leaving this scope.
// destroy the imageViews, the swapChain,and the surface
for ( auto & imageView : imageViews )
{
device.destroyImageView( imageView );
}
device.destroySwapchainKHR( swapChain );
instance.destroySurfaceKHR( surface );
/* VULKAN_HPP_KEY_END */
device.destroy();
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -27,18 +27,19 @@ int main( int /*argc*/, char ** /*argv*/ )
{
try
{
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
vk::Instance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
vk::PhysicalDevice physicalDevice = instance->enumeratePhysicalDevices().front();
vk::PhysicalDevice physicalDevice = instance.enumeratePhysicalDevices().front();
vk::su::SurfaceData surfaceData( instance, AppName, vk::Extent2D( 500, 500 ) );
std::pair<uint32_t, uint32_t> graphicsAndPresentQueueFamilyIndex =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, *surfaceData.surface );
vk::UniqueDevice device =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, surfaceData.surface );
vk::Device device =
vk::su::createDevice( physicalDevice, graphicsAndPresentQueueFamilyIndex.first, vk::su::getDeviceExtensions() );
/* VULKAN_HPP_KEY_START */
@@ -68,10 +69,10 @@ int main( int /*argc*/, char ** /*argv*/ )
vk::SampleCountFlagBits::e1,
tiling,
vk::ImageUsageFlagBits::eDepthStencilAttachment );
vk::UniqueImage depthImage = device->createImageUnique( imageCreateInfo );
vk::Image depthImage = device.createImage( imageCreateInfo );
vk::PhysicalDeviceMemoryProperties memoryProperties = physicalDevice.getMemoryProperties();
vk::MemoryRequirements memoryRequirements = device->getImageMemoryRequirements( depthImage.get() );
vk::MemoryRequirements memoryRequirements = device.getImageMemoryRequirements( depthImage );
uint32_t typeBits = memoryRequirements.memoryTypeBits;
uint32_t typeIndex = uint32_t( ~0 );
for ( uint32_t i = 0; i < memoryProperties.memoryTypeCount; i++ )
@@ -86,22 +87,32 @@ int main( int /*argc*/, char ** /*argv*/ )
typeBits >>= 1;
}
assert( typeIndex != uint32_t( ~0 ) );
vk::UniqueDeviceMemory depthMemory =
device->allocateMemoryUnique( vk::MemoryAllocateInfo( memoryRequirements.size, typeIndex ) );
vk::DeviceMemory depthMemory =
device.allocateMemory( vk::MemoryAllocateInfo( memoryRequirements.size, typeIndex ) );
device->bindImageMemory( depthImage.get(), depthMemory.get(), 0 );
device.bindImageMemory( depthImage, depthMemory, 0 );
vk::ComponentMapping componentMapping(
vk::ComponentSwizzle::eR, vk::ComponentSwizzle::eG, vk::ComponentSwizzle::eB, vk::ComponentSwizzle::eA );
vk::ImageSubresourceRange subResourceRange( vk::ImageAspectFlagBits::eDepth, 0, 1, 0, 1 );
vk::UniqueImageView depthView = device->createImageViewUnique( vk::ImageViewCreateInfo( vk::ImageViewCreateFlags(),
depthImage.get(),
vk::ImageViewType::e2D,
depthFormat,
componentMapping,
subResourceRange ) );
vk::ImageView depthView = device.createImageView( vk::ImageViewCreateInfo( vk::ImageViewCreateFlags(),
depthImage,
vk::ImageViewType::e2D,
depthFormat,
componentMapping,
subResourceRange ) );
// destroy depthView, depthMemory, and depthImage
device.destroyImageView( depthView );
device.freeMemory( depthMemory );
device.destroyImage( depthImage );
/* VULKAN_HPP_KEY_END */
device.destroy();
instance.destroySurfaceKHR( surfaceData.surface );
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -16,9 +16,9 @@
// Initialize a uniform buffer
#if defined( _MSC_VER )
# pragma warning( disable : 4127 ) // disable warning 4127: conditional expression is constant
# pragma warning( disable : 4201 ) // disable warning C4201: nonstandard extension used: nameless struct/union; needed
// to get glm/detail/type_vec?.hpp without warnings
# pragma warning( disable : 4127 ) // disable warning 4127: conditional expression is constant
# pragma warning( disable : 4201 ) // disable warning C4201: nonstandard extension used: nameless struct/union; needed
// to get glm/detail/type_vec?.hpp without warnings
#elif defined( __GNUC__ )
// don't know how to switch off that warning here
#else
@@ -30,7 +30,7 @@
#include <iostream>
# define GLM_FORCE_RADIANS
#define GLM_FORCE_RADIANS
#include <glm/gtc/matrix_transform.hpp>
static char const * AppName = "07_InitUniformBuffer";
@@ -40,15 +40,17 @@ int main( int /*argc*/, char ** /*argv*/ )
{
try
{
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName );
vk::Instance instance = vk::su::createInstance( AppName, EngineName );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
vk::PhysicalDevice physicalDevice = instance->enumeratePhysicalDevices().front();
vk::PhysicalDevice physicalDevice = instance.enumeratePhysicalDevices().front();
vk::UniqueDevice device = vk::su::createDevice(
physicalDevice, vk::su::findGraphicsQueueFamilyIndex( physicalDevice.getQueueFamilyProperties() ) );
uint32_t graphicsQueueFamilyIndex =
vk::su::findGraphicsQueueFamilyIndex( physicalDevice.getQueueFamilyProperties() );
vk::Device device = vk::su::createDevice( physicalDevice, graphicsQueueFamilyIndex );
/* VULKAN_HPP_KEY_START */
@@ -56,46 +58,40 @@ int main( int /*argc*/, char ** /*argv*/ )
glm::mat4x4 view =
glm::lookAt( glm::vec3( -5.0f, 3.0f, -10.0f ), glm::vec3( 0.0f, 0.0f, 0.0f ), glm::vec3( 0.0f, -1.0f, 0.0f ) );
glm::mat4x4 projection = glm::perspective( glm::radians( 45.0f ), 1.0f, 0.1f, 100.0f );
glm::mat4x4 clip = glm::mat4x4( 1.0f,
0.0f,
0.0f,
0.0f,
0.0f,
-1.0f,
0.0f,
0.0f,
0.0f,
0.0f,
0.5f,
0.0f,
0.0f,
0.0f,
0.5f,
1.0f ); // vulkan clip space has inverted y and half z !
glm::mat4x4 mvpc = clip * projection * view * model;
// clang-format off
glm::mat4x4 clip = glm::mat4x4( 1.0f, 0.0f, 0.0f, 0.0f,
0.0f, -1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.5f, 0.0f,
0.0f, 0.0f, 0.5f, 1.0f ); // vulkan clip space has inverted y and half z !
// clang-format on
glm::mat4x4 mvpc = clip * projection * view * model;
vk::UniqueBuffer uniformDataBuffer = device->createBufferUnique(
vk::Buffer uniformDataBuffer = device.createBuffer(
vk::BufferCreateInfo( vk::BufferCreateFlags(), sizeof( mvpc ), vk::BufferUsageFlagBits::eUniformBuffer ) );
vk::MemoryRequirements memoryRequirements = device->getBufferMemoryRequirements( uniformDataBuffer.get() );
vk::MemoryRequirements memoryRequirements = device.getBufferMemoryRequirements( uniformDataBuffer );
uint32_t typeIndex =
vk::su::findMemoryType( physicalDevice.getMemoryProperties(),
memoryRequirements.memoryTypeBits,
vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent );
vk::UniqueDeviceMemory uniformDataMemory =
device->allocateMemoryUnique( vk::MemoryAllocateInfo( memoryRequirements.size, typeIndex ) );
vk::DeviceMemory uniformDataMemory =
device.allocateMemory( vk::MemoryAllocateInfo( memoryRequirements.size, typeIndex ) );
uint8_t * pData =
static_cast<uint8_t *>( device->mapMemory( uniformDataMemory.get(), 0, memoryRequirements.size ) );
uint8_t * pData = static_cast<uint8_t *>( device.mapMemory( uniformDataMemory, 0, memoryRequirements.size ) );
memcpy( pData, &mvpc, sizeof( mvpc ) );
device->unmapMemory( uniformDataMemory.get() );
device.unmapMemory( uniformDataMemory );
device->bindBufferMemory( uniformDataBuffer.get(), uniformDataMemory.get(), 0 );
device.bindBufferMemory( uniformDataBuffer, uniformDataMemory, 0 );
// Note: No need to explicitly destroy the memory or the buffer, as the corresponding destroy function is
// called by the destructor of the UniqueMemory or UniqueBuffer, respectively, on leaving this scope.
// free device memory and destroy buffer
device.freeMemory( uniformDataMemory );
device.destroyBuffer( uniformDataBuffer );
/* VULKAN_HPP_KEY_END */
device.destroy();
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -27,33 +27,39 @@ int main( int /*argc*/, char ** /*argv*/ )
{
try
{
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName );
vk::Instance instance = vk::su::createInstance( AppName, EngineName );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
vk::PhysicalDevice physicalDevice = instance->enumeratePhysicalDevices().front();
vk::PhysicalDevice physicalDevice = instance.enumeratePhysicalDevices().front();
vk::UniqueDevice device = vk::su::createDevice(
physicalDevice, vk::su::findGraphicsQueueFamilyIndex( physicalDevice.getQueueFamilyProperties() ) );
uint32_t graphicsQueueFamilyIndex =
vk::su::findGraphicsQueueFamilyIndex( physicalDevice.getQueueFamilyProperties() );
vk::Device device = vk::su::createDevice( physicalDevice, graphicsQueueFamilyIndex );
/* VULKAN_HPP_KEY_START */
// create a DescriptorSetLayout
vk::DescriptorSetLayoutBinding descriptorSetLayoutBinding(
0, vk::DescriptorType::eUniformBuffer, 1, vk::ShaderStageFlagBits::eVertex );
vk::UniqueDescriptorSetLayout descriptorSetLayout = device->createDescriptorSetLayoutUnique(
vk::DescriptorSetLayout descriptorSetLayout = device.createDescriptorSetLayout(
vk::DescriptorSetLayoutCreateInfo( vk::DescriptorSetLayoutCreateFlags(), descriptorSetLayoutBinding ) );
// create a PipelineLayout using that DescriptorSetLayout
vk::UniquePipelineLayout pipelineLayout = device->createPipelineLayoutUnique(
vk::PipelineLayoutCreateInfo( vk::PipelineLayoutCreateFlags(), *descriptorSetLayout ) );
vk::PipelineLayout pipelineLayout = device.createPipelineLayout(
vk::PipelineLayoutCreateInfo( vk::PipelineLayoutCreateFlags(), descriptorSetLayout ) );
// Note: No need to explicitly destroy the layouts, as the corresponding destroy function is
// called by the destructor of the UniqueDescriptorSetLayout or UniquePipelineLayout, respectively, on leaving this
// scope.
// destroy the pipelineLayout and the descriptorSetLayout
device.destroyPipelineLayout( pipelineLayout );
device.destroyDescriptorSetLayout( descriptorSetLayout );
/* VULKAN_HPP_KEY_END */
device.destroy();
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -40,42 +40,52 @@ int main( int /*argc*/, char ** /*argv*/ )
{
try
{
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName );
vk::Instance instance = vk::su::createInstance( AppName, EngineName );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
vk::PhysicalDevice physicalDevice = instance->enumeratePhysicalDevices().front();
vk::PhysicalDevice physicalDevice = instance.enumeratePhysicalDevices().front();
vk::UniqueDevice device = vk::su::createDevice(
physicalDevice, vk::su::findGraphicsQueueFamilyIndex( physicalDevice.getQueueFamilyProperties() ) );
uint32_t graphicsQueueFamilyIndex =
vk::su::findGraphicsQueueFamilyIndex( physicalDevice.getQueueFamilyProperties() );
vk::Device device = vk::su::createDevice( physicalDevice, graphicsQueueFamilyIndex );
vk::su::BufferData uniformBufferData(
physicalDevice, device, sizeof( glm::mat4x4 ), vk::BufferUsageFlagBits::eUniformBuffer );
vk::su::copyToDevice(
device, uniformBufferData.deviceMemory, vk::su::createModelViewProjectionClipMatrix( vk::Extent2D( 0, 0 ) ) );
glm::mat4x4 mvpcMatrix = vk::su::createModelViewProjectionClipMatrix( vk::Extent2D( 0, 0 ) );
vk::su::copyToDevice( device, uniformBufferData.deviceMemory, mvpcMatrix );
vk::UniqueDescriptorSetLayout descriptorSetLayout = vk::su::createDescriptorSetLayout(
vk::DescriptorSetLayout descriptorSetLayout = vk::su::createDescriptorSetLayout(
device, { { vk::DescriptorType::eUniformBuffer, 1, vk::ShaderStageFlagBits::eVertex } } );
/* VULKAN_HPP_KEY_START */
// create a descriptor pool
vk::DescriptorPoolSize poolSize( vk::DescriptorType::eUniformBuffer, 1 );
vk::UniqueDescriptorPool descriptorPool = device->createDescriptorPoolUnique(
vk::DescriptorPoolSize poolSize( vk::DescriptorType::eUniformBuffer, 1 );
vk::DescriptorPool descriptorPool = device.createDescriptorPool(
vk::DescriptorPoolCreateInfo( vk::DescriptorPoolCreateFlagBits::eFreeDescriptorSet, 1, poolSize ) );
// allocate a descriptor set
vk::UniqueDescriptorSet descriptorSet = std::move(
device->allocateDescriptorSetsUnique( vk::DescriptorSetAllocateInfo( *descriptorPool, *descriptorSetLayout ) )
.front() );
vk::DescriptorSetAllocateInfo descriptorSetAllocateInfo( descriptorPool, descriptorSetLayout );
vk::DescriptorSet descriptorSet = device.allocateDescriptorSets( descriptorSetAllocateInfo ).front();
vk::DescriptorBufferInfo descriptorBufferInfo( uniformBufferData.buffer.get(), 0, sizeof( glm::mat4x4 ) );
device->updateDescriptorSets(
vk::WriteDescriptorSet( descriptorSet.get(), 0, 0, vk::DescriptorType::eUniformBuffer, {}, descriptorBufferInfo ),
{} );
vk::DescriptorBufferInfo descriptorBufferInfo( uniformBufferData.buffer, 0, sizeof( glm::mat4x4 ) );
vk::WriteDescriptorSet writeDescriptorSet(
descriptorSet, 0, 0, vk::DescriptorType::eUniformBuffer, {}, descriptorBufferInfo );
device.updateDescriptorSets( writeDescriptorSet, nullptr );
device.freeDescriptorSets( descriptorPool, descriptorSet );
device.destroyDescriptorPool( descriptorPool );
/* VULKAN_HPP_KEY_END */
device.destroyDescriptorSetLayout( descriptorSetLayout );
uniformBufferData.clear( device );
device.destroy();
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -16,8 +16,8 @@
// Initialize a render pass
#if defined( _MSC_VER )
# pragma warning( disable : 4201 ) // disable warning C4201: nonstandard extension used: nameless struct/union; needed
// to get glm/detail/type_vec?.hpp without warnings
# pragma warning( disable : 4201 ) // disable warning C4201: nonstandard extension used: nameless struct/union; needed
// to get glm/detail/type_vec?.hpp without warnings
#elif defined( __GNUC__ )
// don't know how to switch off that warning here
#else
@@ -39,22 +39,23 @@ int main( int /*argc*/, char ** /*argv*/ )
{
try
{
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
vk::Instance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
vk::PhysicalDevice physicalDevice = instance->enumeratePhysicalDevices().front();
vk::PhysicalDevice physicalDevice = instance.enumeratePhysicalDevices().front();
vk::su::SurfaceData surfaceData( instance, AppName, vk::Extent2D( 64, 64 ) );
std::pair<uint32_t, uint32_t> graphicsAndPresentQueueFamilyIndex =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, *surfaceData.surface );
vk::UniqueDevice device =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, surfaceData.surface );
vk::Device device =
vk::su::createDevice( physicalDevice, graphicsAndPresentQueueFamilyIndex.first, vk::su::getDeviceExtensions() );
vk::Format colorFormat =
vk::su::pickSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( surfaceData.surface.get() ) ).format;
vk::su::pickSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( surfaceData.surface ) ).format;
vk::Format depthFormat = vk::Format::eD16Unorm;
/* VULKAN_HPP_KEY_START */
@@ -84,13 +85,17 @@ int main( int /*argc*/, char ** /*argv*/ )
vk::SubpassDescription subpass(
vk::SubpassDescriptionFlags(), vk::PipelineBindPoint::eGraphics, {}, colorReference, {}, &depthReference );
vk::UniqueRenderPass renderPass = device->createRenderPassUnique(
vk::RenderPass renderPass = device.createRenderPass(
vk::RenderPassCreateInfo( vk::RenderPassCreateFlags(), attachmentDescriptions, subpass ) );
// Note: No need to explicitly destroy the RenderPass or the Semaphore, as the corresponding destroy
// functions are called by the destructor of the UniqueRenderPass and the UniqueSemaphore on leaving this scope.
device.destroyRenderPass( renderPass );
/* VULKAN_HPP_KEY_END */
device.destroy();
instance.destroySurfaceKHR( surfaceData.surface );
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -29,15 +29,17 @@ int main( int /*argc*/, char ** /*argv*/ )
{
try
{
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
vk::Instance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
vk::PhysicalDevice physicalDevice = instance->enumeratePhysicalDevices().front();
vk::PhysicalDevice physicalDevice = instance.enumeratePhysicalDevices().front();
vk::UniqueDevice device = vk::su::createDevice(
physicalDevice, vk::su::findGraphicsQueueFamilyIndex( physicalDevice.getQueueFamilyProperties() ) );
uint32_t graphicsQueueFamilyIndex =
vk::su::findGraphicsQueueFamilyIndex( physicalDevice.getQueueFamilyProperties() );
vk::Device device = vk::su::createDevice( physicalDevice, graphicsQueueFamilyIndex );
/* VULKAN_HPP_KEY_START */
@@ -48,21 +50,25 @@ int main( int /*argc*/, char ** /*argv*/ )
assert( ok );
vk::ShaderModuleCreateInfo vertexShaderModuleCreateInfo( vk::ShaderModuleCreateFlags(), vertexShaderSPV );
vk::UniqueShaderModule vertexShaderModule = device->createShaderModuleUnique( vertexShaderModuleCreateInfo );
vk::ShaderModule vertexShaderModule = device.createShaderModule( vertexShaderModuleCreateInfo );
std::vector<unsigned int> fragmentShaderSPV;
ok = vk::su::GLSLtoSPV( vk::ShaderStageFlagBits::eFragment, fragmentShaderText_C_C, fragmentShaderSPV );
assert( ok );
vk::ShaderModuleCreateInfo fragmentShaderModuleCreateInfo( vk::ShaderModuleCreateFlags(), fragmentShaderSPV );
vk::UniqueShaderModule fragmentShaderModule = device->createShaderModuleUnique( fragmentShaderModuleCreateInfo );
vk::ShaderModule fragmentShaderModule = device.createShaderModule( fragmentShaderModuleCreateInfo );
glslang::FinalizeProcess();
// Note: No need to explicitly destroy the ShaderModules, as the corresponding destroy
// functions are called by the destructor of the UniqueShaderModule on leaving this scope.
device.destroyShaderModule( fragmentShaderModule );
device.destroyShaderModule( vertexShaderModule );
/* VULKAN_HPP_KEY_END */
device.destroy();
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -27,57 +27,64 @@ int main( int /*argc*/, char ** /*argv*/ )
{
try
{
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
vk::Instance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
vk::PhysicalDevice physicalDevice = instance->enumeratePhysicalDevices().front();
vk::PhysicalDevice physicalDevice = instance.enumeratePhysicalDevices().front();
vk::su::SurfaceData surfaceData( instance, AppName, vk::Extent2D( 64, 64 ) );
std::pair<uint32_t, uint32_t> graphicsAndPresentQueueFamilyIndex =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, *surfaceData.surface );
vk::UniqueDevice device =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, surfaceData.surface );
vk::Device device =
vk::su::createDevice( physicalDevice, graphicsAndPresentQueueFamilyIndex.first, vk::su::getDeviceExtensions() );
vk::su::SwapChainData swapChainData( physicalDevice,
device,
*surfaceData.surface,
surfaceData.surface,
surfaceData.extent,
vk::ImageUsageFlagBits::eColorAttachment |
vk::ImageUsageFlagBits::eTransferSrc,
vk::UniqueSwapchainKHR(),
nullptr,
graphicsAndPresentQueueFamilyIndex.first,
graphicsAndPresentQueueFamilyIndex.second );
vk::su::DepthBufferData depthBufferData( physicalDevice, device, vk::Format::eD16Unorm, surfaceData.extent );
vk::UniqueRenderPass renderPass =
vk::su::createRenderPass( device, swapChainData.colorFormat, depthBufferData.format );
vk::RenderPass renderPass = vk::su::createRenderPass( device, swapChainData.colorFormat, depthBufferData.format );
/* VULKAN_KEY_START */
std::array<vk::ImageView, 2> attachments;
attachments[1] = depthBufferData.imageView.get();
attachments[1] = depthBufferData.imageView;
std::vector<vk::UniqueFramebuffer> framebuffers;
vk::FramebufferCreateInfo framebufferCreateInfo(
vk::FramebufferCreateFlags(), renderPass, attachments, surfaceData.extent.width, surfaceData.extent.height, 1 );
std::vector<vk::Framebuffer> framebuffers;
framebuffers.reserve( swapChainData.imageViews.size() );
for ( auto const & view : swapChainData.imageViews )
for ( auto const & imageView : swapChainData.imageViews )
{
attachments[0] = view.get();
framebuffers.push_back( device->createFramebufferUnique( vk::FramebufferCreateInfo( vk::FramebufferCreateFlags(),
renderPass.get(),
attachments,
surfaceData.extent.width,
surfaceData.extent.height,
1 ) ) );
attachments[0] = imageView;
framebuffers.push_back( device.createFramebuffer( framebufferCreateInfo ) );
}
// Note: No need to explicitly destroy the Framebuffers, as the destroy functions are called by the destructor of
// the UniqueFramebuffer on leaving this scope.
for ( auto const & framebuffer : framebuffers )
{
device.destroyFramebuffer( framebuffer );
}
/* VULKAN_KEY_END */
device.destroyRenderPass( renderPass );
depthBufferData.clear( device );
swapChainData.clear( device );
device.destroy();
instance.destroySurfaceKHR( surfaceData.surface );
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -28,73 +28,72 @@ int main( int /*argc*/, char ** /*argv*/ )
{
try
{
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
vk::Instance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
vk::PhysicalDevice physicalDevice = instance->enumeratePhysicalDevices().front();
vk::PhysicalDevice physicalDevice = instance.enumeratePhysicalDevices().front();
vk::su::SurfaceData surfaceData( instance, AppName, vk::Extent2D( 64, 64 ) );
std::pair<uint32_t, uint32_t> graphicsAndPresentQueueFamilyIndex =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, *surfaceData.surface );
vk::UniqueDevice device =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, surfaceData.surface );
vk::Device device =
vk::su::createDevice( physicalDevice, graphicsAndPresentQueueFamilyIndex.first, vk::su::getDeviceExtensions() );
vk::UniqueCommandPool commandPool = vk::su::createCommandPool( device, graphicsAndPresentQueueFamilyIndex.first );
vk::UniqueCommandBuffer commandBuffer = std::move( device
->allocateCommandBuffersUnique( vk::CommandBufferAllocateInfo(
commandPool.get(), vk::CommandBufferLevel::ePrimary, 1 ) )
.front() );
vk::CommandPool commandPool = vk::su::createCommandPool( device, graphicsAndPresentQueueFamilyIndex.first );
vk::CommandBuffer commandBuffer =
device.allocateCommandBuffers( vk::CommandBufferAllocateInfo( commandPool, vk::CommandBufferLevel::ePrimary, 1 ) )
.front();
vk::Queue graphicsQueue = device->getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
vk::Queue graphicsQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
vk::su::SwapChainData swapChainData( physicalDevice,
device,
*surfaceData.surface,
surfaceData.surface,
surfaceData.extent,
vk::ImageUsageFlagBits::eColorAttachment |
vk::ImageUsageFlagBits::eTransferSrc,
vk::UniqueSwapchainKHR(),
{},
graphicsAndPresentQueueFamilyIndex.first,
graphicsAndPresentQueueFamilyIndex.second );
vk::su::DepthBufferData depthBufferData( physicalDevice, device, vk::Format::eD16Unorm, surfaceData.extent );
vk::UniqueRenderPass renderPass =
vk::su::createRenderPass( device, swapChainData.colorFormat, depthBufferData.format );
vk::RenderPass renderPass = vk::su::createRenderPass( device, swapChainData.colorFormat, depthBufferData.format );
std::vector<vk::UniqueFramebuffer> framebuffers = vk::su::createFramebuffers(
std::vector<vk::Framebuffer> framebuffers = vk::su::createFramebuffers(
device, renderPass, swapChainData.imageViews, depthBufferData.imageView, surfaceData.extent );
/* VULKAN_KEY_START */
// create a vertex buffer for some vertex and color data
vk::UniqueBuffer vertexBuffer = device->createBufferUnique( vk::BufferCreateInfo(
vk::Buffer vertexBuffer = device.createBuffer( vk::BufferCreateInfo(
vk::BufferCreateFlags(), sizeof( coloredCubeData ), vk::BufferUsageFlagBits::eVertexBuffer ) );
// allocate device memory for that buffer
vk::MemoryRequirements memoryRequirements = device->getBufferMemoryRequirements( vertexBuffer.get() );
vk::MemoryRequirements memoryRequirements = device.getBufferMemoryRequirements( vertexBuffer );
uint32_t memoryTypeIndex =
vk::su::findMemoryType( physicalDevice.getMemoryProperties(),
memoryRequirements.memoryTypeBits,
vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent );
vk::UniqueDeviceMemory deviceMemory =
device->allocateMemoryUnique( vk::MemoryAllocateInfo( memoryRequirements.size, memoryTypeIndex ) );
vk::DeviceMemory deviceMemory =
device.allocateMemory( vk::MemoryAllocateInfo( memoryRequirements.size, memoryTypeIndex ) );
// copy the vertex and color data into that device memory
uint8_t * pData = static_cast<uint8_t *>( device->mapMemory( deviceMemory.get(), 0, memoryRequirements.size ) );
uint8_t * pData = static_cast<uint8_t *>( device.mapMemory( deviceMemory, 0, memoryRequirements.size ) );
memcpy( pData, coloredCubeData, sizeof( coloredCubeData ) );
device->unmapMemory( deviceMemory.get() );
device.unmapMemory( deviceMemory );
// and bind the device memory to the vertex buffer
device->bindBufferMemory( vertexBuffer.get(), deviceMemory.get(), 0 );
device.bindBufferMemory( vertexBuffer, deviceMemory, 0 );
vk::UniqueSemaphore imageAcquiredSemaphore =
device->createSemaphoreUnique( vk::SemaphoreCreateInfo( vk::SemaphoreCreateFlags() ) );
vk::ResultValue<uint32_t> currentBuffer = device->acquireNextImageKHR(
swapChainData.swapChain.get(), vk::su::FenceTimeout, imageAcquiredSemaphore.get(), nullptr );
vk::Semaphore imageAcquiredSemaphore =
device.createSemaphore( vk::SemaphoreCreateInfo( vk::SemaphoreCreateFlags() ) );
vk::ResultValue<uint32_t> currentBuffer = device.acquireNextImageKHR(
swapChainData.swapChain, vk::su::FenceTimeout, imageAcquiredSemaphore, nullptr );
assert( currentBuffer.result == vk::Result::eSuccess );
assert( currentBuffer.value < framebuffers.size() );
@@ -102,25 +101,39 @@ int main( int /*argc*/, char ** /*argv*/ )
clearValues[0].color = vk::ClearColorValue( std::array<float, 4>( { { 0.2f, 0.2f, 0.2f, 0.2f } } ) );
clearValues[1].depthStencil = vk::ClearDepthStencilValue( 1.0f, 0 );
commandBuffer->begin( vk::CommandBufferBeginInfo( vk::CommandBufferUsageFlags() ) );
commandBuffer.begin( vk::CommandBufferBeginInfo( vk::CommandBufferUsageFlags() ) );
vk::RenderPassBeginInfo renderPassBeginInfo( renderPass.get(),
framebuffers[currentBuffer.value].get(),
vk::RenderPassBeginInfo renderPassBeginInfo( renderPass,
framebuffers[currentBuffer.value],
vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ),
clearValues );
commandBuffer->beginRenderPass( renderPassBeginInfo, vk::SubpassContents::eInline );
commandBuffer.beginRenderPass( renderPassBeginInfo, vk::SubpassContents::eInline );
commandBuffer->bindVertexBuffers( 0, *vertexBuffer, { 0 } );
commandBuffer.bindVertexBuffers( 0, vertexBuffer, { 0 } );
commandBuffer->endRenderPass();
commandBuffer->end();
commandBuffer.endRenderPass();
commandBuffer.end();
vk::su::submitAndWait( device, graphicsQueue, commandBuffer );
// Note: No need to explicitly destroy the vertexBuffer, deviceMemory, or semaphore, as the destroy functions are
// called by the destructor of the UniqueBuffer, UniqueDeviceMemory, and UniqueSemaphore, respectively, on leaving
// this scope.
device.destroySemaphore( imageAcquiredSemaphore );
device.freeMemory( deviceMemory );
device.destroyBuffer( vertexBuffer );
/* VULKAN_KEY_END */
swapChainData.clear( device );
depthBufferData.clear( device );
for ( auto const & framebuffer : framebuffers )
{
device.destroyFramebuffer( framebuffer );
}
device.destroyRenderPass( renderPass );
device.freeCommandBuffers( commandPool, commandBuffer );
device.destroyCommandPool( commandPool );
device.destroy();
instance.destroySurfaceKHR( surfaceData.surface );
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -41,34 +41,35 @@ int main( int /*argc*/, char ** /*argv*/ )
{
try
{
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
vk::Instance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
vk::PhysicalDevice physicalDevice = instance->enumeratePhysicalDevices().front();
vk::PhysicalDevice physicalDevice = instance.enumeratePhysicalDevices().front();
vk::su::SurfaceData surfaceData( instance, AppName, vk::Extent2D( 500, 500 ) );
std::pair<uint32_t, uint32_t> graphicsAndPresentQueueFamilyIndex =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, *surfaceData.surface );
vk::UniqueDevice device =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, surfaceData.surface );
vk::Device device =
vk::su::createDevice( physicalDevice, graphicsAndPresentQueueFamilyIndex.first, vk::su::getDeviceExtensions() );
vk::UniqueRenderPass renderPass = vk::su::createRenderPass(
vk::RenderPass renderPass = vk::su::createRenderPass(
device,
vk::su::pickSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( surfaceData.surface.get() ) ).format,
vk::su::pickSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( surfaceData.surface ) ).format,
vk::Format::eD16Unorm );
vk::UniqueDescriptorSetLayout descriptorSetLayout = vk::su::createDescriptorSetLayout(
vk::DescriptorSetLayout descriptorSetLayout = vk::su::createDescriptorSetLayout(
device, { { vk::DescriptorType::eUniformBuffer, 1, vk::ShaderStageFlagBits::eVertex } } );
vk::UniquePipelineLayout pipelineLayout = device->createPipelineLayoutUnique(
vk::PipelineLayoutCreateInfo( vk::PipelineLayoutCreateFlags(), *descriptorSetLayout ) );
vk::PipelineLayout pipelineLayout = device.createPipelineLayout(
vk::PipelineLayoutCreateInfo( vk::PipelineLayoutCreateFlags(), descriptorSetLayout ) );
glslang::InitializeProcess();
vk::UniqueShaderModule vertexShaderModule =
vk::ShaderModule vertexShaderModule =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eVertex, vertexShaderText_PC_C );
vk::UniqueShaderModule fragmentShaderModule =
vk::ShaderModule fragmentShaderModule =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eFragment, fragmentShaderText_C_C );
glslang::FinalizeProcess();
@@ -76,9 +77,9 @@ int main( int /*argc*/, char ** /*argv*/ )
std::array<vk::PipelineShaderStageCreateInfo, 2> pipelineShaderStageCreateInfos = {
vk::PipelineShaderStageCreateInfo(
vk::PipelineShaderStageCreateFlags(), vk::ShaderStageFlagBits::eVertex, vertexShaderModule.get(), "main" ),
vk::PipelineShaderStageCreateFlags(), vk::ShaderStageFlagBits::eVertex, vertexShaderModule, "main" ),
vk::PipelineShaderStageCreateInfo(
vk::PipelineShaderStageCreateFlags(), vk::ShaderStageFlagBits::eFragment, fragmentShaderModule.get(), "main" )
vk::PipelineShaderStageCreateFlags(), vk::ShaderStageFlagBits::eFragment, fragmentShaderModule, "main" )
};
vk::VertexInputBindingDescription vertexInputBindingDescription( 0, sizeof( coloredCubeData[0] ) );
@@ -167,14 +168,13 @@ int main( int /*argc*/, char ** /*argv*/ )
&pipelineDepthStencilStateCreateInfo, // pDepthStencilState
&pipelineColorBlendStateCreateInfo, // pColorBlendState
&pipelineDynamicStateCreateInfo, // pDynamicState
pipelineLayout.get(), // layout
renderPass.get() // renderPass
pipelineLayout, // layout
renderPass // renderPass
);
vk::Result result;
vk::UniquePipeline pipeline;
std::tie( result, pipeline ) =
device->createGraphicsPipelineUnique( nullptr, graphicsPipelineCreateInfo ).asTuple();
vk::Result result;
vk::Pipeline pipeline;
std::tie( result, pipeline ) = device.createGraphicsPipeline( nullptr, graphicsPipelineCreateInfo );
switch ( result )
{
case vk::Result::eSuccess: break;
@@ -184,7 +184,19 @@ int main( int /*argc*/, char ** /*argv*/ )
default: assert( false ); // should never happen
}
device.destroyPipeline( pipeline );
/* VULKAN_KEY_END */
device.destroyShaderModule( fragmentShaderModule );
device.destroyShaderModule( vertexShaderModule );
device.destroyPipelineLayout( pipelineLayout );
device.destroyDescriptorSetLayout( descriptorSetLayout );
device.destroyRenderPass( renderPass );
device.destroy();
instance.destroySurfaceKHR( surfaceData.surface );
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -32,36 +32,36 @@ int main( int /*argc*/, char ** /*argv*/ )
{
try
{
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
vk::Instance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
vk::PhysicalDevice physicalDevice = instance->enumeratePhysicalDevices().front();
vk::PhysicalDevice physicalDevice = instance.enumeratePhysicalDevices().front();
vk::su::SurfaceData surfaceData( instance, AppName, vk::Extent2D( 500, 500 ) );
std::pair<uint32_t, uint32_t> graphicsAndPresentQueueFamilyIndex =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, *surfaceData.surface );
vk::UniqueDevice device =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, surfaceData.surface );
vk::Device device =
vk::su::createDevice( physicalDevice, graphicsAndPresentQueueFamilyIndex.first, vk::su::getDeviceExtensions() );
vk::UniqueCommandPool commandPool = vk::su::createCommandPool( device, graphicsAndPresentQueueFamilyIndex.first );
vk::UniqueCommandBuffer commandBuffer = std::move( device
->allocateCommandBuffersUnique( vk::CommandBufferAllocateInfo(
commandPool.get(), vk::CommandBufferLevel::ePrimary, 1 ) )
.front() );
vk::CommandPool commandPool = vk::su::createCommandPool( device, graphicsAndPresentQueueFamilyIndex.first );
vk::CommandBuffer commandBuffer =
device.allocateCommandBuffers( vk::CommandBufferAllocateInfo( commandPool, vk::CommandBufferLevel::ePrimary, 1 ) )
.front();
vk::Queue graphicsQueue = device->getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
vk::Queue presentQueue = device->getQueue( graphicsAndPresentQueueFamilyIndex.second, 0 );
vk::Queue graphicsQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
vk::Queue presentQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.second, 0 );
vk::su::SwapChainData swapChainData( physicalDevice,
device,
*surfaceData.surface,
surfaceData.surface,
surfaceData.extent,
vk::ImageUsageFlagBits::eColorAttachment |
vk::ImageUsageFlagBits::eTransferSrc,
vk::UniqueSwapchainKHR(),
{},
graphicsAndPresentQueueFamilyIndex.first,
graphicsAndPresentQueueFamilyIndex.second );
@@ -69,27 +69,27 @@ int main( int /*argc*/, char ** /*argv*/ )
vk::su::BufferData uniformBufferData(
physicalDevice, device, sizeof( glm::mat4x4 ), vk::BufferUsageFlagBits::eUniformBuffer );
vk::su::copyToDevice(
device, uniformBufferData.deviceMemory, vk::su::createModelViewProjectionClipMatrix( surfaceData.extent ) );
glm::mat4x4 mvpcMatrix = vk::su::createModelViewProjectionClipMatrix( surfaceData.extent );
vk::su::copyToDevice( device, uniformBufferData.deviceMemory, mvpcMatrix );
vk::UniqueDescriptorSetLayout descriptorSetLayout = vk::su::createDescriptorSetLayout(
vk::DescriptorSetLayout descriptorSetLayout = vk::su::createDescriptorSetLayout(
device, { { vk::DescriptorType::eUniformBuffer, 1, vk::ShaderStageFlagBits::eVertex } } );
vk::UniquePipelineLayout pipelineLayout = device->createPipelineLayoutUnique(
vk::PipelineLayoutCreateInfo( vk::PipelineLayoutCreateFlags(), *descriptorSetLayout ) );
vk::PipelineLayout pipelineLayout = device.createPipelineLayout(
vk::PipelineLayoutCreateInfo( vk::PipelineLayoutCreateFlags(), descriptorSetLayout ) );
vk::UniqueRenderPass renderPass = vk::su::createRenderPass(
vk::RenderPass renderPass = vk::su::createRenderPass(
device,
vk::su::pickSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( surfaceData.surface.get() ) ).format,
vk::su::pickSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( surfaceData.surface ) ).format,
depthBufferData.format );
glslang::InitializeProcess();
vk::UniqueShaderModule vertexShaderModule =
vk::ShaderModule vertexShaderModule =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eVertex, vertexShaderText_PC_C );
vk::UniqueShaderModule fragmentShaderModule =
vk::ShaderModule fragmentShaderModule =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eFragment, fragmentShaderText_C_C );
glslang::FinalizeProcess();
std::vector<vk::UniqueFramebuffer> framebuffers = vk::su::createFramebuffers(
std::vector<vk::Framebuffer> framebuffers = vk::su::createFramebuffers(
device, renderPass, swapChainData.imageViews, depthBufferData.imageView, surfaceData.extent );
vk::su::BufferData vertexBufferData(
@@ -99,75 +99,74 @@ int main( int /*argc*/, char ** /*argv*/ )
coloredCubeData,
sizeof( coloredCubeData ) / sizeof( coloredCubeData[0] ) );
vk::UniqueDescriptorPool descriptorPool =
vk::DescriptorPool descriptorPool =
vk::su::createDescriptorPool( device, { { vk::DescriptorType::eUniformBuffer, 1 } } );
vk::UniqueDescriptorSet descriptorSet = std::move(
device->allocateDescriptorSetsUnique( vk::DescriptorSetAllocateInfo( *descriptorPool, *descriptorSetLayout ) )
.front() );
vk::DescriptorSetAllocateInfo descriptorSetAllocateInfo( descriptorPool, descriptorSetLayout );
vk::DescriptorSet descriptorSet = device.allocateDescriptorSets( descriptorSetAllocateInfo ).front();
vk::su::updateDescriptorSets(
device, descriptorSet, { { vk::DescriptorType::eUniformBuffer, uniformBufferData.buffer, {} } }, {} );
vk::UniquePipelineCache pipelineCache = device->createPipelineCacheUnique( vk::PipelineCacheCreateInfo() );
vk::UniquePipeline graphicsPipeline = vk::su::createGraphicsPipeline(
vk::PipelineCache pipelineCache = device.createPipelineCache( vk::PipelineCacheCreateInfo() );
vk::Pipeline graphicsPipeline = vk::su::createGraphicsPipeline(
device,
pipelineCache,
std::make_pair( *vertexShaderModule, nullptr ),
std::make_pair( *fragmentShaderModule, nullptr ),
std::make_pair( vertexShaderModule, nullptr ),
std::make_pair( fragmentShaderModule, nullptr ),
sizeof( coloredCubeData[0] ),
{ { vk::Format::eR32G32B32A32Sfloat, 0 }, { vk::Format::eR32G32B32A32Sfloat, 16 } },
vk::FrontFace::eClockwise,
true,
pipelineLayout,
renderPass );
/* VULKAN_KEY_START */
// Get the index of the next available swapchain image:
vk::UniqueSemaphore imageAcquiredSemaphore = device->createSemaphoreUnique( vk::SemaphoreCreateInfo() );
vk::ResultValue<uint32_t> currentBuffer = device->acquireNextImageKHR(
swapChainData.swapChain.get(), vk::su::FenceTimeout, imageAcquiredSemaphore.get(), nullptr );
vk::Semaphore imageAcquiredSemaphore = device.createSemaphore( vk::SemaphoreCreateInfo() );
vk::ResultValue<uint32_t> currentBuffer =
device.acquireNextImageKHR( swapChainData.swapChain, vk::su::FenceTimeout, imageAcquiredSemaphore, nullptr );
assert( currentBuffer.result == vk::Result::eSuccess );
assert( currentBuffer.value < framebuffers.size() );
commandBuffer->begin( vk::CommandBufferBeginInfo( vk::CommandBufferUsageFlags() ) );
commandBuffer.begin( vk::CommandBufferBeginInfo( vk::CommandBufferUsageFlags() ) );
std::array<vk::ClearValue, 2> clearValues;
clearValues[0].color = vk::ClearColorValue( std::array<float, 4>( { { 0.2f, 0.2f, 0.2f, 0.2f } } ) );
clearValues[1].depthStencil = vk::ClearDepthStencilValue( 1.0f, 0 );
vk::RenderPassBeginInfo renderPassBeginInfo( renderPass.get(),
framebuffers[currentBuffer.value].get(),
vk::RenderPassBeginInfo renderPassBeginInfo( renderPass,
framebuffers[currentBuffer.value],
vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ),
clearValues );
commandBuffer->beginRenderPass( renderPassBeginInfo, vk::SubpassContents::eInline );
commandBuffer->bindPipeline( vk::PipelineBindPoint::eGraphics, graphicsPipeline.get() );
commandBuffer->bindDescriptorSets(
vk::PipelineBindPoint::eGraphics, pipelineLayout.get(), 0, descriptorSet.get(), nullptr );
commandBuffer.beginRenderPass( renderPassBeginInfo, vk::SubpassContents::eInline );
commandBuffer.bindPipeline( vk::PipelineBindPoint::eGraphics, graphicsPipeline );
commandBuffer.bindDescriptorSets( vk::PipelineBindPoint::eGraphics, pipelineLayout, 0, descriptorSet, nullptr );
commandBuffer->bindVertexBuffers( 0, *vertexBufferData.buffer, { 0 } );
commandBuffer->setViewport( 0,
vk::Viewport( 0.0f,
0.0f,
static_cast<float>( surfaceData.extent.width ),
static_cast<float>( surfaceData.extent.height ),
0.0f,
1.0f ) );
commandBuffer->setScissor( 0, vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ) );
commandBuffer.bindVertexBuffers( 0, vertexBufferData.buffer, { 0 } );
commandBuffer.setViewport( 0,
vk::Viewport( 0.0f,
0.0f,
static_cast<float>( surfaceData.extent.width ),
static_cast<float>( surfaceData.extent.height ),
0.0f,
1.0f ) );
commandBuffer.setScissor( 0, vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ) );
commandBuffer->draw( 12 * 3, 1, 0, 0 );
commandBuffer->endRenderPass();
commandBuffer->end();
commandBuffer.draw( 12 * 3, 1, 0, 0 );
commandBuffer.endRenderPass();
commandBuffer.end();
vk::UniqueFence drawFence = device->createFenceUnique( vk::FenceCreateInfo() );
vk::Fence drawFence = device.createFence( vk::FenceCreateInfo() );
vk::PipelineStageFlags waitDestinationStageMask( vk::PipelineStageFlagBits::eColorAttachmentOutput );
vk::SubmitInfo submitInfo( *imageAcquiredSemaphore, waitDestinationStageMask, *commandBuffer );
graphicsQueue.submit( submitInfo, drawFence.get() );
vk::SubmitInfo submitInfo( imageAcquiredSemaphore, waitDestinationStageMask, commandBuffer );
graphicsQueue.submit( submitInfo, drawFence );
while ( vk::Result::eTimeout == device->waitForFences( drawFence.get(), VK_TRUE, vk::su::FenceTimeout ) )
while ( vk::Result::eTimeout == device.waitForFences( drawFence, VK_TRUE, vk::su::FenceTimeout ) )
;
vk::Result result =
presentQueue.presentKHR( vk::PresentInfoKHR( {}, *swapChainData.swapChain, currentBuffer.value ) );
presentQueue.presentKHR( vk::PresentInfoKHR( {}, swapChainData.swapChain, currentBuffer.value ) );
switch ( result )
{
case vk::Result::eSuccess: break;
@@ -178,9 +177,34 @@ int main( int /*argc*/, char ** /*argv*/ )
}
std::this_thread::sleep_for( std::chrono::milliseconds( 1000 ) );
device.waitIdle();
device.destroyFence( drawFence );
device.destroySemaphore( imageAcquiredSemaphore );
/* VULKAN_KEY_END */
device->waitIdle();
device.destroyPipeline( graphicsPipeline );
device.destroyPipelineCache( pipelineCache );
device.destroyDescriptorPool( descriptorPool );
vertexBufferData.clear( device );
for ( auto framebuffer : framebuffers )
{
device.destroyFramebuffer( framebuffer );
}
device.destroyShaderModule( fragmentShaderModule );
device.destroyShaderModule( vertexShaderModule );
device.destroyRenderPass( renderPass );
device.destroyPipelineLayout( pipelineLayout );
device.destroyDescriptorSetLayout( descriptorSetLayout );
uniformBufferData.clear( device );
depthBufferData.clear( device );
swapChainData.clear( device );
device.destroyCommandPool( commandPool );
device.destroy();
instance.destroySurfaceKHR( surfaceData.surface );
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -63,14 +63,15 @@ int main( int /*argc*/, char ** /*argv*/ )
( loader_major_version == desiredMajorVersion && loader_minor_version >= desiredMinorVersion ) )
{
// Create the instance
vk::UniqueInstance instance =
vk::Instance instance =
vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions(), desiredVersion );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
// Get the list of physical devices
std::vector<vk::PhysicalDevice> physicalDevices = instance->enumeratePhysicalDevices();
std::vector<vk::PhysicalDevice> physicalDevices = instance.enumeratePhysicalDevices();
// Go through the list of physical devices and select only those that are capable of running the API version we
// want.
@@ -87,6 +88,9 @@ int main( int /*argc*/, char ** /*argv*/ )
usingMajorVersion = desiredMajorVersion;
usingMinorVersion = desiredMinorVersion;
}
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
usingVersionString += std::to_string( usingMajorVersion );

View File

@@ -27,17 +27,17 @@ int main( int /*argc*/, char ** /*argv*/ )
{
try
{
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
vk::Instance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
vk::PhysicalDevice physicalDevice = instance->enumeratePhysicalDevices().front();
vk::PhysicalDevice physicalDevice = instance.enumeratePhysicalDevices().front();
vk::su::SurfaceData surfaceData( instance, AppName, vk::Extent2D( 640, 640 ) );
vk::SurfaceCapabilitiesKHR surfaceCapabilities =
physicalDevice.getSurfaceCapabilitiesKHR( surfaceData.surface.get() );
vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR( surfaceData.surface );
if ( !( surfaceCapabilities.supportedUsageFlags & vk::ImageUsageFlagBits::eTransferDst ) )
{
std::cout << "Surface cannot be destination of blit - abort \n";
@@ -45,26 +45,25 @@ int main( int /*argc*/, char ** /*argv*/ )
}
std::pair<uint32_t, uint32_t> graphicsAndPresentQueueFamilyIndex =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, *surfaceData.surface );
vk::UniqueDevice device =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, surfaceData.surface );
vk::Device device =
vk::su::createDevice( physicalDevice, graphicsAndPresentQueueFamilyIndex.first, vk::su::getDeviceExtensions() );
vk::UniqueCommandPool commandPool = vk::su::createCommandPool( device, graphicsAndPresentQueueFamilyIndex.first );
vk::UniqueCommandBuffer commandBuffer = std::move( device
->allocateCommandBuffersUnique( vk::CommandBufferAllocateInfo(
commandPool.get(), vk::CommandBufferLevel::ePrimary, 1 ) )
.front() );
vk::CommandPool commandPool = vk::su::createCommandPool( device, graphicsAndPresentQueueFamilyIndex.first );
vk::CommandBuffer commandBuffer =
device.allocateCommandBuffers( vk::CommandBufferAllocateInfo( commandPool, vk::CommandBufferLevel::ePrimary, 1 ) )
.front();
vk::Queue graphicsQueue = device->getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
vk::Queue presentQueue = device->getQueue( graphicsAndPresentQueueFamilyIndex.second, 0 );
vk::Queue graphicsQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
vk::Queue presentQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.second, 0 );
vk::su::SwapChainData swapChainData( physicalDevice,
device,
*surfaceData.surface,
surfaceData.surface,
surfaceData.extent,
vk::ImageUsageFlagBits::eColorAttachment |
vk::ImageUsageFlagBits::eTransferDst,
vk::UniqueSwapchainKHR(),
{},
graphicsAndPresentQueueFamilyIndex.first,
graphicsAndPresentQueueFamilyIndex.second );
@@ -74,18 +73,18 @@ int main( int /*argc*/, char ** /*argv*/ )
assert( ( formatProperties.linearTilingFeatures & vk::FormatFeatureFlagBits::eBlitSrc ) &&
"Format cannot be used as transfer source" );
vk::UniqueSemaphore imageAcquiredSemaphore = device->createSemaphoreUnique( vk::SemaphoreCreateInfo() );
vk::Semaphore imageAcquiredSemaphore = device.createSemaphore( vk::SemaphoreCreateInfo() );
// Get the index of the next available swapchain image:
vk::ResultValue<uint32_t> nextImage = device->acquireNextImageKHR(
swapChainData.swapChain.get(), vk::su::FenceTimeout, imageAcquiredSemaphore.get(), nullptr );
vk::ResultValue<uint32_t> nextImage =
device.acquireNextImageKHR( swapChainData.swapChain, vk::su::FenceTimeout, imageAcquiredSemaphore, nullptr );
assert( nextImage.result == vk::Result::eSuccess );
assert( nextImage.value < swapChainData.images.size() );
uint32_t currentBuffer = nextImage.value;
uint32_t imageIndex = nextImage.value;
commandBuffer->begin( vk::CommandBufferBeginInfo() );
commandBuffer.begin( vk::CommandBufferBeginInfo() );
vk::su::setImageLayout( commandBuffer,
swapChainData.images[currentBuffer],
swapChainData.images[imageIndex],
swapChainData.colorFormat,
vk::ImageLayout::eUndefined,
vk::ImageLayout::eTransferDstOptimal );
@@ -100,37 +99,36 @@ int main( int /*argc*/, char ** /*argv*/ )
vk::SampleCountFlagBits::e1,
vk::ImageTiling::eLinear,
vk::ImageUsageFlagBits::eTransferSrc );
vk::UniqueImage blitSourceImage = device->createImageUnique( imageCreateInfo );
vk::Image blitSourceImage = device.createImage( imageCreateInfo );
vk::PhysicalDeviceMemoryProperties memoryProperties = physicalDevice.getMemoryProperties();
vk::MemoryRequirements memoryRequirements = device->getImageMemoryRequirements( blitSourceImage.get() );
vk::MemoryRequirements memoryRequirements = device.getImageMemoryRequirements( blitSourceImage );
uint32_t memoryTypeIndex = vk::su::findMemoryType(
memoryProperties, memoryRequirements.memoryTypeBits, vk::MemoryPropertyFlagBits::eHostVisible );
vk::UniqueDeviceMemory deviceMemory =
device->allocateMemoryUnique( vk::MemoryAllocateInfo( memoryRequirements.size, memoryTypeIndex ) );
device->bindImageMemory( blitSourceImage.get(), deviceMemory.get(), 0 );
vk::DeviceMemory deviceMemory =
device.allocateMemory( vk::MemoryAllocateInfo( memoryRequirements.size, memoryTypeIndex ) );
device.bindImageMemory( blitSourceImage, deviceMemory, 0 );
vk::su::setImageLayout( commandBuffer,
blitSourceImage.get(),
blitSourceImage,
swapChainData.colorFormat,
vk::ImageLayout::eUndefined,
vk::ImageLayout::eGeneral );
commandBuffer->end();
commandBuffer.end();
/* Queue the command buffer for execution */
vk::UniqueFence commandFence = device->createFenceUnique( {} );
vk::Fence commandFence = device.createFence( {} );
vk::PipelineStageFlags pipeStageFlags( vk::PipelineStageFlagBits::eColorAttachmentOutput );
graphicsQueue.submit( vk::SubmitInfo( *imageAcquiredSemaphore, pipeStageFlags, *commandBuffer ),
commandFence.get() );
graphicsQueue.submit( vk::SubmitInfo( imageAcquiredSemaphore, pipeStageFlags, commandBuffer ), commandFence );
/* Make sure command buffer is finished before mapping */
while ( device->waitForFences( commandFence.get(), true, vk::su::FenceTimeout ) == vk::Result::eTimeout )
while ( device.waitForFences( commandFence, true, vk::su::FenceTimeout ) == vk::Result::eTimeout )
;
unsigned char * pImageMemory =
static_cast<unsigned char *>( device->mapMemory( deviceMemory.get(), 0, memoryRequirements.size ) );
static_cast<unsigned char *>( device.mapMemory( deviceMemory, 0, memoryRequirements.size ) );
// Checkerboard of 8x8 pixel squares
for ( uint32_t row = 0; row < surfaceData.extent.height; row++ )
@@ -147,20 +145,20 @@ int main( int /*argc*/, char ** /*argv*/ )
}
// Flush the mapped memory and then unmap it. Assume it isn't coherent since we didn't really confirm
device->flushMappedMemoryRanges( vk::MappedMemoryRange( deviceMemory.get(), 0, memoryRequirements.size ) );
device->unmapMemory( deviceMemory.get() );
device.flushMappedMemoryRanges( vk::MappedMemoryRange( deviceMemory, 0, memoryRequirements.size ) );
device.unmapMemory( deviceMemory );
commandBuffer->reset( {} );
commandBuffer->begin( vk::CommandBufferBeginInfo() );
commandBuffer.reset( {} );
commandBuffer.begin( vk::CommandBufferBeginInfo() );
// Intend to blit from this image, set the layout accordingly
vk::su::setImageLayout( commandBuffer,
blitSourceImage.get(),
blitSourceImage,
swapChainData.colorFormat,
vk::ImageLayout::eGeneral,
vk::ImageLayout::eTransferSrcOptimal );
vk::Image blitDestinationImage = swapChainData.images[currentBuffer];
vk::Image blitDestinationImage = swapChainData.images[imageIndex];
// Do a 32x32 blit to all of the dst image - should get big squares
vk::ImageSubresourceLayers imageSubresourceLayers( vk::ImageAspectFlagBits::eColor, 0, 0, 1 );
@@ -169,12 +167,12 @@ int main( int /*argc*/, char ** /*argv*/ )
{ { vk::Offset3D( 0, 0, 0 ), vk::Offset3D( 32, 32, 1 ) } },
imageSubresourceLayers,
{ { vk::Offset3D( 0, 0, 0 ), vk::Offset3D( surfaceData.extent.width, surfaceData.extent.height, 1 ) } } );
commandBuffer->blitImage( blitSourceImage.get(),
vk::ImageLayout::eTransferSrcOptimal,
blitDestinationImage,
vk::ImageLayout::eTransferDstOptimal,
imageBlit,
vk::Filter::eLinear );
commandBuffer.blitImage( blitSourceImage,
vk::ImageLayout::eTransferSrcOptimal,
blitDestinationImage,
vk::ImageLayout::eTransferDstOptimal,
imageBlit,
vk::Filter::eLinear );
// Use a barrier to make sure the blit is finished before the copy starts
vk::ImageMemoryBarrier memoryBarrier( vk::AccessFlagBits::eTransferWrite,
@@ -185,12 +183,12 @@ int main( int /*argc*/, char ** /*argv*/ )
VK_QUEUE_FAMILY_IGNORED,
blitDestinationImage,
vk::ImageSubresourceRange( vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 ) );
commandBuffer->pipelineBarrier( vk::PipelineStageFlagBits::eTransfer,
vk::PipelineStageFlagBits::eTransfer,
vk::DependencyFlags(),
nullptr,
nullptr,
memoryBarrier );
commandBuffer.pipelineBarrier( vk::PipelineStageFlagBits::eTransfer,
vk::PipelineStageFlagBits::eTransfer,
vk::DependencyFlags(),
nullptr,
nullptr,
memoryBarrier );
// Do a image copy to part of the dst image - checks should stay small
vk::ImageCopy imageCopy( imageSubresourceLayers,
@@ -198,11 +196,11 @@ int main( int /*argc*/, char ** /*argv*/ )
imageSubresourceLayers,
vk::Offset3D( 256, 256, 0 ),
vk::Extent3D( 128, 128, 1 ) );
commandBuffer->copyImage( blitSourceImage.get(),
vk::ImageLayout::eTransferSrcOptimal,
blitDestinationImage,
vk::ImageLayout::eTransferDstOptimal,
imageCopy );
commandBuffer.copyImage( blitSourceImage,
vk::ImageLayout::eTransferSrcOptimal,
blitDestinationImage,
vk::ImageLayout::eTransferDstOptimal,
imageCopy );
vk::ImageMemoryBarrier prePresentBarrier(
vk::AccessFlagBits::eTransferWrite,
@@ -211,27 +209,26 @@ int main( int /*argc*/, char ** /*argv*/ )
vk::ImageLayout::ePresentSrcKHR,
VK_QUEUE_FAMILY_IGNORED,
VK_QUEUE_FAMILY_IGNORED,
swapChainData.images[currentBuffer],
swapChainData.images[imageIndex],
vk::ImageSubresourceRange( vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 ) );
commandBuffer->pipelineBarrier( vk::PipelineStageFlagBits::eTransfer,
vk::PipelineStageFlagBits::eTopOfPipe,
vk::DependencyFlags(),
nullptr,
nullptr,
prePresentBarrier );
commandBuffer->end();
commandBuffer.pipelineBarrier( vk::PipelineStageFlagBits::eTransfer,
vk::PipelineStageFlagBits::eTopOfPipe,
vk::DependencyFlags(),
nullptr,
nullptr,
prePresentBarrier );
commandBuffer.end();
vk::UniqueFence drawFence = device->createFenceUnique( {} );
graphicsQueue.submit( vk::SubmitInfo( {}, {}, *commandBuffer ), drawFence.get() );
vk::Fence drawFence = device.createFence( {} );
graphicsQueue.submit( vk::SubmitInfo( {}, {}, commandBuffer ), drawFence );
graphicsQueue.waitIdle();
/* Make sure command buffer is finished before presenting */
while ( device->waitForFences( drawFence.get(), true, vk::su::FenceTimeout ) == vk::Result::eTimeout )
while ( device.waitForFences( drawFence, true, vk::su::FenceTimeout ) == vk::Result::eTimeout )
;
/* Now present the image in the window */
vk::Result result =
presentQueue.presentKHR( vk::PresentInfoKHR( {}, *swapChainData.swapChain, currentBuffer, {} ) );
vk::Result result = presentQueue.presentKHR( vk::PresentInfoKHR( {}, swapChainData.swapChain, imageIndex, {} ) );
switch ( result )
{
case vk::Result::eSuccess: break;
@@ -243,6 +240,19 @@ int main( int /*argc*/, char ** /*argv*/ )
std::this_thread::sleep_for( std::chrono::milliseconds( 1000 ) );
/* VULKAN_KEY_END */
device.destroyFence( drawFence );
device.destroyFence( commandFence );
device.freeMemory( deviceMemory );
device.destroyImage( blitSourceImage );
device.destroySemaphore( imageAcquiredSemaphore );
swapChainData.clear( device );
device.freeCommandBuffers( commandPool, commandBuffer );
device.destroyCommandPool( commandPool );
device.destroy();
instance.destroySurfaceKHR( surfaceData.surface );
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -114,10 +114,10 @@ int main( int /*argc*/, char ** /*argv*/ )
std::vector<vk::ExtensionProperties> props = vk::enumerateInstanceExtensionProperties();
auto propsIterator = std::find_if( props.begin(), props.end(), []( vk::ExtensionProperties const & ep ) {
auto propertyIterator = std::find_if( props.begin(), props.end(), []( vk::ExtensionProperties const & ep ) {
return strcmp( ep.extensionName, VK_EXT_DEBUG_UTILS_EXTENSION_NAME ) == 0;
} );
if ( propsIterator == props.end() )
if ( propertyIterator == props.end() )
{
std::cout << "Something went very wrong, cannot find " << VK_EXT_DEBUG_UTILS_EXTENSION_NAME << " extension"
<< std::endl;
@@ -126,11 +126,11 @@ int main( int /*argc*/, char ** /*argv*/ )
vk::ApplicationInfo applicationInfo( AppName, 1, EngineName, 1, VK_API_VERSION_1_1 );
const char * extensionName = VK_EXT_DEBUG_UTILS_EXTENSION_NAME;
vk::UniqueInstance instance = vk::createInstanceUnique(
vk::InstanceCreateInfo( vk::InstanceCreateFlags(), &applicationInfo, {}, extensionName ) );
vk::Instance instance =
vk::createInstance( vk::InstanceCreateInfo( vk::InstanceCreateFlags(), &applicationInfo, {}, extensionName ) );
pfnVkCreateDebugUtilsMessengerEXT =
reinterpret_cast<PFN_vkCreateDebugUtilsMessengerEXT>( instance->getProcAddr( "vkCreateDebugUtilsMessengerEXT" ) );
reinterpret_cast<PFN_vkCreateDebugUtilsMessengerEXT>( instance.getProcAddr( "vkCreateDebugUtilsMessengerEXT" ) );
if ( !pfnVkCreateDebugUtilsMessengerEXT )
{
std::cout << "GetInstanceProcAddr: Unable to find pfnVkCreateDebugUtilsMessengerEXT function." << std::endl;
@@ -138,7 +138,7 @@ int main( int /*argc*/, char ** /*argv*/ )
}
pfnVkDestroyDebugUtilsMessengerEXT = reinterpret_cast<PFN_vkDestroyDebugUtilsMessengerEXT>(
instance->getProcAddr( "vkDestroyDebugUtilsMessengerEXT" ) );
instance.getProcAddr( "vkDestroyDebugUtilsMessengerEXT" ) );
if ( !pfnVkDestroyDebugUtilsMessengerEXT )
{
std::cout << "GetInstanceProcAddr: Unable to find pfnVkDestroyDebugUtilsMessengerEXT function." << std::endl;
@@ -150,9 +150,12 @@ int main( int /*argc*/, char ** /*argv*/ )
vk::DebugUtilsMessageTypeFlagsEXT messageTypeFlags( vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral |
vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance |
vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation );
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = instance->createDebugUtilsMessengerEXTUnique(
vk::DebugUtilsMessengerEXT debugUtilsMessenger = instance.createDebugUtilsMessengerEXT(
vk::DebugUtilsMessengerCreateInfoEXT( {}, severityFlags, messageTypeFlags, &debugMessageFunc ) );
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
/* VULKAN_KEY_END */
}
catch ( vk::SystemError & err )

View File

@@ -31,17 +31,18 @@ int main( int /*argc*/, char ** /*argv*/ )
{
try
{
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName );
vk::Instance instance = vk::su::createInstance( AppName, EngineName );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
std::vector<vk::PhysicalDevice> physicalDevices = instance->enumeratePhysicalDevices();
std::vector<vk::PhysicalDevice> physicalDevices = instance.enumeratePhysicalDevices();
assert( !physicalDevices.empty() );
uint32_t graphicsQueueFamilyIndex =
vk::su::findGraphicsQueueFamilyIndex( physicalDevices[0].getQueueFamilyProperties() );
vk::UniqueDevice device = vk::su::createDevice( physicalDevices[0], graphicsQueueFamilyIndex );
vk::Device device = vk::su::createDevice( physicalDevices[0], graphicsQueueFamilyIndex );
// create an image
vk::ImageCreateInfo imageCreateInfo( {},
@@ -53,15 +54,20 @@ int main( int /*argc*/, char ** /*argv*/ )
vk::SampleCountFlagBits::e1,
vk::ImageTiling::eLinear,
vk::ImageUsageFlagBits::eTransferSrc );
vk::UniqueImage image = device->createImageUnique( imageCreateInfo );
vk::Image image = device.createImage( imageCreateInfo );
/* VULKAN_KEY_START */
vk::DebugUtilsObjectNameInfoEXT debugUtilsObjectNameInfo(
vk::ObjectType::eImage, NON_DISPATCHABLE_HANDLE_TO_UINT64_CAST( VkImage, *image ), "Image name" );
device->setDebugUtilsObjectNameEXT( debugUtilsObjectNameInfo );
vk::ObjectType::eImage, NON_DISPATCHABLE_HANDLE_TO_UINT64_CAST( VkImage, image ), "Image name" );
device.setDebugUtilsObjectNameEXT( debugUtilsObjectNameInfo );
/* VULKAN_KEY_END */
device.destroyImage( image );
device.destroy();
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -32,36 +32,36 @@ int main( int /*argc*/, char ** /*argv*/ )
{
try
{
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
vk::Instance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
vk::PhysicalDevice physicalDevice = instance->enumeratePhysicalDevices().front();
vk::PhysicalDevice physicalDevice = instance.enumeratePhysicalDevices().front();
vk::su::SurfaceData surfaceData( instance, AppName, vk::Extent2D( 500, 500 ) );
std::pair<uint32_t, uint32_t> graphicsAndPresentQueueFamilyIndex =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, *surfaceData.surface );
vk::UniqueDevice device =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, surfaceData.surface );
vk::Device device =
vk::su::createDevice( physicalDevice, graphicsAndPresentQueueFamilyIndex.first, vk::su::getDeviceExtensions() );
vk::UniqueCommandPool commandPool = vk::su::createCommandPool( device, graphicsAndPresentQueueFamilyIndex.first );
vk::UniqueCommandBuffer commandBuffer = std::move( device
->allocateCommandBuffersUnique( vk::CommandBufferAllocateInfo(
commandPool.get(), vk::CommandBufferLevel::ePrimary, 1 ) )
.front() );
vk::CommandPool commandPool = vk::su::createCommandPool( device, graphicsAndPresentQueueFamilyIndex.first );
vk::CommandBuffer commandBuffer =
device.allocateCommandBuffers( vk::CommandBufferAllocateInfo( commandPool, vk::CommandBufferLevel::ePrimary, 1 ) )
.front();
vk::Queue graphicsQueue = device->getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
vk::Queue presentQueue = device->getQueue( graphicsAndPresentQueueFamilyIndex.second, 0 );
vk::Queue graphicsQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
vk::Queue presentQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.second, 0 );
vk::su::SwapChainData swapChainData( physicalDevice,
device,
*surfaceData.surface,
surfaceData.surface,
surfaceData.extent,
vk::ImageUsageFlagBits::eColorAttachment |
vk::ImageUsageFlagBits::eTransferSrc,
vk::UniqueSwapchainKHR(),
{},
graphicsAndPresentQueueFamilyIndex.first,
graphicsAndPresentQueueFamilyIndex.second );
@@ -69,34 +69,34 @@ int main( int /*argc*/, char ** /*argv*/ )
vk::su::TextureData textureData( physicalDevice, device );
commandBuffer->begin( vk::CommandBufferBeginInfo() );
commandBuffer.begin( vk::CommandBufferBeginInfo() );
textureData.setImage( device, commandBuffer, vk::su::CheckerboardImageGenerator() );
vk::su::BufferData uniformBufferData(
physicalDevice, device, sizeof( glm::mat4x4 ), vk::BufferUsageFlagBits::eUniformBuffer );
vk::su::copyToDevice(
device, uniformBufferData.deviceMemory, vk::su::createModelViewProjectionClipMatrix( surfaceData.extent ) );
glm::mat4x4 mvpcMatrix = vk::su::createModelViewProjectionClipMatrix( surfaceData.extent );
vk::su::copyToDevice( device, uniformBufferData.deviceMemory, mvpcMatrix );
vk::UniqueDescriptorSetLayout descriptorSetLayout = vk::su::createDescriptorSetLayout(
vk::DescriptorSetLayout descriptorSetLayout = vk::su::createDescriptorSetLayout(
device,
{ { vk::DescriptorType::eUniformBuffer, 1, vk::ShaderStageFlagBits::eVertex },
{ vk::DescriptorType::eCombinedImageSampler, 1, vk::ShaderStageFlagBits::eFragment } } );
vk::UniquePipelineLayout pipelineLayout = device->createPipelineLayoutUnique(
vk::PipelineLayoutCreateInfo( vk::PipelineLayoutCreateFlags(), *descriptorSetLayout ) );
vk::PipelineLayout pipelineLayout = device.createPipelineLayout(
vk::PipelineLayoutCreateInfo( vk::PipelineLayoutCreateFlags(), descriptorSetLayout ) );
vk::UniqueRenderPass renderPass = vk::su::createRenderPass(
vk::RenderPass renderPass = vk::su::createRenderPass(
device,
vk::su::pickSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( surfaceData.surface.get() ) ).format,
vk::su::pickSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( surfaceData.surface ) ).format,
depthBufferData.format );
glslang::InitializeProcess();
vk::UniqueShaderModule vertexShaderModule =
vk::ShaderModule vertexShaderModule =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eVertex, vertexShaderText_PT_T );
vk::UniqueShaderModule fragmentShaderModule =
vk::ShaderModule fragmentShaderModule =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eFragment, fragmentShaderText_T_C );
glslang::FinalizeProcess();
std::vector<vk::UniqueFramebuffer> framebuffers = vk::su::createFramebuffers(
std::vector<vk::Framebuffer> framebuffers = vk::su::createFramebuffers(
device, renderPass, swapChainData.imageViews, depthBufferData.imageView, surfaceData.extent );
vk::su::BufferData vertexBufferData(
@@ -106,21 +106,20 @@ int main( int /*argc*/, char ** /*argv*/ )
texturedCubeData,
sizeof( texturedCubeData ) / sizeof( texturedCubeData[0] ) );
vk::UniqueDescriptorPool descriptorPool = vk::su::createDescriptorPool(
vk::DescriptorPool descriptorPool = vk::su::createDescriptorPool(
device, { { vk::DescriptorType::eUniformBuffer, 1 }, { vk::DescriptorType::eCombinedImageSampler, 1 } } );
vk::UniqueDescriptorSet descriptorSet = std::move(
device->allocateDescriptorSetsUnique( vk::DescriptorSetAllocateInfo( *descriptorPool, *descriptorSetLayout ) )
.front() );
vk::DescriptorSetAllocateInfo descriptorSetAllocateInfo( descriptorPool, descriptorSetLayout );
vk::DescriptorSet descriptorSet = device.allocateDescriptorSets( descriptorSetAllocateInfo ).front();
vk::su::updateDescriptorSets(
device, descriptorSet, { { vk::DescriptorType::eUniformBuffer, uniformBufferData.buffer, {} } }, textureData );
vk::UniquePipelineCache pipelineCache = device->createPipelineCacheUnique( vk::PipelineCacheCreateInfo() );
vk::UniquePipeline graphicsPipeline =
vk::PipelineCache pipelineCache = device.createPipelineCache( vk::PipelineCacheCreateInfo() );
vk::Pipeline graphicsPipeline =
vk::su::createGraphicsPipeline( device,
pipelineCache,
std::make_pair( *vertexShaderModule, nullptr ),
std::make_pair( *fragmentShaderModule, nullptr ),
std::make_pair( vertexShaderModule, nullptr ),
std::make_pair( fragmentShaderModule, nullptr ),
sizeof( texturedCubeData[0] ),
{ { vk::Format::eR32G32B32A32Sfloat, 0 }, { vk::Format::eR32G32Sfloat, 16 } },
vk::FrontFace::eClockwise,
@@ -130,51 +129,50 @@ int main( int /*argc*/, char ** /*argv*/ )
/* VULKAN_KEY_START */
// Get the index of the next available swapchain image:
vk::UniqueSemaphore imageAcquiredSemaphore = device->createSemaphoreUnique( vk::SemaphoreCreateInfo() );
vk::ResultValue<uint32_t> currentBuffer = device->acquireNextImageKHR(
swapChainData.swapChain.get(), vk::su::FenceTimeout, imageAcquiredSemaphore.get(), nullptr );
vk::Semaphore imageAcquiredSemaphore = device.createSemaphore( vk::SemaphoreCreateInfo() );
vk::ResultValue<uint32_t> currentBuffer =
device.acquireNextImageKHR( swapChainData.swapChain, vk::su::FenceTimeout, imageAcquiredSemaphore, nullptr );
assert( currentBuffer.result == vk::Result::eSuccess );
assert( currentBuffer.value < framebuffers.size() );
// commandBuffer->begin() has already been called above!
// commandBuffer.begin() has already been called above!
std::array<vk::ClearValue, 2> clearValues;
clearValues[0].color = vk::ClearColorValue( std::array<float, 4>( { { 0.2f, 0.2f, 0.2f, 0.2f } } ) );
clearValues[1].depthStencil = vk::ClearDepthStencilValue( 1.0f, 0 );
vk::RenderPassBeginInfo renderPassBeginInfo( renderPass.get(),
framebuffers[currentBuffer.value].get(),
vk::RenderPassBeginInfo renderPassBeginInfo( renderPass,
framebuffers[currentBuffer.value],
vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ),
clearValues );
commandBuffer->beginRenderPass( renderPassBeginInfo, vk::SubpassContents::eInline );
commandBuffer->bindPipeline( vk::PipelineBindPoint::eGraphics, graphicsPipeline.get() );
commandBuffer->bindDescriptorSets(
vk::PipelineBindPoint::eGraphics, pipelineLayout.get(), 0, descriptorSet.get(), nullptr );
commandBuffer.beginRenderPass( renderPassBeginInfo, vk::SubpassContents::eInline );
commandBuffer.bindPipeline( vk::PipelineBindPoint::eGraphics, graphicsPipeline );
commandBuffer.bindDescriptorSets( vk::PipelineBindPoint::eGraphics, pipelineLayout, 0, descriptorSet, nullptr );
commandBuffer->bindVertexBuffers( 0, *vertexBufferData.buffer, { 0 } );
commandBuffer->setViewport( 0,
vk::Viewport( 0.0f,
0.0f,
static_cast<float>( surfaceData.extent.width ),
static_cast<float>( surfaceData.extent.height ),
0.0f,
1.0f ) );
commandBuffer->setScissor( 0, vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ) );
commandBuffer.bindVertexBuffers( 0, vertexBufferData.buffer, { 0 } );
commandBuffer.setViewport( 0,
vk::Viewport( 0.0f,
0.0f,
static_cast<float>( surfaceData.extent.width ),
static_cast<float>( surfaceData.extent.height ),
0.0f,
1.0f ) );
commandBuffer.setScissor( 0, vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ) );
commandBuffer->draw( 12 * 3, 1, 0, 0 );
commandBuffer->endRenderPass();
commandBuffer->end();
commandBuffer.draw( 12 * 3, 1, 0, 0 );
commandBuffer.endRenderPass();
commandBuffer.end();
vk::UniqueFence drawFence = device->createFenceUnique( vk::FenceCreateInfo() );
vk::Fence drawFence = device.createFence( vk::FenceCreateInfo() );
vk::PipelineStageFlags waitDestinationStageMask( vk::PipelineStageFlagBits::eColorAttachmentOutput );
vk::SubmitInfo submitInfo( *imageAcquiredSemaphore, waitDestinationStageMask, *commandBuffer );
graphicsQueue.submit( submitInfo, drawFence.get() );
vk::SubmitInfo submitInfo( imageAcquiredSemaphore, waitDestinationStageMask, commandBuffer );
graphicsQueue.submit( submitInfo, drawFence );
while ( vk::Result::eTimeout == device->waitForFences( drawFence.get(), VK_TRUE, vk::su::FenceTimeout ) )
while ( vk::Result::eTimeout == device.waitForFences( drawFence, VK_TRUE, vk::su::FenceTimeout ) )
;
vk::Result result =
presentQueue.presentKHR( vk::PresentInfoKHR( {}, *swapChainData.swapChain, currentBuffer.value ) );
presentQueue.presentKHR( vk::PresentInfoKHR( {}, swapChainData.swapChain, currentBuffer.value ) );
switch ( result )
{
case vk::Result::eSuccess: break;
@@ -187,7 +185,34 @@ int main( int /*argc*/, char ** /*argv*/ )
/* VULKAN_KEY_END */
device->waitIdle();
device.waitIdle();
device.destroyFence( drawFence );
device.destroySemaphore( imageAcquiredSemaphore );
device.destroyPipeline( graphicsPipeline );
device.destroyPipelineCache( pipelineCache );
device.freeDescriptorSets( descriptorPool, descriptorSet );
device.destroyDescriptorPool( descriptorPool );
vertexBufferData.clear( device );
for ( auto framebuffer : framebuffers )
{
device.destroyFramebuffer( framebuffer );
}
device.destroyShaderModule( fragmentShaderModule );
device.destroyShaderModule( vertexShaderModule );
device.destroyRenderPass( renderPass );
device.destroyPipelineLayout( pipelineLayout );
device.destroyDescriptorSetLayout( descriptorSetLayout );
uniformBufferData.clear( device );
textureData.clear( device );
depthBufferData.clear( device );
swapChainData.clear( device );
device.freeCommandBuffers( commandPool, commandBuffer );
device.destroyCommandPool( commandPool );
device.destroy();
instance.destroySurfaceKHR( surfaceData.surface );
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -43,54 +43,54 @@ int main( int /*argc*/, char ** /*argv*/ )
{
try
{
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
vk::Instance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
vk::PhysicalDevice physicalDevice = instance->enumeratePhysicalDevices().front();
vk::PhysicalDevice physicalDevice = instance.enumeratePhysicalDevices().front();
vk::su::SurfaceData surfaceData( instance, AppName, vk::Extent2D( 500, 500 ) );
std::pair<uint32_t, uint32_t> graphicsAndPresentQueueFamilyIndex =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, *surfaceData.surface );
vk::UniqueDevice device =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, surfaceData.surface );
vk::Device device =
vk::su::createDevice( physicalDevice, graphicsAndPresentQueueFamilyIndex.first, vk::su::getDeviceExtensions() );
vk::UniqueCommandPool commandPool = vk::su::createCommandPool( device, graphicsAndPresentQueueFamilyIndex.first );
vk::UniqueCommandBuffer commandBuffer = std::move( device
->allocateCommandBuffersUnique( vk::CommandBufferAllocateInfo(
commandPool.get(), vk::CommandBufferLevel::ePrimary, 1 ) )
.front() );
vk::CommandPool commandPool = vk::su::createCommandPool( device, graphicsAndPresentQueueFamilyIndex.first );
vk::CommandBuffer commandBuffer =
device.allocateCommandBuffers( vk::CommandBufferAllocateInfo( commandPool, vk::CommandBufferLevel::ePrimary, 1 ) )
.front();
vk::Queue graphicsQueue = device->getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
vk::Queue presentQueue = device->getQueue( graphicsAndPresentQueueFamilyIndex.second, 0 );
vk::Queue graphicsQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
vk::Queue presentQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.second, 0 );
vk::su::SwapChainData swapChainData( physicalDevice,
device,
*surfaceData.surface,
surfaceData.surface,
surfaceData.extent,
vk::ImageUsageFlagBits::eColorAttachment |
vk::ImageUsageFlagBits::eTransferSrc,
vk::UniqueSwapchainKHR(),
{},
graphicsAndPresentQueueFamilyIndex.first,
graphicsAndPresentQueueFamilyIndex.second );
vk::su::DepthBufferData depthBufferData( physicalDevice, device, vk::Format::eD16Unorm, surfaceData.extent );
vk::UniqueRenderPass renderPass = vk::su::createRenderPass(
vk::RenderPass renderPass = vk::su::createRenderPass(
device,
vk::su::pickSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( surfaceData.surface.get() ) ).format,
vk::su::pickSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( surfaceData.surface ) ).format,
depthBufferData.format );
glslang::InitializeProcess();
vk::UniqueShaderModule vertexShaderModule =
vk::ShaderModule vertexShaderModule =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eVertex, vertexShaderText_PC_C );
vk::UniqueShaderModule fragmentShaderModule =
vk::ShaderModule fragmentShaderModule =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eFragment, fragmentShaderText_C_C );
glslang::FinalizeProcess();
std::vector<vk::UniqueFramebuffer> framebuffers = vk::su::createFramebuffers(
std::vector<vk::Framebuffer> framebuffers = vk::su::createFramebuffers(
device, renderPass, swapChainData.imageViews, depthBufferData.imageView, surfaceData.extent );
vk::su::BufferData vertexBufferData(
@@ -115,23 +115,13 @@ int main( int /*argc*/, char ** /*argv*/ )
glm::mat4x4 view =
glm::lookAt( glm::vec3( 0.0f, 3.0f, -10.0f ), glm::vec3( 0.0f, 0.0f, 0.0f ), glm::vec3( 0.0f, -1.0f, 0.0f ) );
glm::mat4x4 projection = glm::perspective( glm::radians( 45.0f ), 1.0f, 0.1f, 100.0f );
glm::mat4x4 clip = glm::mat4x4( 1.0f,
0.0f,
0.0f,
0.0f,
0.0f,
-1.0f,
0.0f,
0.0f,
0.0f,
0.0f,
0.5f,
0.0f,
0.0f,
0.0f,
0.5f,
1.0f ); // vulkan clip space has inverted y and half z !
mvpcs[0] = clip * projection * view * model;
// clang-format off
glm::mat4x4 clip = glm::mat4x4( 1.0f, 0.0f, 0.0f, 0.0f,
0.0f, -1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.5f, 0.0f,
0.0f, 0.0f, 0.5f, 1.0f ); // vulkan clip space has inverted y and half z !
// clang-format on
mvpcs[0] = clip * projection * view * model;
model = glm::translate( model, glm::vec3( -1.5f, 1.5f, -1.5f ) );
mvpcs[1] = clip * projection * view * model;
@@ -148,27 +138,26 @@ int main( int /*argc*/, char ** /*argv*/ )
vk::su::copyToDevice( device, uniformBufferData.deviceMemory, mvpcs, 2, bufferSize );
// create a DescriptorSetLayout with vk::DescriptorType::eUniformBufferDynamic
vk::UniqueDescriptorSetLayout descriptorSetLayout = vk::su::createDescriptorSetLayout(
vk::DescriptorSetLayout descriptorSetLayout = vk::su::createDescriptorSetLayout(
device, { { vk::DescriptorType::eUniformBufferDynamic, 1, vk::ShaderStageFlagBits::eVertex } } );
vk::UniquePipelineLayout pipelineLayout = device->createPipelineLayoutUnique(
vk::PipelineLayoutCreateInfo( vk::PipelineLayoutCreateFlags(), *descriptorSetLayout ) );
vk::PipelineLayout pipelineLayout = device.createPipelineLayout(
vk::PipelineLayoutCreateInfo( vk::PipelineLayoutCreateFlags(), descriptorSetLayout ) );
// create a DescriptorPool with vk::DescriptorType::eUniformBufferDynamic
vk::UniqueDescriptorPool descriptorPool =
vk::DescriptorPool descriptorPool =
vk::su::createDescriptorPool( device, { { vk::DescriptorType::eUniformBufferDynamic, 1 } } );
vk::UniqueDescriptorSet descriptorSet = std::move(
device->allocateDescriptorSetsUnique( vk::DescriptorSetAllocateInfo( *descriptorPool, *descriptorSetLayout ) )
.front() );
vk::DescriptorSetAllocateInfo descriptorSetAllocateInfo( descriptorPool, descriptorSetLayout );
vk::DescriptorSet descriptorSet = device.allocateDescriptorSets( descriptorSetAllocateInfo ).front();
vk::su::updateDescriptorSets(
device, descriptorSet, { { vk::DescriptorType::eUniformBufferDynamic, uniformBufferData.buffer, {} } }, {} );
vk::UniquePipelineCache pipelineCache = device->createPipelineCacheUnique( vk::PipelineCacheCreateInfo() );
vk::UniquePipeline graphicsPipeline = vk::su::createGraphicsPipeline(
vk::PipelineCache pipelineCache = device.createPipelineCache( vk::PipelineCacheCreateInfo() );
vk::Pipeline graphicsPipeline = vk::su::createGraphicsPipeline(
device,
pipelineCache,
std::make_pair( *vertexShaderModule, nullptr ),
std::make_pair( *fragmentShaderModule, nullptr ),
std::make_pair( vertexShaderModule, nullptr ),
std::make_pair( fragmentShaderModule, nullptr ),
sizeof( coloredCubeData[0] ),
{ { vk::Format::eR32G32B32A32Sfloat, 0 }, { vk::Format::eR32G32B32A32Sfloat, 16 } },
vk::FrontFace::eClockwise,
@@ -176,61 +165,61 @@ int main( int /*argc*/, char ** /*argv*/ )
pipelineLayout,
renderPass );
// Get the index of the next available swapchain image:
vk::UniqueSemaphore imageAcquiredSemaphore = device->createSemaphoreUnique( vk::SemaphoreCreateInfo() );
vk::ResultValue<uint32_t> currentBuffer = device->acquireNextImageKHR(
swapChainData.swapChain.get(), vk::su::FenceTimeout, imageAcquiredSemaphore.get(), nullptr );
vk::Semaphore imageAcquiredSemaphore = device.createSemaphore( vk::SemaphoreCreateInfo() );
vk::ResultValue<uint32_t> currentBuffer =
device.acquireNextImageKHR( swapChainData.swapChain, vk::su::FenceTimeout, imageAcquiredSemaphore, nullptr );
assert( currentBuffer.result == vk::Result::eSuccess );
assert( currentBuffer.value < framebuffers.size() );
commandBuffer->begin( vk::CommandBufferBeginInfo( vk::CommandBufferUsageFlags() ) );
commandBuffer.begin( vk::CommandBufferBeginInfo( vk::CommandBufferUsageFlags() ) );
std::array<vk::ClearValue, 2> clearValues;
clearValues[0].color = vk::ClearColorValue( std::array<float, 4>( { { 0.2f, 0.2f, 0.2f, 0.2f } } ) );
clearValues[1].depthStencil = vk::ClearDepthStencilValue( 1.0f, 0 );
vk::RenderPassBeginInfo renderPassBeginInfo( renderPass.get(),
framebuffers[currentBuffer.value].get(),
vk::RenderPassBeginInfo renderPassBeginInfo( renderPass,
framebuffers[currentBuffer.value],
vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ),
clearValues );
commandBuffer->beginRenderPass( renderPassBeginInfo, vk::SubpassContents::eInline );
commandBuffer->bindPipeline( vk::PipelineBindPoint::eGraphics, graphicsPipeline.get() );
commandBuffer.beginRenderPass( renderPassBeginInfo, vk::SubpassContents::eInline );
commandBuffer.bindPipeline( vk::PipelineBindPoint::eGraphics, graphicsPipeline );
commandBuffer->setViewport( 0,
vk::Viewport( 0.0f,
0.0f,
static_cast<float>( surfaceData.extent.width ),
static_cast<float>( surfaceData.extent.height ),
0.0f,
1.0f ) );
commandBuffer->setScissor( 0, vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ) );
commandBuffer.setViewport( 0,
vk::Viewport( 0.0f,
0.0f,
static_cast<float>( surfaceData.extent.width ),
static_cast<float>( surfaceData.extent.height ),
0.0f,
1.0f ) );
commandBuffer.setScissor( 0, vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ) );
/* The first draw should use the first matrix in the buffer */
uint32_t dynamicOffset = 0;
commandBuffer->bindDescriptorSets(
vk::PipelineBindPoint::eGraphics, pipelineLayout.get(), 0, descriptorSet.get(), dynamicOffset );
commandBuffer.bindDescriptorSets(
vk::PipelineBindPoint::eGraphics, pipelineLayout, 0, descriptorSet, dynamicOffset );
commandBuffer->bindVertexBuffers( 0, *vertexBufferData.buffer, { 0 } );
commandBuffer->draw( 12 * 3, 1, 0, 0 );
commandBuffer.bindVertexBuffers( 0, vertexBufferData.buffer, { 0 } );
commandBuffer.draw( 12 * 3, 1, 0, 0 );
// the second draw should use the second matrix in the buffer;
dynamicOffset = (uint32_t)bufferSize;
commandBuffer->bindDescriptorSets(
vk::PipelineBindPoint::eGraphics, pipelineLayout.get(), 0, descriptorSet.get(), dynamicOffset );
commandBuffer->draw( 12 * 3, 1, 0, 0 );
commandBuffer.bindDescriptorSets(
vk::PipelineBindPoint::eGraphics, pipelineLayout, 0, descriptorSet, dynamicOffset );
commandBuffer.draw( 12 * 3, 1, 0, 0 );
commandBuffer->endRenderPass();
commandBuffer->end();
commandBuffer.endRenderPass();
commandBuffer.end();
vk::UniqueFence drawFence = device->createFenceUnique( vk::FenceCreateInfo() );
vk::Fence drawFence = device.createFence( vk::FenceCreateInfo() );
vk::PipelineStageFlags waitDestinationStageMask( vk::PipelineStageFlagBits::eColorAttachmentOutput );
vk::SubmitInfo submitInfo( *imageAcquiredSemaphore, waitDestinationStageMask, *commandBuffer );
graphicsQueue.submit( submitInfo, drawFence.get() );
vk::SubmitInfo submitInfo( imageAcquiredSemaphore, waitDestinationStageMask, commandBuffer );
graphicsQueue.submit( submitInfo, drawFence );
while ( vk::Result::eTimeout == device->waitForFences( drawFence.get(), VK_TRUE, vk::su::FenceTimeout ) )
while ( vk::Result::eTimeout == device.waitForFences( drawFence, VK_TRUE, vk::su::FenceTimeout ) )
;
vk::Result result =
presentQueue.presentKHR( vk::PresentInfoKHR( {}, *swapChainData.swapChain, currentBuffer.value ) );
presentQueue.presentKHR( vk::PresentInfoKHR( {}, swapChainData.swapChain, currentBuffer.value ) );
switch ( result )
{
case vk::Result::eSuccess: break;
@@ -243,7 +232,33 @@ int main( int /*argc*/, char ** /*argv*/ )
/* VULKAN_KEY_END */
device->waitIdle();
device.waitIdle();
device.destroyFence( drawFence );
device.destroySemaphore( imageAcquiredSemaphore );
device.destroyPipeline( graphicsPipeline );
device.destroyPipelineCache( pipelineCache );
device.freeDescriptorSets( descriptorPool, descriptorSet );
device.destroyDescriptorPool( descriptorPool );
device.destroyPipelineLayout( pipelineLayout );
device.destroyDescriptorSetLayout( descriptorSetLayout );
uniformBufferData.clear( device );
vertexBufferData.clear( device );
for ( auto framebuffer : framebuffers )
{
device.destroyFramebuffer( framebuffer );
}
device.destroyShaderModule( fragmentShaderModule );
device.destroyShaderModule( vertexShaderModule );
device.destroyRenderPass( renderPass );
depthBufferData.clear( device );
swapChainData.clear( device );
device.freeCommandBuffers( commandPool, commandBuffer );
device.destroyCommandPool( commandPool );
device.destroy();
instance.destroySurfaceKHR( surfaceData.surface );
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -148,15 +148,15 @@ int main( int /*argc*/, char ** /*argv*/ )
vk::ApplicationInfo applicationInfo( AppName, 1, EngineName, 1, VK_API_VERSION_1_1 );
vk::InstanceCreateInfo instanceCreateInfo(
vk::InstanceCreateFlags(), &applicationInfo, instanceLayerNames, instanceExtensionNames );
vk::UniqueInstance instance = vk::createInstanceUnique( instanceCreateInfo );
vk::Instance instance = vk::createInstance( instanceCreateInfo );
#if ( VULKAN_HPP_DISPATCH_LOADER_DYNAMIC == 1 )
// initialize function pointers for instance
VULKAN_HPP_DEFAULT_DISPATCHER.init( *instance );
VULKAN_HPP_DEFAULT_DISPATCHER.init( instance );
#endif
pfnVkCreateDebugUtilsMessengerEXT =
reinterpret_cast<PFN_vkCreateDebugUtilsMessengerEXT>( instance->getProcAddr( "vkCreateDebugUtilsMessengerEXT" ) );
reinterpret_cast<PFN_vkCreateDebugUtilsMessengerEXT>( instance.getProcAddr( "vkCreateDebugUtilsMessengerEXT" ) );
if ( !pfnVkCreateDebugUtilsMessengerEXT )
{
std::cout << "GetInstanceProcAddr: Unable to find pfnVkCreateDebugUtilsMessengerEXT function." << std::endl;
@@ -164,7 +164,7 @@ int main( int /*argc*/, char ** /*argv*/ )
}
pfnVkDestroyDebugUtilsMessengerEXT = reinterpret_cast<PFN_vkDestroyDebugUtilsMessengerEXT>(
instance->getProcAddr( "vkDestroyDebugUtilsMessengerEXT" ) );
instance.getProcAddr( "vkDestroyDebugUtilsMessengerEXT" ) );
if ( !pfnVkDestroyDebugUtilsMessengerEXT )
{
std::cout << "GetInstanceProcAddr: Unable to find pfnVkDestroyDebugUtilsMessengerEXT function." << std::endl;
@@ -176,35 +176,37 @@ int main( int /*argc*/, char ** /*argv*/ )
vk::DebugUtilsMessageTypeFlagsEXT messageTypeFlags( vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral |
vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance |
vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation );
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = instance->createDebugUtilsMessengerEXTUnique(
vk::DebugUtilsMessengerEXT debugUtilsMessenger = instance.createDebugUtilsMessengerEXT(
vk::DebugUtilsMessengerCreateInfoEXT( {}, severityFlags, messageTypeFlags, &debugMessageFunc ) );
vk::PhysicalDevice physicalDevice = instance->enumeratePhysicalDevices().front();
vk::PhysicalDevice physicalDevice = instance.enumeratePhysicalDevices().front();
std::vector<vk::QueueFamilyProperties> queueFamilyProperties = physicalDevice.getQueueFamilyProperties();
assert( !queueFamilyProperties.empty() );
auto qfpIt = std::find_if(
queueFamilyProperties.begin(), queueFamilyProperties.end(), []( vk::QueueFamilyProperties const & qfp ) {
return !!( qfp.queueFlags & vk::QueueFlagBits::eGraphics );
} );
assert( qfpIt != queueFamilyProperties.end() );
uint32_t queueFamilyIndex = static_cast<uint32_t>( std::distance( queueFamilyProperties.begin(), qfpIt ) );
// get the index of the first queue family that supports graphics
uint32_t graphicsQueueFamilyIndex =
vk::su::findGraphicsQueueFamilyIndex( physicalDevice.getQueueFamilyProperties() );
float queuePriority = 0.0f;
vk::DeviceQueueCreateInfo deviceQueueCreateInfo(
vk::DeviceQueueCreateFlags(), queueFamilyIndex, 1, &queuePriority );
vk::UniqueDevice device =
physicalDevice.createDeviceUnique( vk::DeviceCreateInfo( vk::DeviceCreateFlags(), deviceQueueCreateInfo ) );
vk::DeviceQueueCreateFlags(), graphicsQueueFamilyIndex, 1, &queuePriority );
vk::Device device =
physicalDevice.createDevice( vk::DeviceCreateInfo( vk::DeviceCreateFlags(), deviceQueueCreateInfo ) );
// Create a command pool (not a UniqueCommandPool, for testing purposes!
// Create a CommandPool and don't destroy it, for testing purposes!
vk::CommandPool commandPool =
device->createCommandPool( vk::CommandPoolCreateInfo( vk::CommandPoolCreateFlags(), queueFamilyIndex ) );
device.createCommandPool( vk::CommandPoolCreateInfo( vk::CommandPoolCreateFlags(), graphicsQueueFamilyIndex ) );
// The commandPool is not destroyed automatically (as it's not a UniqueCommandPool.
#if true
// The commandPool is not destroyed automatically
// That is, the device is destroyed before the commmand pool and will trigger a validation error.
std::cout << "*** INTENTIONALLY calling vkDestroyDevice before destroying command pool ***\n";
std::cout << "*** INTENTIONALLY destroying the Device before destroying a CommandPool ***\n";
std::cout << "*** The following error message is EXPECTED ***\n";
#else
device.destroyCommandPool( commandPool );
#endif
device.destroy();
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
/* VULKAN_KEY_END */
}

View File

@@ -28,15 +28,16 @@ int main( int /*argc*/, char ** /*argv*/ )
{
try
{
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName );
vk::Instance instance = vk::su::createInstance( AppName, EngineName );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
/* VULKAN_HPP_KEY_START */
// enumerate the physicalDevices
std::vector<vk::PhysicalDevice> physicalDevices = instance->enumeratePhysicalDevices();
std::vector<vk::PhysicalDevice> physicalDevices = instance.enumeratePhysicalDevices();
for ( auto const & physicalDevice : physicalDevices )
{
@@ -63,6 +64,9 @@ int main( int /*argc*/, char ** /*argv*/ )
}
/* VULKAN_HPP_KEY_END */
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -27,43 +27,43 @@ int main( int /*argc*/, char ** /*argv*/ )
{
try
{
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
vk::Instance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
vk::PhysicalDevice physicalDevice = instance->enumeratePhysicalDevices().front();
vk::PhysicalDevice physicalDevice = instance.enumeratePhysicalDevices().front();
uint32_t graphicsQueueFamilyIndex =
vk::su::findGraphicsQueueFamilyIndex( physicalDevice.getQueueFamilyProperties() );
vk::UniqueDevice device = vk::su::createDevice( physicalDevice, graphicsQueueFamilyIndex );
vk::Device device = vk::su::createDevice( physicalDevice, graphicsQueueFamilyIndex );
vk::UniqueCommandPool commandPool = vk::su::createCommandPool( device, graphicsQueueFamilyIndex );
vk::UniqueCommandBuffer commandBuffer = std::move( device
->allocateCommandBuffersUnique( vk::CommandBufferAllocateInfo(
commandPool.get(), vk::CommandBufferLevel::ePrimary, 1 ) )
.front() );
vk::CommandPool commandPool = vk::su::createCommandPool( device, graphicsQueueFamilyIndex );
vk::CommandBuffer commandBuffer =
device.allocateCommandBuffers( vk::CommandBufferAllocateInfo( commandPool, vk::CommandBufferLevel::ePrimary, 1 ) )
.front();
vk::Queue graphicsQueue = device->getQueue( graphicsQueueFamilyIndex, 0 );
vk::Queue graphicsQueue = device.getQueue( graphicsQueueFamilyIndex, 0 );
/* VULKAN_KEY_START */
// Start with a trivial command buffer and make sure fence wait doesn't time out
commandBuffer->begin( vk::CommandBufferBeginInfo( vk::CommandBufferUsageFlags() ) );
commandBuffer->setViewport( 0, vk::Viewport( 0.0f, 0.0f, 10.0f, 10.0f, 0.0f, 1.0f ) );
commandBuffer->end();
commandBuffer.begin( vk::CommandBufferBeginInfo( vk::CommandBufferUsageFlags() ) );
commandBuffer.setViewport( 0, vk::Viewport( 0.0f, 0.0f, 10.0f, 10.0f, 0.0f, 1.0f ) );
commandBuffer.end();
vk::UniqueFence fence = device->createFenceUnique( vk::FenceCreateInfo() );
vk::Fence fence = device.createFence( vk::FenceCreateInfo() );
vk::SubmitInfo submitInfo( {}, {}, *commandBuffer );
graphicsQueue.submit( submitInfo, fence.get() );
vk::SubmitInfo submitInfo( {}, {}, commandBuffer );
graphicsQueue.submit( submitInfo, fence );
// Make sure timeout is long enough for a simple command buffer without waiting for an event
vk::Result result;
int timeouts = -1;
do
{
result = device->waitForFences( fence.get(), true, vk::su::FenceTimeout );
result = device.waitForFences( fence, true, vk::su::FenceTimeout );
timeouts++;
} while ( result == vk::Result::eTimeout );
assert( result == vk::Result::eSuccess );
@@ -74,25 +74,21 @@ int main( int /*argc*/, char ** /*argv*/ )
}
// Now create an event and wait for it on the GPU
vk::UniqueEvent event = device->createEventUnique( vk::EventCreateInfo( vk::EventCreateFlags() ) );
vk::Event event = device.createEvent( vk::EventCreateInfo( vk::EventCreateFlags() ) );
commandBuffer->reset( vk::CommandBufferResetFlags() );
commandBuffer->begin( vk::CommandBufferBeginInfo() );
commandBuffer->waitEvents( event.get(),
vk::PipelineStageFlagBits::eHost,
vk::PipelineStageFlagBits::eBottomOfPipe,
nullptr,
nullptr,
nullptr );
commandBuffer->end();
device->resetFences( fence.get() );
commandBuffer.reset( vk::CommandBufferResetFlags() );
commandBuffer.begin( vk::CommandBufferBeginInfo() );
commandBuffer.waitEvents(
event, vk::PipelineStageFlagBits::eHost, vk::PipelineStageFlagBits::eBottomOfPipe, nullptr, nullptr, nullptr );
commandBuffer.end();
device.resetFences( fence );
// Note that stepping through this code in the debugger is a bad idea because the GPU can TDR waiting for the event.
// Execute the code from vk::Queue::submit() through vk::Device::setEvent() without breakpoints
graphicsQueue.submit( submitInfo, fence.get() );
graphicsQueue.submit( submitInfo, fence );
// We should timeout waiting for the fence because the GPU should be waiting on the event
result = device->waitForFences( fence.get(), true, vk::su::FenceTimeout );
result = device.waitForFences( fence, true, vk::su::FenceTimeout );
if ( result != vk::Result::eTimeout )
{
std::cout << "Didn't get expected timeout in vk::Device::waitForFences, exiting\n";
@@ -101,44 +97,53 @@ int main( int /*argc*/, char ** /*argv*/ )
// Set the event from the CPU and wait for the fence.
// This should succeed since we set the event
device->setEvent( event.get() );
device.setEvent( event );
do
{
result = device->waitForFences( fence.get(), true, vk::su::FenceTimeout );
result = device.waitForFences( fence, true, vk::su::FenceTimeout );
} while ( result == vk::Result::eTimeout );
assert( result == vk::Result::eSuccess );
commandBuffer->reset( {} );
device->resetFences( fence.get() );
device->resetEvent( event.get() );
commandBuffer.reset( {} );
device.resetFences( fence );
device.resetEvent( event );
// Now set the event from the GPU and wait on the CPU
commandBuffer->begin( vk::CommandBufferBeginInfo() );
commandBuffer->setEvent( event.get(), vk::PipelineStageFlagBits::eBottomOfPipe );
commandBuffer->end();
commandBuffer.begin( vk::CommandBufferBeginInfo() );
commandBuffer.setEvent( event, vk::PipelineStageFlagBits::eBottomOfPipe );
commandBuffer.end();
// Look for the event on the CPU. It should be vk::Result::eEventReset since we haven't sent the command buffer yet.
result = device->getEventStatus( event.get() );
result = device.getEventStatus( event );
assert( result == vk::Result::eEventReset );
// Send the command buffer and loop waiting for the event
graphicsQueue.submit( submitInfo, fence.get() );
graphicsQueue.submit( submitInfo, fence );
int polls = 0;
do
{
result = device->getEventStatus( event.get() );
result = device.getEventStatus( event );
polls++;
} while ( result != vk::Result::eEventSet );
printf( "%d polls to find the event set\n", polls );
do
{
result = device->waitForFences( fence.get(), true, vk::su::FenceTimeout );
result = device.waitForFences( fence, true, vk::su::FenceTimeout );
} while ( result == vk::Result::eTimeout );
assert( result == vk::Result::eSuccess );
device.destroyEvent( event );
device.destroyFence( fence );
/* VULKAN_KEY_END */
device.freeCommandBuffers( commandPool, commandBuffer );
device.destroyCommandPool( commandPool );
device.destroy();
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -41,36 +41,36 @@ int main( int /*argc*/, char ** /*argv*/ )
{
try
{
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
vk::Instance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
vk::PhysicalDevice physicalDevice = instance->enumeratePhysicalDevices().front();
vk::PhysicalDevice physicalDevice = instance.enumeratePhysicalDevices().front();
vk::su::SurfaceData surfaceData( instance, AppName, vk::Extent2D( 500, 500 ) );
std::pair<uint32_t, uint32_t> graphicsAndPresentQueueFamilyIndex =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, *surfaceData.surface );
vk::UniqueDevice device =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, surfaceData.surface );
vk::Device device =
vk::su::createDevice( physicalDevice, graphicsAndPresentQueueFamilyIndex.first, vk::su::getDeviceExtensions() );
vk::UniqueCommandPool commandPool = vk::su::createCommandPool( device, graphicsAndPresentQueueFamilyIndex.first );
vk::UniqueCommandBuffer commandBuffer = std::move( device
->allocateCommandBuffersUnique( vk::CommandBufferAllocateInfo(
commandPool.get(), vk::CommandBufferLevel::ePrimary, 1 ) )
.front() );
vk::CommandPool commandPool = vk::su::createCommandPool( device, graphicsAndPresentQueueFamilyIndex.first );
vk::CommandBuffer commandBuffer =
device.allocateCommandBuffers( vk::CommandBufferAllocateInfo( commandPool, vk::CommandBufferLevel::ePrimary, 1 ) )
.front();
vk::Queue graphicsQueue = device->getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
vk::Queue presentQueue = device->getQueue( graphicsAndPresentQueueFamilyIndex.second, 0 );
vk::Queue graphicsQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
vk::Queue presentQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.second, 0 );
vk::su::SwapChainData swapChainData( physicalDevice,
device,
*surfaceData.surface,
surfaceData.surface,
surfaceData.extent,
vk::ImageUsageFlagBits::eColorAttachment |
vk::ImageUsageFlagBits::eTransferSrc,
vk::UniqueSwapchainKHR(),
{},
graphicsAndPresentQueueFamilyIndex.first,
graphicsAndPresentQueueFamilyIndex.second );
@@ -78,22 +78,22 @@ int main( int /*argc*/, char ** /*argv*/ )
vk::su::BufferData uniformBufferData(
physicalDevice, device, sizeof( glm::mat4x4 ), vk::BufferUsageFlagBits::eUniformBuffer );
vk::su::copyToDevice(
device, uniformBufferData.deviceMemory, vk::su::createModelViewProjectionClipMatrix( surfaceData.extent ) );
glm::mat4x4 mvpcMatrix = vk::su::createModelViewProjectionClipMatrix( surfaceData.extent );
vk::su::copyToDevice( device, uniformBufferData.deviceMemory, mvpcMatrix );
vk::UniqueRenderPass renderPass = vk::su::createRenderPass(
vk::RenderPass renderPass = vk::su::createRenderPass(
device,
vk::su::pickSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( surfaceData.surface.get() ) ).format,
vk::su::pickSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( surfaceData.surface ) ).format,
depthBufferData.format );
glslang::InitializeProcess();
vk::UniqueShaderModule vertexShaderModule =
vk::ShaderModule vertexShaderModule =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eVertex, vertexShaderText_PT_T );
vk::UniqueShaderModule fragmentShaderModule =
vk::ShaderModule fragmentShaderModule =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eFragment, fragmentShaderText_T_C );
glslang::FinalizeProcess();
std::vector<vk::UniqueFramebuffer> framebuffers = vk::su::createFramebuffers(
std::vector<vk::Framebuffer> framebuffers = vk::su::createFramebuffers(
device, renderPass, swapChainData.imageViews, depthBufferData.imageView, surfaceData.extent );
vk::su::BufferData vertexBufferData(
@@ -107,51 +107,49 @@ int main( int /*argc*/, char ** /*argv*/ )
vk::su::TextureData textureData( physicalDevice, device );
commandBuffer->begin( vk::CommandBufferBeginInfo() );
commandBuffer.begin( vk::CommandBufferBeginInfo() );
textureData.setImage( device, commandBuffer, vk::su::CheckerboardImageGenerator() );
std::array<vk::DescriptorSetLayoutBinding, 2> bindings = {
vk::DescriptorSetLayoutBinding( 0, vk::DescriptorType::eUniformBuffer, 1, vk::ShaderStageFlagBits::eVertex ),
vk::DescriptorSetLayoutBinding(
1, vk::DescriptorType::eCombinedImageSampler, vk::ShaderStageFlagBits::eFragment, *textureData.textureSampler )
1, vk::DescriptorType::eCombinedImageSampler, vk::ShaderStageFlagBits::eFragment, textureData.sampler )
};
vk::UniqueDescriptorSetLayout descriptorSetLayout = device->createDescriptorSetLayoutUnique(
vk::DescriptorSetLayout descriptorSetLayout = device.createDescriptorSetLayout(
vk::DescriptorSetLayoutCreateInfo( vk::DescriptorSetLayoutCreateFlags(), bindings ) );
// Create pipeline layout
vk::UniquePipelineLayout pipelineLayout = device->createPipelineLayoutUnique(
vk::PipelineLayoutCreateInfo( vk::PipelineLayoutCreateFlags(), *descriptorSetLayout ) );
vk::PipelineLayout pipelineLayout = device.createPipelineLayout(
vk::PipelineLayoutCreateInfo( vk::PipelineLayoutCreateFlags(), descriptorSetLayout ) );
// Create a single pool to contain data for our descriptor set
std::array<vk::DescriptorPoolSize, 2> poolSizes = { vk::DescriptorPoolSize( vk::DescriptorType::eUniformBuffer, 1 ),
vk::DescriptorPoolSize(
vk::DescriptorType::eCombinedImageSampler, 1 ) };
vk::UniqueDescriptorPool descriptorPool = device->createDescriptorPoolUnique(
vk::DescriptorPool descriptorPool = device.createDescriptorPool(
vk::DescriptorPoolCreateInfo( vk::DescriptorPoolCreateFlagBits::eFreeDescriptorSet, 1, poolSizes ) );
// Populate descriptor sets
vk::UniqueDescriptorSet descriptorSet = std::move(
device->allocateDescriptorSetsUnique( vk::DescriptorSetAllocateInfo( *descriptorPool, *descriptorSetLayout ) )
.front() );
vk::DescriptorSetAllocateInfo descriptorSetAllocateInfo( descriptorPool, descriptorSetLayout );
vk::DescriptorSet descriptorSet = device.allocateDescriptorSets( descriptorSetAllocateInfo ).front();
vk::DescriptorBufferInfo bufferInfo( uniformBufferData.buffer.get(), 0, sizeof( glm::mat4x4 ) );
vk::DescriptorImageInfo imageInfo( textureData.textureSampler.get(),
textureData.imageData->imageView.get(),
vk::ImageLayout::eShaderReadOnlyOptimal );
vk::WriteDescriptorSet writeDescriptorSets[2] = {
vk::WriteDescriptorSet( descriptorSet.get(), 0, 0, vk::DescriptorType::eUniformBuffer, {}, bufferInfo ),
vk::WriteDescriptorSet( descriptorSet.get(), 1, 0, vk::DescriptorType::eCombinedImageSampler, imageInfo )
vk::DescriptorBufferInfo bufferInfo( uniformBufferData.buffer, 0, sizeof( glm::mat4x4 ) );
vk::DescriptorImageInfo imageInfo(
textureData.sampler, textureData.imageData->imageView, vk::ImageLayout::eShaderReadOnlyOptimal );
std::array<vk::WriteDescriptorSet, 2> writeDescriptorSets = {
vk::WriteDescriptorSet( descriptorSet, 0, 0, vk::DescriptorType::eUniformBuffer, {}, bufferInfo ),
vk::WriteDescriptorSet( descriptorSet, 1, 0, vk::DescriptorType::eCombinedImageSampler, imageInfo )
};
device->updateDescriptorSets( vk::ArrayProxy<const vk::WriteDescriptorSet>( 2, writeDescriptorSets ), nullptr );
device.updateDescriptorSets( writeDescriptorSets, nullptr );
/* VULKAN_KEY_END */
vk::UniquePipelineCache pipelineCache = device->createPipelineCacheUnique( vk::PipelineCacheCreateInfo() );
vk::UniquePipeline graphicsPipeline =
vk::PipelineCache pipelineCache = device.createPipelineCache( vk::PipelineCacheCreateInfo() );
vk::Pipeline graphicsPipeline =
vk::su::createGraphicsPipeline( device,
pipelineCache,
std::make_pair( *vertexShaderModule, nullptr ),
std::make_pair( *fragmentShaderModule, nullptr ),
std::make_pair( vertexShaderModule, nullptr ),
std::make_pair( fragmentShaderModule, nullptr ),
sizeof( texturedCubeData[0] ),
{ { vk::Format::eR32G32B32A32Sfloat, 0 }, { vk::Format::eR32G32Sfloat, 16 } },
vk::FrontFace::eClockwise,
@@ -159,42 +157,41 @@ int main( int /*argc*/, char ** /*argv*/ )
pipelineLayout,
renderPass );
vk::UniqueSemaphore imageAcquiredSemaphore = device->createSemaphoreUnique( vk::SemaphoreCreateInfo() );
vk::ResultValue<uint32_t> currentBuffer = device->acquireNextImageKHR(
swapChainData.swapChain.get(), vk::su::FenceTimeout, imageAcquiredSemaphore.get(), nullptr );
vk::Semaphore imageAcquiredSemaphore = device.createSemaphore( vk::SemaphoreCreateInfo() );
vk::ResultValue<uint32_t> currentBuffer =
device.acquireNextImageKHR( swapChainData.swapChain, vk::su::FenceTimeout, imageAcquiredSemaphore, nullptr );
assert( currentBuffer.result == vk::Result::eSuccess );
assert( currentBuffer.value < framebuffers.size() );
std::array<vk::ClearValue, 2> clearValues;
clearValues[0].color = vk::ClearColorValue( std::array<float, 4>( { { 0.2f, 0.2f, 0.2f, 0.2f } } ) );
clearValues[1].depthStencil = vk::ClearDepthStencilValue( 1.0f, 0 );
vk::RenderPassBeginInfo renderPassBeginInfo( renderPass.get(),
framebuffers[currentBuffer.value].get(),
vk::RenderPassBeginInfo renderPassBeginInfo( renderPass,
framebuffers[currentBuffer.value],
vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ),
clearValues );
commandBuffer->beginRenderPass( renderPassBeginInfo, vk::SubpassContents::eInline );
commandBuffer->bindPipeline( vk::PipelineBindPoint::eGraphics, graphicsPipeline.get() );
commandBuffer->bindDescriptorSets(
vk::PipelineBindPoint::eGraphics, pipelineLayout.get(), 0, descriptorSet.get(), nullptr );
commandBuffer.beginRenderPass( renderPassBeginInfo, vk::SubpassContents::eInline );
commandBuffer.bindPipeline( vk::PipelineBindPoint::eGraphics, graphicsPipeline );
commandBuffer.bindDescriptorSets( vk::PipelineBindPoint::eGraphics, pipelineLayout, 0, descriptorSet, nullptr );
commandBuffer->bindVertexBuffers( 0, *vertexBufferData.buffer, { 0 } );
commandBuffer->setViewport( 0,
vk::Viewport( 0.0f,
0.0f,
static_cast<float>( surfaceData.extent.width ),
static_cast<float>( surfaceData.extent.height ),
0.0f,
1.0f ) );
commandBuffer->setScissor( 0, vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ) );
commandBuffer.bindVertexBuffers( 0, vertexBufferData.buffer, { 0 } );
commandBuffer.setViewport( 0,
vk::Viewport( 0.0f,
0.0f,
static_cast<float>( surfaceData.extent.width ),
static_cast<float>( surfaceData.extent.height ),
0.0f,
1.0f ) );
commandBuffer.setScissor( 0, vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ) );
commandBuffer->draw( 12 * 3, 1, 0, 0 );
commandBuffer->endRenderPass();
commandBuffer->end();
commandBuffer.draw( 12 * 3, 1, 0, 0 );
commandBuffer.endRenderPass();
commandBuffer.end();
vk::su::submitAndWait( device, graphicsQueue, commandBuffer );
vk::Result result =
presentQueue.presentKHR( vk::PresentInfoKHR( {}, *swapChainData.swapChain, currentBuffer.value ) );
presentQueue.presentKHR( vk::PresentInfoKHR( {}, swapChainData.swapChain, currentBuffer.value ) );
switch ( result )
{
case vk::Result::eSuccess: break;
@@ -205,7 +202,33 @@ int main( int /*argc*/, char ** /*argv*/ )
}
std::this_thread::sleep_for( std::chrono::milliseconds( 1000 ) );
device->waitIdle();
device.waitIdle();
device.destroySemaphore( imageAcquiredSemaphore );
device.destroyPipeline( graphicsPipeline );
device.destroyPipelineCache( pipelineCache );
device.freeDescriptorSets( descriptorPool, descriptorSet );
device.destroyDescriptorPool( descriptorPool );
device.destroyDescriptorSetLayout( descriptorSetLayout );
textureData.clear( device );
vertexBufferData.clear( device );
for ( auto framebuffer : framebuffers )
{
device.destroyFramebuffer( framebuffer );
}
device.destroyShaderModule( fragmentShaderModule );
device.destroyShaderModule( vertexShaderModule );
device.destroyPipelineLayout( pipelineLayout );
device.destroyRenderPass( renderPass );
uniformBufferData.clear( device );
depthBufferData.clear( device );
swapChainData.clear( device );
device.freeCommandBuffers( commandPool, commandBuffer );
device.destroyCommandPool( commandPool );
device.destroy();
instance.destroySurfaceKHR( surfaceData.surface );
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -41,28 +41,28 @@ int main( int /*argc*/, char ** /*argv*/ )
{
try
{
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
vk::Instance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
vk::PhysicalDevice physicalDevice = instance->enumeratePhysicalDevices().front();
vk::PhysicalDevice physicalDevice = instance.enumeratePhysicalDevices().front();
vk::su::SurfaceData surfaceData( instance, AppName, vk::Extent2D( 50, 50 ) );
std::pair<uint32_t, uint32_t> graphicsAndPresentQueueFamilyIndex =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, *surfaceData.surface );
vk::UniqueDevice device =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, surfaceData.surface );
vk::Device device =
vk::su::createDevice( physicalDevice, graphicsAndPresentQueueFamilyIndex.first, vk::su::getDeviceExtensions() );
vk::UniqueCommandPool commandPool = vk::su::createCommandPool( device, graphicsAndPresentQueueFamilyIndex.first );
vk::UniqueCommandBuffer commandBuffer = std::move( device
->allocateCommandBuffersUnique( vk::CommandBufferAllocateInfo(
commandPool.get(), vk::CommandBufferLevel::ePrimary, 1 ) )
.front() );
vk::CommandPool commandPool = vk::su::createCommandPool( device, graphicsAndPresentQueueFamilyIndex.first );
vk::CommandBuffer commandBuffer =
device.allocateCommandBuffers( vk::CommandBufferAllocateInfo( commandPool, vk::CommandBufferLevel::ePrimary, 1 ) )
.front();
vk::Queue graphicsQueue = device->getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
vk::Queue presentQueue = device->getQueue( graphicsAndPresentQueueFamilyIndex.second, 0 );
vk::Queue graphicsQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
vk::Queue presentQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.second, 0 );
/* VULKAN_KEY_START */
@@ -72,66 +72,66 @@ int main( int /*argc*/, char ** /*argv*/ )
// See if we can use a linear tiled image for a texture, if not, we will need a staging buffer for the texture data
bool needsStaging = !( formatProperties.linearTilingFeatures & vk::FormatFeatureFlagBits::eSampledImage );
vk::UniqueImage image = device->createImageUnique(
vk::ImageCreateInfo( vk::ImageCreateFlags(),
vk::ImageType::e2D,
format,
vk::Extent3D( surfaceData.extent, 1 ),
1,
1,
vk::SampleCountFlagBits::e1,
needsStaging ? vk::ImageTiling::eOptimal : vk::ImageTiling::eLinear,
vk::ImageUsageFlagBits::eSampled |
( needsStaging ? vk::ImageUsageFlagBits::eTransferDst : vk::ImageUsageFlagBits() ),
vk::SharingMode::eExclusive,
{},
needsStaging ? vk::ImageLayout::eUndefined : vk::ImageLayout::ePreinitialized ) );
vk::ImageCreateInfo imageCreateInfo(
vk::ImageCreateFlags(),
vk::ImageType::e2D,
format,
vk::Extent3D( surfaceData.extent, 1 ),
1,
1,
vk::SampleCountFlagBits::e1,
needsStaging ? vk::ImageTiling::eOptimal : vk::ImageTiling::eLinear,
vk::ImageUsageFlagBits::eSampled |
( needsStaging ? vk::ImageUsageFlagBits::eTransferDst : vk::ImageUsageFlagBits() ),
vk::SharingMode::eExclusive,
{},
needsStaging ? vk::ImageLayout::eUndefined : vk::ImageLayout::ePreinitialized );
vk::Image image = device.createImage( imageCreateInfo );
vk::MemoryRequirements memoryRequirements = device->getImageMemoryRequirements( image.get() );
vk::MemoryRequirements memoryRequirements = device.getImageMemoryRequirements( image );
uint32_t memoryTypeIndex = vk::su::findMemoryType(
physicalDevice.getMemoryProperties(),
memoryRequirements.memoryTypeBits,
needsStaging ? vk::MemoryPropertyFlags()
: ( vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent ) );
: ( vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent ) );
// allocate memory
vk::UniqueDeviceMemory imageMemory =
device->allocateMemoryUnique( vk::MemoryAllocateInfo( memoryRequirements.size, memoryTypeIndex ) );
vk::DeviceMemory imageMemory =
device.allocateMemory( vk::MemoryAllocateInfo( memoryRequirements.size, memoryTypeIndex ) );
// bind memory
device->bindImageMemory( image.get(), imageMemory.get(), 0 );
device.bindImageMemory( image, imageMemory, 0 );
vk::UniqueBuffer textureBuffer;
vk::UniqueDeviceMemory textureBufferMemory;
vk::Buffer textureBuffer;
vk::DeviceMemory textureBufferMemory;
if ( needsStaging )
{
// Need a staging buffer to map and copy texture into
textureBuffer =
device->createBufferUnique( vk::BufferCreateInfo( vk::BufferCreateFlags(),
surfaceData.extent.width * surfaceData.extent.height * 4,
vk::BufferUsageFlagBits::eTransferSrc ) );
device.createBuffer( vk::BufferCreateInfo( vk::BufferCreateFlags(),
surfaceData.extent.width * surfaceData.extent.height * 4,
vk::BufferUsageFlagBits::eTransferSrc ) );
memoryRequirements = device->getBufferMemoryRequirements( textureBuffer.get() );
memoryRequirements = device.getBufferMemoryRequirements( textureBuffer );
memoryTypeIndex =
vk::su::findMemoryType( physicalDevice.getMemoryProperties(),
memoryRequirements.memoryTypeBits,
vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent );
// allocate memory
textureBufferMemory =
device->allocateMemoryUnique( vk::MemoryAllocateInfo( memoryRequirements.size, memoryTypeIndex ) );
textureBufferMemory = device.allocateMemory( vk::MemoryAllocateInfo( memoryRequirements.size, memoryTypeIndex ) );
// bind memory
device->bindBufferMemory( textureBuffer.get(), textureBufferMemory.get(), 0 );
device.bindBufferMemory( textureBuffer, textureBufferMemory, 0 );
}
else
{
vk::SubresourceLayout subresourceLayout =
device->getImageSubresourceLayout( image.get(), vk::ImageSubresource( vk::ImageAspectFlagBits::eColor ) );
device.getImageSubresourceLayout( image, vk::ImageSubresource( vk::ImageAspectFlagBits::eColor ) );
}
void * data = device->mapMemory(
needsStaging ? textureBufferMemory.get() : imageMemory.get(), 0, memoryRequirements.size, vk::MemoryMapFlags() );
void * data = device.mapMemory(
needsStaging ? textureBufferMemory : imageMemory, 0, memoryRequirements.size, vk::MemoryMapFlags() );
// Checkerboard of 16x16 pixel squares
unsigned char * pImageMemory = static_cast<unsigned char *>( data );
@@ -148,68 +148,73 @@ int main( int /*argc*/, char ** /*argv*/ )
}
}
device->unmapMemory( needsStaging ? textureBufferMemory.get() : imageMemory.get() );
device.unmapMemory( needsStaging ? textureBufferMemory : imageMemory );
commandBuffer->begin( vk::CommandBufferBeginInfo() );
commandBuffer.begin( vk::CommandBufferBeginInfo() );
if ( needsStaging )
{
// Since we're going to blit to the texture image, set its layout to eTransferDstOptimal
vk::su::setImageLayout(
commandBuffer, image.get(), format, vk::ImageLayout::eUndefined, vk::ImageLayout::eTransferDstOptimal );
commandBuffer, image, format, vk::ImageLayout::eUndefined, vk::ImageLayout::eTransferDstOptimal );
vk::BufferImageCopy copyRegion( 0,
surfaceData.extent.width,
surfaceData.extent.height,
vk::ImageSubresourceLayers( vk::ImageAspectFlagBits::eColor, 0, 0, 1 ),
vk::Offset3D( 0, 0, 0 ),
vk::Extent3D( surfaceData.extent, 1 ) );
commandBuffer->copyBufferToImage(
textureBuffer.get(), image.get(), vk::ImageLayout::eTransferDstOptimal, copyRegion );
commandBuffer.copyBufferToImage( textureBuffer, image, vk::ImageLayout::eTransferDstOptimal, copyRegion );
// Set the layout for the texture image from eTransferDstOptimal to SHADER_READ_ONLY
vk::su::setImageLayout( commandBuffer,
image.get(),
format,
vk::ImageLayout::eTransferDstOptimal,
vk::ImageLayout::eShaderReadOnlyOptimal );
vk::su::setImageLayout(
commandBuffer, image, format, vk::ImageLayout::eTransferDstOptimal, vk::ImageLayout::eShaderReadOnlyOptimal );
}
else
{
// If we can use the linear tiled image as a texture, just do it
vk::su::setImageLayout(
commandBuffer, image.get(), format, vk::ImageLayout::ePreinitialized, vk::ImageLayout::eShaderReadOnlyOptimal );
commandBuffer, image, format, vk::ImageLayout::ePreinitialized, vk::ImageLayout::eShaderReadOnlyOptimal );
}
commandBuffer->end();
commandBuffer.end();
vk::su::submitAndWait( device, graphicsQueue, commandBuffer );
vk::UniqueSampler sampler =
device->createSamplerUnique( vk::SamplerCreateInfo( vk::SamplerCreateFlags(),
vk::Filter::eNearest,
vk::Filter::eNearest,
vk::SamplerMipmapMode::eNearest,
vk::SamplerAddressMode::eClampToEdge,
vk::SamplerAddressMode::eClampToEdge,
vk::SamplerAddressMode::eClampToEdge,
0.0f,
false,
1.0f,
false,
vk::CompareOp::eNever,
0.0f,
0.0f,
vk::BorderColor::eFloatOpaqueWhite ) );
vk::SamplerCreateInfo samplerCreateInfo( vk::SamplerCreateFlags(),
vk::Filter::eNearest,
vk::Filter::eNearest,
vk::SamplerMipmapMode::eNearest,
vk::SamplerAddressMode::eClampToEdge,
vk::SamplerAddressMode::eClampToEdge,
vk::SamplerAddressMode::eClampToEdge,
0.0f,
false,
1.0f,
false,
vk::CompareOp::eNever,
0.0f,
0.0f,
vk::BorderColor::eFloatOpaqueWhite );
vk::Sampler sampler = device.createSampler( samplerCreateInfo );
vk::ComponentMapping componentMapping(
vk::ComponentSwizzle::eR, vk::ComponentSwizzle::eG, vk::ComponentSwizzle::eB, vk::ComponentSwizzle::eA );
vk::ImageViewCreateInfo imageViewCreateInfo(
vk::ImageViewCreateFlags(),
image.get(),
vk::ImageViewType::e2D,
format,
componentMapping,
vk::ImageSubresourceRange( vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 ) );
vk::UniqueImageView imageView = device->createImageViewUnique( imageViewCreateInfo );
vk::ImageSubresourceRange imageSubresourceRange( vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 );
vk::ImageViewCreateInfo imageViewCreateInfo(
{}, image, vk::ImageViewType::e2D, format, componentMapping, imageSubresourceRange );
vk::ImageView imageView = device.createImageView( imageViewCreateInfo );
/* VULKAN_KEY_END */
device.destroyImageView( imageView );
device.destroySampler( sampler );
device.freeMemory( textureBufferMemory );
device.destroyBuffer( textureBuffer );
device.freeMemory( imageMemory );
device.destroyImage( image );
device.freeCommandBuffers( commandPool, commandBuffer );
device.destroyCommandPool( commandPool );
device.destroy();
instance.destroySurfaceKHR( surfaceData.surface );
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -70,12 +70,13 @@ int main( int /*argc*/, char ** /*argv*/ )
{
try
{
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
vk::Instance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
vk::PhysicalDevice physicalDevice = instance->enumeratePhysicalDevices().front();
vk::PhysicalDevice physicalDevice = instance.enumeratePhysicalDevices().front();
vk::FormatProperties formatProperties = physicalDevice.getFormatProperties( vk::Format::eR8G8B8A8Unorm );
if ( !( formatProperties.optimalTilingFeatures & vk::FormatFeatureFlagBits::eColorAttachment ) )
@@ -87,26 +88,25 @@ int main( int /*argc*/, char ** /*argv*/ )
vk::su::SurfaceData surfaceData( instance, AppName, vk::Extent2D( 500, 500 ) );
std::pair<uint32_t, uint32_t> graphicsAndPresentQueueFamilyIndex =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, *surfaceData.surface );
vk::UniqueDevice device =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, surfaceData.surface );
vk::Device device =
vk::su::createDevice( physicalDevice, graphicsAndPresentQueueFamilyIndex.first, vk::su::getDeviceExtensions() );
vk::UniqueCommandPool commandPool = vk::su::createCommandPool( device, graphicsAndPresentQueueFamilyIndex.first );
vk::UniqueCommandBuffer commandBuffer = std::move( device
->allocateCommandBuffersUnique( vk::CommandBufferAllocateInfo(
commandPool.get(), vk::CommandBufferLevel::ePrimary, 1 ) )
.front() );
vk::CommandPool commandPool = vk::su::createCommandPool( device, graphicsAndPresentQueueFamilyIndex.first );
vk::CommandBuffer commandBuffer =
device.allocateCommandBuffers( vk::CommandBufferAllocateInfo( commandPool, vk::CommandBufferLevel::ePrimary, 1 ) )
.front();
vk::Queue graphicsQueue = device->getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
vk::Queue presentQueue = device->getQueue( graphicsAndPresentQueueFamilyIndex.second, 0 );
vk::Queue graphicsQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
vk::Queue presentQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.second, 0 );
vk::su::SwapChainData swapChainData( physicalDevice,
device,
*surfaceData.surface,
surfaceData.surface,
surfaceData.extent,
vk::ImageUsageFlagBits::eColorAttachment |
vk::ImageUsageFlagBits::eTransferSrc,
vk::UniqueSwapchainKHR(),
{},
graphicsAndPresentQueueFamilyIndex.first,
graphicsAndPresentQueueFamilyIndex.second );
@@ -118,34 +118,35 @@ int main( int /*argc*/, char ** /*argv*/ )
// Create the image that will be used as the input attachment
// The image for the color attachment is the presentable image already created as part of the SwapChainData
vk::UniqueImage inputImage = device->createImageUnique(
vk::ImageCreateInfo( vk::ImageCreateFlags(),
vk::ImageType::e2D,
swapChainData.colorFormat,
vk::Extent3D( surfaceData.extent, 1 ),
1,
1,
vk::SampleCountFlagBits::e1,
vk::ImageTiling::eOptimal,
vk::ImageUsageFlagBits::eInputAttachment | vk::ImageUsageFlagBits::eTransferDst ) );
vk::ImageCreateInfo imageCreateInfo( vk::ImageCreateFlags(),
vk::ImageType::e2D,
swapChainData.colorFormat,
vk::Extent3D( surfaceData.extent, 1 ),
1,
1,
vk::SampleCountFlagBits::e1,
vk::ImageTiling::eOptimal,
vk::ImageUsageFlagBits::eInputAttachment |
vk::ImageUsageFlagBits::eTransferDst );
vk::Image inputImage = device.createImage( imageCreateInfo );
vk::MemoryRequirements memoryRequirements = device->getImageMemoryRequirements( inputImage.get() );
vk::MemoryRequirements memoryRequirements = device.getImageMemoryRequirements( inputImage );
uint32_t memoryTypeIndex = vk::su::findMemoryType(
physicalDevice.getMemoryProperties(), memoryRequirements.memoryTypeBits, vk::MemoryPropertyFlags() );
vk::UniqueDeviceMemory inputMemory =
device->allocateMemoryUnique( vk::MemoryAllocateInfo( memoryRequirements.size, memoryTypeIndex ) );
device->bindImageMemory( inputImage.get(), inputMemory.get(), 0 );
vk::DeviceMemory inputMemory =
device.allocateMemory( vk::MemoryAllocateInfo( memoryRequirements.size, memoryTypeIndex ) );
device.bindImageMemory( inputImage, inputMemory, 0 );
// Set the image layout to TRANSFER_DST_OPTIMAL to be ready for clear
commandBuffer->begin( vk::CommandBufferBeginInfo() );
commandBuffer.begin( vk::CommandBufferBeginInfo() );
vk::su::setImageLayout( commandBuffer,
inputImage.get(),
inputImage,
swapChainData.colorFormat,
vk::ImageLayout::eUndefined,
vk::ImageLayout::eTransferDstOptimal );
commandBuffer->clearColorImage(
inputImage.get(),
commandBuffer.clearColorImage(
inputImage,
vk::ImageLayout::eTransferDstOptimal,
vk::ClearColorValue( std::array<float, 4>( { { 1.0f, 1.0f, 0.0f, 0.0f } } ) ),
vk::ImageSubresourceRange(
@@ -153,29 +154,25 @@ int main( int /*argc*/, char ** /*argv*/ )
// Set the image layout to SHADER_READONLY_OPTIMAL for use by the shaders
vk::su::setImageLayout( commandBuffer,
inputImage.get(),
inputImage,
swapChainData.colorFormat,
vk::ImageLayout::eTransferDstOptimal,
vk::ImageLayout::eShaderReadOnlyOptimal );
vk::ComponentMapping componentMapping(
vk::ComponentSwizzle::eR, vk::ComponentSwizzle::eG, vk::ComponentSwizzle::eB, vk::ComponentSwizzle::eA );
vk::ImageViewCreateInfo imageViewCreateInfo(
vk::ImageViewCreateFlags(),
inputImage.get(),
vk::ImageViewType::e2D,
swapChainData.colorFormat,
componentMapping,
vk::ImageSubresourceRange( vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 ) );
vk::UniqueImageView inputAttachmentView = device->createImageViewUnique( imageViewCreateInfo );
vk::ImageSubresourceRange imageSubresourceRange( vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 );
vk::ImageViewCreateInfo imageViewCreateInfo(
{}, inputImage, vk::ImageViewType::e2D, swapChainData.colorFormat, componentMapping, imageSubresourceRange );
vk::ImageView inputAttachmentView = device.createImageView( imageViewCreateInfo );
vk::DescriptorSetLayoutBinding layoutBinding(
0, vk::DescriptorType::eInputAttachment, 1, vk::ShaderStageFlagBits::eFragment );
vk::UniqueDescriptorSetLayout descriptorSetLayout = device->createDescriptorSetLayoutUnique(
vk::DescriptorSetLayout descriptorSetLayout = device.createDescriptorSetLayout(
vk::DescriptorSetLayoutCreateInfo( vk::DescriptorSetLayoutCreateFlags(), layoutBinding ) );
vk::UniquePipelineLayout pipelineLayout = device->createPipelineLayoutUnique(
vk::PipelineLayoutCreateInfo( vk::PipelineLayoutCreateFlags(), *descriptorSetLayout ) );
vk::PipelineLayout pipelineLayout = device.createPipelineLayout(
vk::PipelineLayoutCreateInfo( vk::PipelineLayoutCreateFlags(), descriptorSetLayout ) );
std::array<vk::AttachmentDescription, 2> attachments = {
// First attachment is the color attachment - clear at the beginning of the renderpass and transition layout to
@@ -206,82 +203,77 @@ int main( int /*argc*/, char ** /*argv*/ )
vk::AttachmentReference inputReference( 1, vk::ImageLayout::eShaderReadOnlyOptimal );
vk::SubpassDescription subPass(
vk::SubpassDescriptionFlags(), vk::PipelineBindPoint::eGraphics, inputReference, colorReference );
vk::UniqueRenderPass renderPass =
device->createRenderPassUnique( vk::RenderPassCreateInfo( vk::RenderPassCreateFlags(), attachments, subPass ) );
vk::RenderPass renderPass =
device.createRenderPass( vk::RenderPassCreateInfo( vk::RenderPassCreateFlags(), attachments, subPass ) );
glslang::InitializeProcess();
vk::UniqueShaderModule vertexShaderModule =
vk::ShaderModule vertexShaderModule =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eVertex, vertexShaderText );
vk::UniqueShaderModule fragmentShaderModule =
vk::ShaderModule fragmentShaderModule =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eFragment, fragmentShaderText );
glslang::FinalizeProcess();
std::vector<vk::UniqueFramebuffer> framebuffers = vk::su::createFramebuffers(
std::vector<vk::Framebuffer> framebuffers = vk::su::createFramebuffers(
device, renderPass, swapChainData.imageViews, inputAttachmentView, surfaceData.extent );
vk::DescriptorPoolSize poolSize( vk::DescriptorType::eInputAttachment, 1 );
vk::UniqueDescriptorPool descriptorPool = device->createDescriptorPoolUnique(
vk::DescriptorPoolSize poolSize( vk::DescriptorType::eInputAttachment, 1 );
vk::DescriptorPool descriptorPool = device.createDescriptorPool(
vk::DescriptorPoolCreateInfo( vk::DescriptorPoolCreateFlagBits::eFreeDescriptorSet, 1, poolSize ) );
vk::UniqueDescriptorSet descriptorSet = std::move(
device->allocateDescriptorSetsUnique( vk::DescriptorSetAllocateInfo( *descriptorPool, *descriptorSetLayout ) )
.front() );
vk::DescriptorSetAllocateInfo descriptorSetAllocateInfo( descriptorPool, descriptorSetLayout );
vk::DescriptorSet descriptorSet = device.allocateDescriptorSets( descriptorSetAllocateInfo ).front();
vk::DescriptorImageInfo inputImageInfo(
nullptr, inputAttachmentView.get(), vk::ImageLayout::eShaderReadOnlyOptimal );
vk::WriteDescriptorSet writeDescriptorSet(
descriptorSet.get(), 0, 0, vk::DescriptorType::eInputAttachment, inputImageInfo );
device->updateDescriptorSets( vk::ArrayProxy<const vk::WriteDescriptorSet>( 1, &writeDescriptorSet ), nullptr );
vk::DescriptorImageInfo inputImageInfo( nullptr, inputAttachmentView, vk::ImageLayout::eShaderReadOnlyOptimal );
vk::WriteDescriptorSet writeDescriptorSet(
descriptorSet, 0, 0, vk::DescriptorType::eInputAttachment, inputImageInfo );
device.updateDescriptorSets( writeDescriptorSet, nullptr );
vk::UniquePipelineCache pipelineCache = device->createPipelineCacheUnique( vk::PipelineCacheCreateInfo() );
vk::UniquePipeline graphicsPipeline =
vk::su::createGraphicsPipeline( device,
pipelineCache,
std::make_pair( *vertexShaderModule, nullptr ),
std::make_pair( *fragmentShaderModule, nullptr ),
0,
{},
vk::FrontFace::eClockwise,
false,
pipelineLayout,
renderPass );
vk::PipelineCache pipelineCache = device.createPipelineCache( vk::PipelineCacheCreateInfo() );
vk::Pipeline graphicsPipeline = vk::su::createGraphicsPipeline( device,
pipelineCache,
std::make_pair( vertexShaderModule, nullptr ),
std::make_pair( fragmentShaderModule, nullptr ),
0,
{},
vk::FrontFace::eClockwise,
false,
pipelineLayout,
renderPass );
vk::UniqueSemaphore imageAcquiredSemaphore = device->createSemaphoreUnique( vk::SemaphoreCreateInfo() );
vk::Semaphore imageAcquiredSemaphore = device.createSemaphore( vk::SemaphoreCreateInfo() );
vk::ResultValue<uint32_t> nexImage = device->acquireNextImage2KHR(
vk::AcquireNextImageInfoKHR( swapChainData.swapChain.get(), UINT64_MAX, imageAcquiredSemaphore.get(), {}, 1 ) );
vk::ResultValue<uint32_t> nexImage = device.acquireNextImage2KHR(
vk::AcquireNextImageInfoKHR( swapChainData.swapChain, UINT64_MAX, imageAcquiredSemaphore, {}, 1 ) );
assert( nexImage.result == vk::Result::eSuccess );
uint32_t currentBuffer = nexImage.value;
vk::ClearValue clearValue;
clearValue.color = vk::ClearColorValue( std::array<float, 4>( { { 0.2f, 0.2f, 0.2f, 0.2f } } ) );
commandBuffer->beginRenderPass( vk::RenderPassBeginInfo( renderPass.get(),
framebuffers[currentBuffer].get(),
vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ),
clearValue ),
vk::SubpassContents::eInline );
commandBuffer->bindPipeline( vk::PipelineBindPoint::eGraphics, graphicsPipeline.get() );
commandBuffer->bindDescriptorSets(
vk::PipelineBindPoint::eGraphics, pipelineLayout.get(), 0, descriptorSet.get(), nullptr );
commandBuffer.beginRenderPass(
vk::RenderPassBeginInfo(
renderPass, framebuffers[currentBuffer], vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ), clearValue ),
vk::SubpassContents::eInline );
commandBuffer.bindPipeline( vk::PipelineBindPoint::eGraphics, graphicsPipeline );
commandBuffer.bindDescriptorSets( vk::PipelineBindPoint::eGraphics, pipelineLayout, 0, descriptorSet, nullptr );
commandBuffer->setViewport( 0,
vk::Viewport( 0.0f,
0.0f,
static_cast<float>( surfaceData.extent.width ),
static_cast<float>( surfaceData.extent.height ),
0.0f,
1.0f ) );
commandBuffer->setScissor( 0, vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ) );
commandBuffer.setViewport( 0,
vk::Viewport( 0.0f,
0.0f,
static_cast<float>( surfaceData.extent.width ),
static_cast<float>( surfaceData.extent.height ),
0.0f,
1.0f ) );
commandBuffer.setScissor( 0, vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ) );
commandBuffer->draw( 3, 1, 0, 0 );
commandBuffer->endRenderPass();
commandBuffer->end();
commandBuffer.draw( 3, 1, 0, 0 );
commandBuffer.endRenderPass();
commandBuffer.end();
/* VULKAN_KEY_END */
vk::su::submitAndWait( device, graphicsQueue, commandBuffer );
vk::Result result = presentQueue.presentKHR( vk::PresentInfoKHR( {}, *swapChainData.swapChain, currentBuffer ) );
vk::Result result = presentQueue.presentKHR( vk::PresentInfoKHR( {}, swapChainData.swapChain, currentBuffer ) );
switch ( result )
{
case vk::Result::eSuccess: break;
@@ -291,6 +283,31 @@ int main( int /*argc*/, char ** /*argv*/ )
default: assert( false ); // an unexpected result is returned !
}
std::this_thread::sleep_for( std::chrono::milliseconds( 1000 ) );
device.destroySemaphore( imageAcquiredSemaphore );
device.destroyPipeline( graphicsPipeline );
device.destroyPipelineCache( pipelineCache );
device.freeDescriptorSets( descriptorPool, descriptorSet );
device.destroyDescriptorPool( descriptorPool );
for ( auto framebuffer : framebuffers )
{
device.destroyFramebuffer( framebuffer );
}
device.destroyShaderModule( fragmentShaderModule );
device.destroyShaderModule( vertexShaderModule );
device.destroyRenderPass( renderPass );
device.destroyPipelineLayout( pipelineLayout );
device.destroyDescriptorSetLayout( descriptorSetLayout );
device.destroyImageView( inputAttachmentView );
device.freeMemory( inputMemory );
device.destroyImage( inputImage );
swapChainData.clear( device );
device.freeCommandBuffers( commandPool, commandBuffer );
device.destroyCommandPool( commandPool );
device.destroy();
instance.destroySurfaceKHR( surfaceData.surface );
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -47,7 +47,7 @@ int main( int /*argc*/, char ** /*argv*/ )
{
std::vector<vk::ExtensionProperties> extensionProperties =
vk::enumerateInstanceExtensionProperties( vk::Optional<const std::string>( layerProperty.layerName ) );
propertyData.push_back( PropertyData( layerProperty, extensionProperties ) );
propertyData.emplace_back( layerProperty, extensionProperties );
}
/* VULKAN_KEY_END */
@@ -62,9 +62,10 @@ int main( int /*argc*/, char ** /*argv*/ )
for ( auto const & pd : propertyData )
{
std::cout << pd.layerProperties.layerName << std::endl;
std::cout << "Layer Extensions: ";
if ( pd.extensionProperties.empty() )
{
std::cout << "Layer Extension: None";
std::cout << "None";
}
else
{

View File

@@ -33,7 +33,7 @@ int main( int /*argc*/, char ** /*argv*/ )
/* VULKAN_KEY_START */
uint32_t apiVersion = vk::enumerateInstanceVersion();
std::cout << "APIVersion = " << decodeAPIVersion( apiVersion );
std::cout << "APIVersion = " << decodeAPIVersion( apiVersion ) << std::endl;
/* VULKAN_KEY_END */
}

View File

@@ -91,36 +91,36 @@ int main( int /*argc*/, char ** /*argv*/ )
{
try
{
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
vk::Instance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
vk::PhysicalDevice physicalDevice = instance->enumeratePhysicalDevices().front();
vk::PhysicalDevice physicalDevice = instance.enumeratePhysicalDevices().front();
vk::su::SurfaceData surfaceData( instance, AppName, vk::Extent2D( 500, 500 ) );
std::pair<uint32_t, uint32_t> graphicsAndPresentQueueFamilyIndex =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, *surfaceData.surface );
vk::UniqueDevice device =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, surfaceData.surface );
vk::Device device =
vk::su::createDevice( physicalDevice, graphicsAndPresentQueueFamilyIndex.first, vk::su::getDeviceExtensions() );
vk::UniqueCommandPool commandPool = vk::su::createCommandPool( device, graphicsAndPresentQueueFamilyIndex.first );
vk::UniqueCommandBuffer commandBuffer = std::move( device
->allocateCommandBuffersUnique( vk::CommandBufferAllocateInfo(
commandPool.get(), vk::CommandBufferLevel::ePrimary, 1 ) )
.front() );
vk::CommandPool commandPool = vk::su::createCommandPool( device, graphicsAndPresentQueueFamilyIndex.first );
vk::CommandBuffer commandBuffer =
device.allocateCommandBuffers( vk::CommandBufferAllocateInfo( commandPool, vk::CommandBufferLevel::ePrimary, 1 ) )
.front();
vk::Queue graphicsQueue = device->getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
vk::Queue presentQueue = device->getQueue( graphicsAndPresentQueueFamilyIndex.second, 0 );
vk::Queue graphicsQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
vk::Queue presentQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.second, 0 );
vk::su::SwapChainData swapChainData( physicalDevice,
device,
*surfaceData.surface,
surfaceData.surface,
surfaceData.extent,
vk::ImageUsageFlagBits::eColorAttachment |
vk::ImageUsageFlagBits::eTransferSrc,
vk::UniqueSwapchainKHR(),
{},
graphicsAndPresentQueueFamilyIndex.first,
graphicsAndPresentQueueFamilyIndex.second );
@@ -128,27 +128,27 @@ int main( int /*argc*/, char ** /*argv*/ )
vk::su::TextureData textureData( physicalDevice, device );
commandBuffer->begin( vk::CommandBufferBeginInfo() );
commandBuffer.begin( vk::CommandBufferBeginInfo() );
textureData.setImage( device, commandBuffer, vk::su::MonochromeImageGenerator( { 118, 185, 0 } ) );
vk::su::BufferData uniformBufferData(
physicalDevice, device, sizeof( glm::mat4x4 ), vk::BufferUsageFlagBits::eUniformBuffer );
vk::su::copyToDevice(
device, uniformBufferData.deviceMemory, vk::su::createModelViewProjectionClipMatrix( surfaceData.extent ) );
glm::mat4x4 mvpcMatrix = vk::su::createModelViewProjectionClipMatrix( surfaceData.extent );
vk::su::copyToDevice( device, uniformBufferData.deviceMemory, mvpcMatrix );
vk::UniqueRenderPass renderPass = vk::su::createRenderPass(
vk::RenderPass renderPass = vk::su::createRenderPass(
device,
vk::su::pickSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( surfaceData.surface.get() ) ).format,
vk::su::pickSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( surfaceData.surface ) ).format,
depthBufferData.format );
glslang::InitializeProcess();
vk::UniqueShaderModule vertexShaderModule =
vk::ShaderModule vertexShaderModule =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eVertex, vertexShaderText );
vk::UniqueShaderModule fragmentShaderModule =
vk::ShaderModule fragmentShaderModule =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eFragment, fragmentShaderText );
glslang::FinalizeProcess();
std::vector<vk::UniqueFramebuffer> framebuffers = vk::su::createFramebuffers(
std::vector<vk::Framebuffer> framebuffers = vk::su::createFramebuffers(
device, renderPass, swapChainData.imageViews, depthBufferData.imageView, surfaceData.extent );
vk::su::BufferData vertexBufferData(
@@ -163,52 +163,49 @@ int main( int /*argc*/, char ** /*argv*/ )
// Create first layout to contain uniform buffer data
vk::DescriptorSetLayoutBinding uniformBinding(
0, vk::DescriptorType::eUniformBuffer, 1, vk::ShaderStageFlagBits::eVertex );
vk::UniqueDescriptorSetLayout uniformLayout = device->createDescriptorSetLayoutUnique(
vk::DescriptorSetLayout uniformLayout = device.createDescriptorSetLayout(
vk::DescriptorSetLayoutCreateInfo( vk::DescriptorSetLayoutCreateFlags(), uniformBinding ) );
// Create second layout containing combined sampler/image data
vk::DescriptorSetLayoutBinding sampler2DBinding(
0, vk::DescriptorType::eCombinedImageSampler, 1, vk::ShaderStageFlagBits::eVertex );
vk::UniqueDescriptorSetLayout samplerLayout = device->createDescriptorSetLayoutUnique(
vk::DescriptorSetLayout samplerLayout = device.createDescriptorSetLayout(
vk::DescriptorSetLayoutCreateInfo( vk::DescriptorSetLayoutCreateFlags(), sampler2DBinding ) );
// Create pipeline layout with multiple descriptor sets
std::array<vk::DescriptorSetLayout, 2> descriptorSetLayouts = { { uniformLayout.get(), samplerLayout.get() } };
vk::UniquePipelineLayout pipelineLayout = device->createPipelineLayoutUnique(
std::array<vk::DescriptorSetLayout, 2> descriptorSetLayouts = { { uniformLayout, samplerLayout } };
vk::PipelineLayout pipelineLayout = device.createPipelineLayout(
vk::PipelineLayoutCreateInfo( vk::PipelineLayoutCreateFlags(), descriptorSetLayouts ) );
// Create a single pool to contain data for our two descriptor sets
std::array<vk::DescriptorPoolSize, 2> poolSizes = { vk::DescriptorPoolSize( vk::DescriptorType::eUniformBuffer, 1 ),
vk::DescriptorPoolSize(
vk::DescriptorType::eCombinedImageSampler, 1 ) };
vk::UniqueDescriptorPool descriptorPool = device->createDescriptorPoolUnique(
vk::DescriptorPool descriptorPool = device.createDescriptorPool(
vk::DescriptorPoolCreateInfo( vk::DescriptorPoolCreateFlagBits::eFreeDescriptorSet, 2, poolSizes ) );
// Populate descriptor sets
std::vector<vk::UniqueDescriptorSet> descriptorSets = device->allocateDescriptorSetsUnique(
vk::DescriptorSetAllocateInfo( descriptorPool.get(), descriptorSetLayouts ) );
vk::DescriptorSetAllocateInfo descriptorSetAllocateInfo( descriptorPool, descriptorSetLayouts );
std::vector<vk::DescriptorSet> descriptorSets = device.allocateDescriptorSets( descriptorSetAllocateInfo );
// Populate with info about our uniform buffer
vk::DescriptorBufferInfo uniformBufferInfo( uniformBufferData.buffer.get(), 0, sizeof( glm::mat4x4 ) );
vk::DescriptorImageInfo textureImageInfo( textureData.textureSampler.get(),
textureData.imageData->imageView.get(),
vk::ImageLayout::eShaderReadOnlyOptimal );
vk::DescriptorBufferInfo uniformBufferInfo( uniformBufferData.buffer, 0, sizeof( glm::mat4x4 ) );
vk::DescriptorImageInfo textureImageInfo(
textureData.sampler, textureData.imageData->imageView, vk::ImageLayout::eShaderReadOnlyOptimal );
std::array<vk::WriteDescriptorSet, 2> writeDescriptorSets = {
{ vk::WriteDescriptorSet(
descriptorSets[0].get(), 0, 0, vk::DescriptorType::eUniformBuffer, {}, uniformBufferInfo ),
vk::WriteDescriptorSet(
descriptorSets[1].get(), 0, 0, vk::DescriptorType::eCombinedImageSampler, textureImageInfo ) }
{ vk::WriteDescriptorSet( descriptorSets[0], 0, 0, vk::DescriptorType::eUniformBuffer, {}, uniformBufferInfo ),
vk::WriteDescriptorSet( descriptorSets[1], 0, 0, vk::DescriptorType::eCombinedImageSampler, textureImageInfo ) }
};
device->updateDescriptorSets( writeDescriptorSets, nullptr );
device.updateDescriptorSets( writeDescriptorSets, nullptr );
/* VULKAN_KEY_END */
vk::UniquePipelineCache pipelineCache = device->createPipelineCacheUnique( vk::PipelineCacheCreateInfo() );
vk::UniquePipeline graphicsPipeline =
vk::PipelineCache pipelineCache = device.createPipelineCache( vk::PipelineCacheCreateInfo() );
vk::Pipeline graphicsPipeline =
vk::su::createGraphicsPipeline( device,
pipelineCache,
std::make_pair( *vertexShaderModule, nullptr ),
std::make_pair( *fragmentShaderModule, nullptr ),
std::make_pair( vertexShaderModule, nullptr ),
std::make_pair( fragmentShaderModule, nullptr ),
sizeof( texturedCubeData[0] ),
{ { vk::Format::eR32G32B32A32Sfloat, 0 }, { vk::Format::eR32G32Sfloat, 16 } },
vk::FrontFace::eClockwise,
@@ -217,52 +214,49 @@ int main( int /*argc*/, char ** /*argv*/ )
renderPass );
// Get the index of the next available swapchain image:
vk::UniqueSemaphore imageAcquiredSemaphore = device->createSemaphoreUnique( vk::SemaphoreCreateInfo() );
vk::ResultValue<uint32_t> currentBuffer = device->acquireNextImageKHR(
swapChainData.swapChain.get(), vk::su::FenceTimeout, imageAcquiredSemaphore.get(), nullptr );
vk::Semaphore imageAcquiredSemaphore = device.createSemaphore( vk::SemaphoreCreateInfo() );
vk::ResultValue<uint32_t> currentBuffer =
device.acquireNextImageKHR( swapChainData.swapChain, vk::su::FenceTimeout, imageAcquiredSemaphore, nullptr );
assert( currentBuffer.result == vk::Result::eSuccess );
assert( currentBuffer.value < framebuffers.size() );
std::array<vk::ClearValue, 2> clearValues;
clearValues[0].color = vk::ClearColorValue( std::array<float, 4>( { { 0.2f, 0.2f, 0.2f, 0.2f } } ) );
clearValues[1].depthStencil = vk::ClearDepthStencilValue( 1.0f, 0 );
vk::RenderPassBeginInfo renderPassBeginInfo( renderPass.get(),
framebuffers[currentBuffer.value].get(),
vk::RenderPassBeginInfo renderPassBeginInfo( renderPass,
framebuffers[currentBuffer.value],
vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ),
clearValues );
commandBuffer->beginRenderPass( renderPassBeginInfo, vk::SubpassContents::eInline );
commandBuffer->bindPipeline( vk::PipelineBindPoint::eGraphics, graphicsPipeline.get() );
commandBuffer->bindDescriptorSets( vk::PipelineBindPoint::eGraphics,
pipelineLayout.get(),
0,
{ descriptorSets[0].get(), descriptorSets[1].get() },
nullptr );
commandBuffer.beginRenderPass( renderPassBeginInfo, vk::SubpassContents::eInline );
commandBuffer.bindPipeline( vk::PipelineBindPoint::eGraphics, graphicsPipeline );
commandBuffer.bindDescriptorSets(
vk::PipelineBindPoint::eGraphics, pipelineLayout, 0, { descriptorSets[0], descriptorSets[1] }, nullptr );
commandBuffer->bindVertexBuffers( 0, *vertexBufferData.buffer, { 0 } );
commandBuffer->setViewport( 0,
vk::Viewport( 0.0f,
0.0f,
static_cast<float>( surfaceData.extent.width ),
static_cast<float>( surfaceData.extent.height ),
0.0f,
1.0f ) );
commandBuffer->setScissor( 0, vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ) );
commandBuffer.bindVertexBuffers( 0, vertexBufferData.buffer, { 0 } );
commandBuffer.setViewport( 0,
vk::Viewport( 0.0f,
0.0f,
static_cast<float>( surfaceData.extent.width ),
static_cast<float>( surfaceData.extent.height ),
0.0f,
1.0f ) );
commandBuffer.setScissor( 0, vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ) );
commandBuffer->draw( 12 * 3, 1, 0, 0 );
commandBuffer->endRenderPass();
commandBuffer->end();
commandBuffer.draw( 12 * 3, 1, 0, 0 );
commandBuffer.endRenderPass();
commandBuffer.end();
vk::UniqueFence drawFence = device->createFenceUnique( vk::FenceCreateInfo() );
vk::Fence drawFence = device.createFence( vk::FenceCreateInfo() );
vk::PipelineStageFlags waitDestinationStageMask( vk::PipelineStageFlagBits::eColorAttachmentOutput );
vk::SubmitInfo submitInfo( *imageAcquiredSemaphore, waitDestinationStageMask, *commandBuffer );
graphicsQueue.submit( submitInfo, drawFence.get() );
vk::SubmitInfo submitInfo( imageAcquiredSemaphore, waitDestinationStageMask, commandBuffer );
graphicsQueue.submit( submitInfo, drawFence );
while ( vk::Result::eTimeout == device->waitForFences( drawFence.get(), VK_TRUE, vk::su::FenceTimeout ) )
while ( vk::Result::eTimeout == device.waitForFences( drawFence, VK_TRUE, vk::su::FenceTimeout ) )
;
vk::Result result =
presentQueue.presentKHR( vk::PresentInfoKHR( {}, *swapChainData.swapChain, currentBuffer.value ) );
presentQueue.presentKHR( vk::PresentInfoKHR( {}, swapChainData.swapChain, currentBuffer.value ) );
switch ( result )
{
case vk::Result::eSuccess: break;
@@ -273,7 +267,35 @@ int main( int /*argc*/, char ** /*argv*/ )
}
std::this_thread::sleep_for( std::chrono::milliseconds( 1000 ) );
device->waitIdle();
device.waitIdle();
device.destroyFence( drawFence );
device.destroySemaphore( imageAcquiredSemaphore );
device.destroyPipeline( graphicsPipeline );
device.destroyPipelineCache( pipelineCache );
device.freeDescriptorSets( descriptorPool, descriptorSets );
device.destroyDescriptorPool( descriptorPool );
device.destroyPipelineLayout( pipelineLayout );
device.destroyDescriptorSetLayout( samplerLayout );
device.destroyDescriptorSetLayout( uniformLayout );
vertexBufferData.clear( device );
for ( auto framebuffer : framebuffers )
{
device.destroyFramebuffer( framebuffer );
}
device.destroyShaderModule( fragmentShaderModule );
device.destroyShaderModule( vertexShaderModule );
device.destroyRenderPass( renderPass );
uniformBufferData.clear( device );
textureData.clear( device );
depthBufferData.clear( device );
swapChainData.clear( device );
device.freeCommandBuffers( commandPool, commandBuffer );
device.destroyCommandPool( commandPool );
device.destroy();
instance.destroySurfaceKHR( surfaceData.surface );
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -32,36 +32,36 @@ int main( int /*argc*/, char ** /*argv*/ )
{
try
{
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
vk::Instance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
vk::PhysicalDevice physicalDevice = instance->enumeratePhysicalDevices().front();
vk::PhysicalDevice physicalDevice = instance.enumeratePhysicalDevices().front();
vk::su::SurfaceData surfaceData( instance, AppName, vk::Extent2D( 500, 500 ) );
std::pair<uint32_t, uint32_t> graphicsAndPresentQueueFamilyIndex =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, *surfaceData.surface );
vk::UniqueDevice device =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, surfaceData.surface );
vk::Device device =
vk::su::createDevice( physicalDevice, graphicsAndPresentQueueFamilyIndex.first, vk::su::getDeviceExtensions() );
vk::UniqueCommandPool commandPool = vk::su::createCommandPool( device, graphicsAndPresentQueueFamilyIndex.first );
vk::UniqueCommandBuffer commandBuffer = std::move( device
->allocateCommandBuffersUnique( vk::CommandBufferAllocateInfo(
commandPool.get(), vk::CommandBufferLevel::ePrimary, 1 ) )
.front() );
vk::CommandPool commandPool = vk::su::createCommandPool( device, graphicsAndPresentQueueFamilyIndex.first );
vk::CommandBuffer commandBuffer =
device.allocateCommandBuffers( vk::CommandBufferAllocateInfo( commandPool, vk::CommandBufferLevel::ePrimary, 1 ) )
.front();
vk::Queue graphicsQueue = device->getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
vk::Queue presentQueue = device->getQueue( graphicsAndPresentQueueFamilyIndex.second, 0 );
vk::Queue graphicsQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
vk::Queue presentQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.second, 0 );
vk::su::SwapChainData swapChainData( physicalDevice,
device,
*surfaceData.surface,
surfaceData.surface,
surfaceData.extent,
vk::ImageUsageFlagBits::eColorAttachment |
vk::ImageUsageFlagBits::eTransferSrc,
vk::UniqueSwapchainKHR(),
{},
graphicsAndPresentQueueFamilyIndex.first,
graphicsAndPresentQueueFamilyIndex.second );
@@ -69,27 +69,27 @@ int main( int /*argc*/, char ** /*argv*/ )
vk::su::BufferData uniformBufferData(
physicalDevice, device, sizeof( glm::mat4x4 ), vk::BufferUsageFlagBits::eUniformBuffer );
vk::su::copyToDevice(
device, uniformBufferData.deviceMemory, vk::su::createModelViewProjectionClipMatrix( surfaceData.extent ) );
glm::mat4x4 mvpcMatrix = vk::su::createModelViewProjectionClipMatrix( surfaceData.extent );
vk::su::copyToDevice( device, uniformBufferData.deviceMemory, mvpcMatrix );
vk::UniqueDescriptorSetLayout descriptorSetLayout = vk::su::createDescriptorSetLayout(
vk::DescriptorSetLayout descriptorSetLayout = vk::su::createDescriptorSetLayout(
device, { { vk::DescriptorType::eUniformBuffer, 1, vk::ShaderStageFlagBits::eVertex } } );
vk::UniquePipelineLayout pipelineLayout = device->createPipelineLayoutUnique(
vk::PipelineLayoutCreateInfo( vk::PipelineLayoutCreateFlags(), *descriptorSetLayout ) );
vk::PipelineLayout pipelineLayout = device.createPipelineLayout(
vk::PipelineLayoutCreateInfo( vk::PipelineLayoutCreateFlags(), descriptorSetLayout ) );
vk::UniqueRenderPass renderPass = vk::su::createRenderPass(
vk::RenderPass renderPass = vk::su::createRenderPass(
device,
vk::su::pickSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( surfaceData.surface.get() ) ).format,
vk::su::pickSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( surfaceData.surface ) ).format,
depthBufferData.format );
glslang::InitializeProcess();
vk::UniqueShaderModule vertexShaderModule =
vk::ShaderModule vertexShaderModule =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eVertex, vertexShaderText_PC_C );
vk::UniqueShaderModule fragmentShaderModule =
vk::ShaderModule fragmentShaderModule =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eFragment, fragmentShaderText_C_C );
glslang::FinalizeProcess();
std::vector<vk::UniqueFramebuffer> framebuffers = vk::su::createFramebuffers(
std::vector<vk::Framebuffer> framebuffers = vk::su::createFramebuffers(
device, renderPass, swapChainData.imageViews, depthBufferData.imageView, surfaceData.extent );
vk::su::BufferData vertexBufferData(
@@ -99,21 +99,20 @@ int main( int /*argc*/, char ** /*argv*/ )
coloredCubeData,
sizeof( coloredCubeData ) / sizeof( coloredCubeData[0] ) );
vk::UniqueDescriptorPool descriptorPool =
vk::DescriptorPool descriptorPool =
vk::su::createDescriptorPool( device, { { vk::DescriptorType::eUniformBuffer, 1 } } );
vk::UniqueDescriptorSet descriptorSet = std::move(
device->allocateDescriptorSetsUnique( vk::DescriptorSetAllocateInfo( *descriptorPool, *descriptorSetLayout ) )
.front() );
vk::DescriptorSetAllocateInfo descriptorSetAllocateInfo( descriptorPool, descriptorSetLayout );
vk::DescriptorSet descriptorSet = device.allocateDescriptorSets( descriptorSetAllocateInfo ).front();
vk::su::updateDescriptorSets(
device, descriptorSet, { { vk::DescriptorType::eUniformBuffer, uniformBufferData.buffer, {} } }, {} );
vk::UniquePipelineCache pipelineCache = device->createPipelineCacheUnique( vk::PipelineCacheCreateInfo() );
vk::UniquePipeline graphicsPipeline = vk::su::createGraphicsPipeline(
vk::PipelineCache pipelineCache = device.createPipelineCache( vk::PipelineCacheCreateInfo() );
vk::Pipeline graphicsPipeline = vk::su::createGraphicsPipeline(
device,
pipelineCache,
std::make_pair( *vertexShaderModule, nullptr ),
std::make_pair( *fragmentShaderModule, nullptr ),
std::make_pair( vertexShaderModule, nullptr ),
std::make_pair( fragmentShaderModule, nullptr ),
sizeof( coloredCubeData[0] ),
{ { vk::Format::eR32G32B32A32Sfloat, 0 }, { vk::Format::eR32G32B32A32Sfloat, 16 } },
vk::FrontFace::eClockwise,
@@ -123,93 +122,91 @@ int main( int /*argc*/, char ** /*argv*/ )
/* VULKAN_KEY_START */
vk::UniqueSemaphore imageAcquiredSemaphore =
device->createSemaphoreUnique( vk::SemaphoreCreateInfo( vk::SemaphoreCreateFlags() ) );
vk::Semaphore imageAcquiredSemaphore =
device.createSemaphore( vk::SemaphoreCreateInfo( vk::SemaphoreCreateFlags() ) );
// Get the index of the next available swapchain image:
vk::ResultValue<uint32_t> currentBuffer =
device->acquireNextImageKHR( swapChainData.swapChain.get(), UINT64_MAX, imageAcquiredSemaphore.get(), nullptr );
device.acquireNextImageKHR( swapChainData.swapChain, UINT64_MAX, imageAcquiredSemaphore, nullptr );
assert( currentBuffer.result == vk::Result::eSuccess );
assert( currentBuffer.value < framebuffers.size() );
/* Allocate a uniform buffer that will take query results. */
vk::UniqueBuffer queryResultBuffer = device->createBufferUnique(
vk::Buffer queryResultBuffer = device.createBuffer(
vk::BufferCreateInfo( vk::BufferCreateFlags(),
4 * sizeof( uint64_t ),
vk::BufferUsageFlagBits::eUniformBuffer | vk::BufferUsageFlagBits::eTransferDst ) );
vk::MemoryRequirements memoryRequirements = device->getBufferMemoryRequirements( queryResultBuffer.get() );
vk::MemoryRequirements memoryRequirements = device.getBufferMemoryRequirements( queryResultBuffer );
uint32_t memoryTypeIndex =
vk::su::findMemoryType( physicalDevice.getMemoryProperties(),
memoryRequirements.memoryTypeBits,
vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent );
vk::UniqueDeviceMemory queryResultMemory =
device->allocateMemoryUnique( vk::MemoryAllocateInfo( memoryRequirements.size, memoryTypeIndex ) );
vk::DeviceMemory queryResultMemory =
device.allocateMemory( vk::MemoryAllocateInfo( memoryRequirements.size, memoryTypeIndex ) );
device->bindBufferMemory( queryResultBuffer.get(), queryResultMemory.get(), 0 );
device.bindBufferMemory( queryResultBuffer, queryResultMemory, 0 );
vk::UniqueQueryPool queryPool = device->createQueryPoolUnique( vk::QueryPoolCreateInfo(
vk::QueryPool queryPool = device.createQueryPool( vk::QueryPoolCreateInfo(
vk::QueryPoolCreateFlags(), vk::QueryType::eOcclusion, 2, vk::QueryPipelineStatisticFlags() ) );
commandBuffer->begin( vk::CommandBufferBeginInfo( vk::CommandBufferUsageFlags() ) );
commandBuffer->resetQueryPool( queryPool.get(), 0, 2 );
commandBuffer.begin( vk::CommandBufferBeginInfo( vk::CommandBufferUsageFlags() ) );
commandBuffer.resetQueryPool( queryPool, 0, 2 );
std::array<vk::ClearValue, 2> clearValues;
clearValues[0].color = vk::ClearColorValue( std::array<float, 4>( { { 0.2f, 0.2f, 0.2f, 0.2f } } ) );
clearValues[1].depthStencil = vk::ClearDepthStencilValue( 1.0f, 0 );
commandBuffer->beginRenderPass( vk::RenderPassBeginInfo( renderPass.get(),
framebuffers[currentBuffer.value].get(),
vk::Rect2D( vk::Offset2D(), surfaceData.extent ),
clearValues ),
vk::SubpassContents::eInline );
commandBuffer.beginRenderPass(
vk::RenderPassBeginInfo(
renderPass, framebuffers[currentBuffer.value], vk::Rect2D( vk::Offset2D(), surfaceData.extent ), clearValues ),
vk::SubpassContents::eInline );
commandBuffer->bindPipeline( vk::PipelineBindPoint::eGraphics, graphicsPipeline.get() );
commandBuffer->bindDescriptorSets(
vk::PipelineBindPoint::eGraphics, pipelineLayout.get(), 0, descriptorSet.get(), {} );
commandBuffer.bindPipeline( vk::PipelineBindPoint::eGraphics, graphicsPipeline );
commandBuffer.bindDescriptorSets( vk::PipelineBindPoint::eGraphics, pipelineLayout, 0, descriptorSet, {} );
commandBuffer->bindVertexBuffers( 0, *vertexBufferData.buffer, { 0 } );
commandBuffer->setViewport( 0,
vk::Viewport( 0.0f,
0.0f,
static_cast<float>( surfaceData.extent.width ),
static_cast<float>( surfaceData.extent.height ),
0.0f,
1.0f ) );
commandBuffer->setScissor( 0, vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ) );
commandBuffer.bindVertexBuffers( 0, vertexBufferData.buffer, { 0 } );
commandBuffer.setViewport( 0,
vk::Viewport( 0.0f,
0.0f,
static_cast<float>( surfaceData.extent.width ),
static_cast<float>( surfaceData.extent.height ),
0.0f,
1.0f ) );
commandBuffer.setScissor( 0, vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ) );
commandBuffer->beginQuery( queryPool.get(), 0, vk::QueryControlFlags() );
commandBuffer->endQuery( queryPool.get(), 0 );
commandBuffer.beginQuery( queryPool, 0, vk::QueryControlFlags() );
commandBuffer.endQuery( queryPool, 0 );
commandBuffer->beginQuery( queryPool.get(), 1, vk::QueryControlFlags() );
commandBuffer->draw( 12 * 3, 1, 0, 0 );
commandBuffer->endRenderPass();
commandBuffer->endQuery( queryPool.get(), 1 );
commandBuffer.beginQuery( queryPool, 1, vk::QueryControlFlags() );
commandBuffer.draw( 12 * 3, 1, 0, 0 );
commandBuffer.endRenderPass();
commandBuffer.endQuery( queryPool, 1 );
commandBuffer->copyQueryPoolResults( queryPool.get(),
0,
2,
queryResultBuffer.get(),
0,
sizeof( uint64_t ),
vk::QueryResultFlagBits::e64 | vk::QueryResultFlagBits::eWait );
commandBuffer->end();
commandBuffer.copyQueryPoolResults( queryPool,
0,
2,
queryResultBuffer,
0,
sizeof( uint64_t ),
vk::QueryResultFlagBits::e64 | vk::QueryResultFlagBits::eWait );
commandBuffer.end();
vk::UniqueFence drawFence = device->createFenceUnique( vk::FenceCreateInfo() );
vk::Fence drawFence = device.createFence( vk::FenceCreateInfo() );
vk::PipelineStageFlags waitDestinationStageMask( vk::PipelineStageFlagBits::eColorAttachmentOutput );
vk::SubmitInfo submitInfo( *imageAcquiredSemaphore, waitDestinationStageMask, *commandBuffer );
graphicsQueue.submit( submitInfo, drawFence.get() );
vk::SubmitInfo submitInfo( imageAcquiredSemaphore, waitDestinationStageMask, commandBuffer );
graphicsQueue.submit( submitInfo, drawFence );
graphicsQueue.waitIdle();
vk::ResultValue<std::vector<uint64_t>> rv =
device->getQueryPoolResults<uint64_t>( *queryPool,
0,
2,
2 * sizeof( uint64_t ),
sizeof( uint64_t ),
vk::QueryResultFlagBits::e64 | vk::QueryResultFlagBits::eWait );
switch ( rv.result )
device.getQueryPoolResults<uint64_t>( queryPool,
0,
2,
2 * sizeof( uint64_t ),
sizeof( uint64_t ),
vk::QueryResultFlagBits::e64 | vk::QueryResultFlagBits::eWait );
switch ( rv.result )
{
case vk::Result::eSuccess: break;
case vk::Result::eNotReady:
@@ -224,18 +221,19 @@ int main( int /*argc*/, char ** /*argv*/ )
/* Read back query result from buffer */
uint64_t * samplesPassedPtr = static_cast<uint64_t *>(
device->mapMemory( queryResultMemory.get(), 0, memoryRequirements.size, vk::MemoryMapFlags() ) );
device.mapMemory( queryResultMemory, 0, memoryRequirements.size, vk::MemoryMapFlags() ) );
std::cout << "vkCmdCopyQueryPoolResults data\n";
std::cout << "samples_passed[0] = " << samplesPassedPtr[0] << "\n";
std::cout << "samples_passed[1] = " << samplesPassedPtr[1] << "\n";
device->unmapMemory( queryResultMemory.get() );
device.unmapMemory( queryResultMemory );
while ( vk::Result::eTimeout == device->waitForFences( drawFence.get(), VK_TRUE, vk::su::FenceTimeout ) )
while ( vk::Result::eTimeout == device.waitForFences( drawFence, VK_TRUE, vk::su::FenceTimeout ) )
;
vk::Result result = presentQueue.presentKHR( vk::PresentInfoKHR( {}, *swapChainData.swapChain, currentBuffer.value ) );
vk::Result result =
presentQueue.presentKHR( vk::PresentInfoKHR( {}, swapChainData.swapChain, currentBuffer.value ) );
switch ( result )
{
case vk::Result::eSuccess: break;
@@ -246,7 +244,37 @@ int main( int /*argc*/, char ** /*argv*/ )
}
std::this_thread::sleep_for( std::chrono::milliseconds( 1000 ) );
device.destroyFence( drawFence );
device.destroyQueryPool( queryPool );
device.freeMemory( queryResultMemory );
device.destroyBuffer( queryResultBuffer );
device.destroySemaphore( imageAcquiredSemaphore );
/* VULKAN_KEY_END */
device.destroyPipeline( graphicsPipeline );
device.destroyPipelineCache( pipelineCache );
device.freeDescriptorSets( descriptorPool, descriptorSet );
device.destroyDescriptorPool( descriptorPool );
vertexBufferData.clear( device );
for ( auto framebuffer : framebuffers )
{
device.destroyFramebuffer( framebuffer );
}
device.destroyShaderModule( fragmentShaderModule );
device.destroyShaderModule( vertexShaderModule );
device.destroyRenderPass( renderPass );
device.destroyPipelineLayout( pipelineLayout );
device.destroyDescriptorSetLayout( descriptorSetLayout );
uniformBufferData.clear( device );
depthBufferData.clear( device );
swapChainData.clear( device );
device.freeCommandBuffers( commandPool, commandBuffer );
device.destroyCommandPool( commandPool );
device.destroy();
instance.destroySurfaceKHR( surfaceData.surface );
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -27,21 +27,22 @@ int main( int /*argc*/, char ** /*argv*/ )
{
try
{
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName );
vk::Instance instance = vk::su::createInstance( AppName, EngineName );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
// enumerate the physicalDevices
std::vector<vk::PhysicalDevice> physicalDevices = instance->enumeratePhysicalDevices();
std::vector<vk::PhysicalDevice> physicalDevices = instance.enumeratePhysicalDevices();
/* VULKAN_KEY_START */
for ( size_t i = 0; i < physicalDevices.size(); i++ )
{
std::cout << "PhysicalDevice " << i << "\n";
std::vector<vk::ExtensionProperties> extensionProperties =
physicalDevices[i].enumerateDeviceExtensionProperties();
std::cout << "PhysicalDevice " << i << " : " << extensionProperties.size() << " extensions:\n";
// sort the extensions alphabetically
std::sort( extensionProperties.begin(),
@@ -58,6 +59,9 @@ int main( int /*argc*/, char ** /*argv*/ )
}
/* VULKAN_KEY_END */
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -36,13 +36,14 @@ int main( int /*argc*/, char ** /*argv*/ )
{
try
{
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName, {}, {}, VK_API_VERSION_1_1 );
vk::Instance instance = vk::su::createInstance( AppName, EngineName, {}, {}, VK_API_VERSION_1_1 );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
// enumerate the physicalDevices
std::vector<vk::PhysicalDevice> physicalDevices = instance->enumeratePhysicalDevices();
std::vector<vk::PhysicalDevice> physicalDevices = instance.enumeratePhysicalDevices();
/* VULKAN_KEY_START */
@@ -53,7 +54,7 @@ int main( int /*argc*/, char ** /*argv*/ )
std::vector<vk::ExtensionProperties> extensionProperties =
physicalDevices[i].enumerateDeviceExtensionProperties();
std::cout << "PhysicalDevice " << i << "\n";
std::cout << "PhysicalDevice " << i << " :\n";
auto features2 = physicalDevices[i]
.getFeatures2<vk::PhysicalDeviceFeatures2,
vk::PhysicalDevice16BitStorageFeatures,
@@ -808,6 +809,9 @@ int main( int /*argc*/, char ** /*argv*/ )
}
/* VULKAN_KEY_END */
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -27,14 +27,15 @@ int main( int /*argc*/, char ** /*argv*/ )
{
try
{
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName, {}, {}, VK_API_VERSION_1_1 );
vk::Instance instance = vk::su::createInstance( AppName, EngineName, {}, {}, VK_API_VERSION_1_1 );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
/* VULKAN_KEY_START */
std::vector<vk::PhysicalDeviceGroupProperties> groupProperties = instance->enumeratePhysicalDeviceGroups();
std::vector<vk::PhysicalDeviceGroupProperties> groupProperties = instance.enumeratePhysicalDeviceGroups();
std::cout << std::boolalpha;
for ( size_t i = 0; i < groupProperties.size(); i++ )
@@ -60,15 +61,14 @@ int main( int /*argc*/, char ** /*argv*/ )
std::vector<vk::QueueFamilyProperties> queueFamilyProperties = physicalDevice.getQueueFamilyProperties();
// get the first index into queueFamiliyProperties which supports graphics
size_t graphicsQueueFamilyIndex = std::distance(
queueFamilyProperties.begin(),
std::find_if(
queueFamilyProperties.begin(), queueFamilyProperties.end(), []( vk::QueueFamilyProperties const & qfp ) {
return qfp.queueFlags & vk::QueueFlagBits::eGraphics;
} ) );
auto propertyIterator = std::find_if(
queueFamilyProperties.begin(), queueFamilyProperties.end(), []( vk::QueueFamilyProperties const & qfp ) {
return qfp.queueFlags & vk::QueueFlagBits::eGraphics;
} );
size_t graphicsQueueFamilyIndex = std::distance( queueFamilyProperties.begin(), propertyIterator );
assert( graphicsQueueFamilyIndex < queueFamilyProperties.size() );
// create a UniqueDevice
// create a Device
float queuePriority = 0.0f;
vk::DeviceQueueCreateInfo deviceQueueCreateInfo(
vk::DeviceQueueCreateFlags(), static_cast<uint32_t>( graphicsQueueFamilyIndex ), 1, &queuePriority );
@@ -78,11 +78,17 @@ int main( int /*argc*/, char ** /*argv*/ )
groupProperties[i].physicalDevices );
deviceCreateInfo.pNext = &deviceGroupDeviceCreateInfo;
vk::UniqueDevice device = physicalDevice.createDeviceUnique( deviceCreateInfo );
vk::Device device = physicalDevice.createDevice( deviceCreateInfo );
// ... and destroy it again
device.destroy();
}
}
/* VULKAN_KEY_END */
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -101,13 +101,14 @@ int main( int /*argc*/, char ** /*argv*/ )
{
try
{
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName, {}, {}, VK_API_VERSION_1_1 );
vk::Instance instance = vk::su::createInstance( AppName, EngineName, {}, {}, VK_API_VERSION_1_1 );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
// enumerate the physicalDevices
std::vector<vk::PhysicalDevice> physicalDevices = instance->enumeratePhysicalDevices();
std::vector<vk::PhysicalDevice> physicalDevices = instance.enumeratePhysicalDevices();
/* VULKAN_KEY_START */
@@ -1266,6 +1267,9 @@ int main( int /*argc*/, char ** /*argv*/ )
}
/* VULKAN_KEY_END */
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -29,13 +29,14 @@ int main( int /*argc*/, char ** /*argv*/ )
{
try
{
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName, {}, {}, VK_API_VERSION_1_1 );
vk::Instance instance = vk::su::createInstance( AppName, EngineName, {}, {}, VK_API_VERSION_1_1 );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
// enumerate the physicalDevices
std::vector<vk::PhysicalDevice> physicalDevices = instance->enumeratePhysicalDevices();
std::vector<vk::PhysicalDevice> physicalDevices = instance.enumeratePhysicalDevices();
/* VULKAN_KEY_START */
@@ -87,6 +88,9 @@ int main( int /*argc*/, char ** /*argv*/ )
}
/* VULKAN_KEY_END */
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -71,71 +71,71 @@ int main( int /*argc*/, char ** /*argv*/ )
{
try
{
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
vk::Instance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
vk::PhysicalDevice physicalDevice = instance->enumeratePhysicalDevices().front();
vk::PhysicalDevice physicalDevice = instance.enumeratePhysicalDevices().front();
vk::PhysicalDeviceProperties properties = physicalDevice.getProperties();
vk::su::SurfaceData surfaceData( instance, AppName, vk::Extent2D( 500, 500 ) );
std::pair<uint32_t, uint32_t> graphicsAndPresentQueueFamilyIndex =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, *surfaceData.surface );
vk::UniqueDevice device =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, surfaceData.surface );
vk::Device device =
vk::su::createDevice( physicalDevice, graphicsAndPresentQueueFamilyIndex.first, vk::su::getDeviceExtensions() );
vk::UniqueCommandPool commandPool = vk::su::createCommandPool( device, graphicsAndPresentQueueFamilyIndex.first );
vk::UniqueCommandBuffer commandBuffer = std::move( device
->allocateCommandBuffersUnique( vk::CommandBufferAllocateInfo(
commandPool.get(), vk::CommandBufferLevel::ePrimary, 1 ) )
.front() );
vk::CommandPool commandPool = vk::su::createCommandPool( device, graphicsAndPresentQueueFamilyIndex.first );
vk::CommandBuffer commandBuffer =
device.allocateCommandBuffers( vk::CommandBufferAllocateInfo( commandPool, vk::CommandBufferLevel::ePrimary, 1 ) )
.front();
vk::Queue graphicsQueue = device->getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
vk::Queue presentQueue = device->getQueue( graphicsAndPresentQueueFamilyIndex.second, 0 );
vk::Queue graphicsQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
vk::Queue presentQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.second, 0 );
vk::su::SwapChainData swapChainData( physicalDevice,
device,
*surfaceData.surface,
surfaceData.surface,
surfaceData.extent,
vk::ImageUsageFlagBits::eColorAttachment |
vk::ImageUsageFlagBits::eTransferSrc,
vk::UniqueSwapchainKHR(),
{},
graphicsAndPresentQueueFamilyIndex.first,
graphicsAndPresentQueueFamilyIndex.second );
vk::su::DepthBufferData depthBufferData( physicalDevice, device, vk::Format::eD16Unorm, surfaceData.extent );
vk::su::TextureData textureData( physicalDevice, device );
commandBuffer->begin( vk::CommandBufferBeginInfo() );
commandBuffer.begin( vk::CommandBufferBeginInfo() );
textureData.setImage( device, commandBuffer, vk::su::MonochromeImageGenerator( { 118, 185, 0 } ) );
vk::su::BufferData uniformBufferData(
physicalDevice, device, sizeof( glm::mat4x4 ), vk::BufferUsageFlagBits::eUniformBuffer );
vk::su::copyToDevice(
device, uniformBufferData.deviceMemory, vk::su::createModelViewProjectionClipMatrix( surfaceData.extent ) );
glm::mat4x4 mvpcMatrix = vk::su::createModelViewProjectionClipMatrix( surfaceData.extent );
vk::su::copyToDevice( device, uniformBufferData.deviceMemory, mvpcMatrix );
vk::UniqueDescriptorSetLayout descriptorSetLayout = vk::su::createDescriptorSetLayout(
vk::DescriptorSetLayout descriptorSetLayout = vk::su::createDescriptorSetLayout(
device,
{ { vk::DescriptorType::eUniformBuffer, 1, vk::ShaderStageFlagBits::eVertex },
{ vk::DescriptorType::eCombinedImageSampler, 1, vk::ShaderStageFlagBits::eFragment } } );
vk::UniquePipelineLayout pipelineLayout = device->createPipelineLayoutUnique(
vk::PipelineLayoutCreateInfo( vk::PipelineLayoutCreateFlags(), *descriptorSetLayout ) );
vk::PipelineLayout pipelineLayout = device.createPipelineLayout(
vk::PipelineLayoutCreateInfo( vk::PipelineLayoutCreateFlags(), descriptorSetLayout ) );
vk::UniqueRenderPass renderPass = vk::su::createRenderPass(
vk::RenderPass renderPass = vk::su::createRenderPass(
device,
vk::su::pickSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( surfaceData.surface.get() ) ).format,
vk::su::pickSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( surfaceData.surface ) ).format,
depthBufferData.format );
glslang::InitializeProcess();
vk::UniqueShaderModule vertexShaderModule =
vk::ShaderModule vertexShaderModule =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eVertex, vertexShaderText_PT_T );
vk::UniqueShaderModule fragmentShaderModule =
vk::ShaderModule fragmentShaderModule =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eFragment, fragmentShaderText_T_C );
glslang::FinalizeProcess();
std::vector<vk::UniqueFramebuffer> framebuffers = vk::su::createFramebuffers(
std::vector<vk::Framebuffer> framebuffers = vk::su::createFramebuffers(
device, renderPass, swapChainData.imageViews, depthBufferData.imageView, surfaceData.extent );
vk::su::BufferData vertexBufferData(
@@ -145,11 +145,10 @@ int main( int /*argc*/, char ** /*argv*/ )
texturedCubeData,
sizeof( texturedCubeData ) / sizeof( texturedCubeData[0] ) );
vk::UniqueDescriptorPool descriptorPool = vk::su::createDescriptorPool(
vk::DescriptorPool descriptorPool = vk::su::createDescriptorPool(
device, { { vk::DescriptorType::eUniformBuffer, 1 }, { vk::DescriptorType::eCombinedImageSampler, 1 } } );
vk::UniqueDescriptorSet descriptorSet = std::move(
device->allocateDescriptorSetsUnique( vk::DescriptorSetAllocateInfo( *descriptorPool, *descriptorSetLayout ) )
.front() );
vk::DescriptorSetAllocateInfo descriptorSetAllocateInfo( descriptorPool, descriptorSetLayout );
vk::DescriptorSet descriptorSet = device.allocateDescriptorSets( descriptorSetAllocateInfo ).front();
vk::su::updateDescriptorSets(
device, descriptorSet, { { vk::DescriptorType::eUniformBuffer, uniformBufferData.buffer, {} } }, textureData );
@@ -287,7 +286,7 @@ int main( int /*argc*/, char ** /*argv*/ )
}
// Feed the initial cache data into cache creation
vk::UniquePipelineCache pipelineCache = device->createPipelineCacheUnique(
vk::PipelineCache pipelineCache = device.createPipelineCache(
vk::PipelineCacheCreateInfo( vk::PipelineCacheCreateFlags(), startCacheSize, startCacheData ) );
// Free our initialData now that pipeline cache has been created
@@ -295,12 +294,12 @@ int main( int /*argc*/, char ** /*argv*/ )
startCacheData = NULL;
// Time (roughly) taken to create the graphics pipeline
timestamp_t start = getMilliseconds();
vk::UniquePipeline graphicsPipeline =
timestamp_t start = getMilliseconds();
vk::Pipeline graphicsPipeline =
vk::su::createGraphicsPipeline( device,
pipelineCache,
std::make_pair( *vertexShaderModule, nullptr ),
std::make_pair( *fragmentShaderModule, nullptr ),
std::make_pair( vertexShaderModule, nullptr ),
std::make_pair( fragmentShaderModule, nullptr ),
sizeof( texturedCubeData[0] ),
{ { vk::Format::eR32G32B32A32Sfloat, 0 }, { vk::Format::eR32G32Sfloat, 16 } },
vk::FrontFace::eClockwise,
@@ -310,12 +309,12 @@ int main( int /*argc*/, char ** /*argv*/ )
timestamp_t elapsed = getMilliseconds() - start;
std::cout << " vkCreateGraphicsPipeline time: " << (double)elapsed << " ms\n";
vk::UniqueSemaphore imageAcquiredSemaphore =
device->createSemaphoreUnique( vk::SemaphoreCreateInfo( vk::SemaphoreCreateFlags() ) );
vk::Semaphore imageAcquiredSemaphore =
device.createSemaphore( vk::SemaphoreCreateInfo( vk::SemaphoreCreateFlags() ) );
// Get the index of the next available swapchain image:
vk::ResultValue<uint32_t> currentBuffer =
device->acquireNextImageKHR( swapChainData.swapChain.get(), UINT64_MAX, imageAcquiredSemaphore.get(), nullptr );
device.acquireNextImageKHR( swapChainData.swapChain, UINT64_MAX, imageAcquiredSemaphore, nullptr );
assert( currentBuffer.result == vk::Result::eSuccess );
assert( currentBuffer.value < framebuffers.size() );
@@ -323,40 +322,38 @@ int main( int /*argc*/, char ** /*argv*/ )
clearValues[0].color = vk::ClearColorValue( std::array<float, 4>( { { 0.2f, 0.2f, 0.2f, 0.2f } } ) );
clearValues[1].depthStencil = vk::ClearDepthStencilValue( 1.0f, 0 );
commandBuffer->beginRenderPass( vk::RenderPassBeginInfo( renderPass.get(),
framebuffers[currentBuffer.value].get(),
vk::Rect2D( vk::Offset2D(), surfaceData.extent ),
clearValues ),
vk::SubpassContents::eInline );
commandBuffer->bindPipeline( vk::PipelineBindPoint::eGraphics, graphicsPipeline.get() );
commandBuffer->bindDescriptorSets(
vk::PipelineBindPoint::eGraphics, pipelineLayout.get(), 0, descriptorSet.get(), {} );
commandBuffer.beginRenderPass(
vk::RenderPassBeginInfo(
renderPass, framebuffers[currentBuffer.value], vk::Rect2D( vk::Offset2D(), surfaceData.extent ), clearValues ),
vk::SubpassContents::eInline );
commandBuffer.bindPipeline( vk::PipelineBindPoint::eGraphics, graphicsPipeline );
commandBuffer.bindDescriptorSets( vk::PipelineBindPoint::eGraphics, pipelineLayout, 0, descriptorSet, {} );
commandBuffer->bindVertexBuffers( 0, *vertexBufferData.buffer, { 0 } );
commandBuffer->setViewport( 0,
vk::Viewport( 0.0f,
0.0f,
static_cast<float>( surfaceData.extent.width ),
static_cast<float>( surfaceData.extent.height ),
0.0f,
1.0f ) );
commandBuffer->setScissor( 0, vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ) );
commandBuffer.bindVertexBuffers( 0, vertexBufferData.buffer, { 0 } );
commandBuffer.setViewport( 0,
vk::Viewport( 0.0f,
0.0f,
static_cast<float>( surfaceData.extent.width ),
static_cast<float>( surfaceData.extent.height ),
0.0f,
1.0f ) );
commandBuffer.setScissor( 0, vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ) );
commandBuffer->draw( 12 * 3, 1, 0, 0 );
commandBuffer->endRenderPass();
commandBuffer->end();
commandBuffer.draw( 12 * 3, 1, 0, 0 );
commandBuffer.endRenderPass();
commandBuffer.end();
vk::UniqueFence drawFence = device->createFenceUnique( vk::FenceCreateInfo() );
vk::Fence drawFence = device.createFence( vk::FenceCreateInfo() );
vk::PipelineStageFlags waitDestinationStageMask( vk::PipelineStageFlagBits::eColorAttachmentOutput );
vk::SubmitInfo submitInfo( *imageAcquiredSemaphore, waitDestinationStageMask, *commandBuffer );
graphicsQueue.submit( submitInfo, drawFence.get() );
vk::SubmitInfo submitInfo( imageAcquiredSemaphore, waitDestinationStageMask, commandBuffer );
graphicsQueue.submit( submitInfo, drawFence );
while ( vk::Result::eTimeout == device->waitForFences( drawFence.get(), VK_TRUE, vk::su::FenceTimeout ) )
while ( vk::Result::eTimeout == device.waitForFences( drawFence, VK_TRUE, vk::su::FenceTimeout ) )
;
vk::Result result =
presentQueue.presentKHR( vk::PresentInfoKHR( {}, *swapChainData.swapChain, currentBuffer.value ) );
presentQueue.presentKHR( vk::PresentInfoKHR( {}, swapChainData.swapChain, currentBuffer.value ) );
switch ( result )
{
case vk::Result::eSuccess: break;
@@ -370,7 +367,7 @@ int main( int /*argc*/, char ** /*argv*/ )
// Store away the cache that we've populated. This could conceivably happen
// earlier, depends on when the pipeline cache stops being populated
// internally.
std::vector<uint8_t> endCacheData = device->getPipelineCacheData( pipelineCache.get() );
std::vector<uint8_t> endCacheData = device.getPipelineCacheData( pipelineCache );
// Write the file to disk, overwriting whatever was there
std::ofstream writeCacheStream( cacheFileName, std::ios_base::out | std::ios_base::binary );
@@ -387,6 +384,33 @@ int main( int /*argc*/, char ** /*argv*/ )
}
/* VULKAN_KEY_END */
device.destroyFence( drawFence );
device.destroySemaphore( imageAcquiredSemaphore );
device.destroyPipeline( graphicsPipeline );
device.destroyPipelineCache( pipelineCache );
device.freeDescriptorSets( descriptorPool, descriptorSet );
device.destroyDescriptorPool( descriptorPool );
vertexBufferData.clear( device );
for ( auto framebuffer : framebuffers )
{
device.destroyFramebuffer( framebuffer );
}
device.destroyShaderModule( fragmentShaderModule );
device.destroyShaderModule( vertexShaderModule );
device.destroyRenderPass( renderPass );
device.destroyPipelineLayout( pipelineLayout );
device.destroyDescriptorSetLayout( descriptorSetLayout );
uniformBufferData.clear( device );
textureData.clear( device );
depthBufferData.clear( device );
swapChainData.clear( device );
device.freeCommandBuffers( commandPool, commandBuffer );
device.destroyCommandPool( commandPool );
device.destroy();
instance.destroySurfaceKHR( surfaceData.surface );
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -23,6 +23,7 @@
#else
// unknow compiler... just ignore the warnings for yourselves ;)
#endif
#include "../utils/geometries.hpp"
#include "../utils/math.hpp"
#include "../utils/shaders.hpp"
@@ -39,70 +40,70 @@ int main( int /*argc*/, char ** /*argv*/ )
{
try
{
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
vk::Instance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
vk::PhysicalDevice physicalDevice = instance->enumeratePhysicalDevices().front();
vk::PhysicalDevice physicalDevice = instance.enumeratePhysicalDevices().front();
vk::su::SurfaceData surfaceData( instance, AppName, vk::Extent2D( 500, 500 ) );
std::pair<uint32_t, uint32_t> graphicsAndPresentQueueFamilyIndex =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, *surfaceData.surface );
vk::UniqueDevice device =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, surfaceData.surface );
vk::Device device =
vk::su::createDevice( physicalDevice, graphicsAndPresentQueueFamilyIndex.first, vk::su::getDeviceExtensions() );
vk::UniqueCommandPool commandPool = vk::su::createCommandPool( device, graphicsAndPresentQueueFamilyIndex.first );
vk::UniqueCommandBuffer commandBuffer = std::move( device
->allocateCommandBuffersUnique( vk::CommandBufferAllocateInfo(
commandPool.get(), vk::CommandBufferLevel::ePrimary, 1 ) )
.front() );
vk::CommandPool commandPool = vk::su::createCommandPool( device, graphicsAndPresentQueueFamilyIndex.first );
vk::CommandBuffer commandBuffer =
device.allocateCommandBuffers( vk::CommandBufferAllocateInfo( commandPool, vk::CommandBufferLevel::ePrimary, 1 ) )
.front();
vk::Queue graphicsQueue = device->getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
vk::Queue presentQueue = device->getQueue( graphicsAndPresentQueueFamilyIndex.second, 0 );
vk::Queue graphicsQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
vk::Queue presentQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.second, 0 );
vk::su::SwapChainData swapChainData( physicalDevice,
device,
*surfaceData.surface,
surfaceData.surface,
surfaceData.extent,
vk::ImageUsageFlagBits::eColorAttachment |
vk::ImageUsageFlagBits::eTransferSrc,
vk::UniqueSwapchainKHR(),
{},
graphicsAndPresentQueueFamilyIndex.first,
graphicsAndPresentQueueFamilyIndex.second );
vk::su::DepthBufferData depthBufferData( physicalDevice, device, vk::Format::eD16Unorm, surfaceData.extent );
vk::su::TextureData textureData( physicalDevice, device );
commandBuffer->begin( vk::CommandBufferBeginInfo() );
commandBuffer.begin( vk::CommandBufferBeginInfo() );
textureData.setImage( device, commandBuffer, vk::su::CheckerboardImageGenerator() );
vk::su::BufferData uniformBufferData(
physicalDevice, device, sizeof( glm::mat4x4 ), vk::BufferUsageFlagBits::eUniformBuffer );
vk::su::copyToDevice(
device, uniformBufferData.deviceMemory, vk::su::createModelViewProjectionClipMatrix( surfaceData.extent ) );
glm::mat4x4 mvpcMatrix = vk::su::createModelViewProjectionClipMatrix( surfaceData.extent );
vk::su::copyToDevice( device, uniformBufferData.deviceMemory, mvpcMatrix );
vk::UniqueDescriptorSetLayout descriptorSetLayout = vk::su::createDescriptorSetLayout(
vk::DescriptorSetLayout descriptorSetLayout = vk::su::createDescriptorSetLayout(
device,
{ { vk::DescriptorType::eUniformBuffer, 1, vk::ShaderStageFlagBits::eVertex },
{ vk::DescriptorType::eCombinedImageSampler, 1, vk::ShaderStageFlagBits::eFragment } } );
vk::UniquePipelineLayout pipelineLayout = device->createPipelineLayoutUnique(
vk::PipelineLayoutCreateInfo( vk::PipelineLayoutCreateFlags(), *descriptorSetLayout ) );
vk::PipelineLayout pipelineLayout = device.createPipelineLayout(
vk::PipelineLayoutCreateInfo( vk::PipelineLayoutCreateFlags(), descriptorSetLayout ) );
vk::UniqueRenderPass renderPass = vk::su::createRenderPass(
vk::RenderPass renderPass = vk::su::createRenderPass(
device,
vk::su::pickSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( surfaceData.surface.get() ) ).format,
vk::su::pickSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( surfaceData.surface ) ).format,
depthBufferData.format );
glslang::InitializeProcess();
vk::UniqueShaderModule vertexShaderModule =
vk::ShaderModule vertexShaderModule =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eVertex, vertexShaderText_PT_T );
vk::UniqueShaderModule fragmentShaderModule =
vk::ShaderModule fragmentShaderModule =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eFragment, fragmentShaderText_T_C );
glslang::FinalizeProcess();
std::vector<vk::UniqueFramebuffer> framebuffers = vk::su::createFramebuffers(
std::vector<vk::Framebuffer> framebuffers = vk::su::createFramebuffers(
device, renderPass, swapChainData.imageViews, depthBufferData.imageView, surfaceData.extent );
vk::su::BufferData vertexBufferData(
@@ -112,16 +113,15 @@ int main( int /*argc*/, char ** /*argv*/ )
texturedCubeData,
sizeof( texturedCubeData ) / sizeof( texturedCubeData[0] ) );
vk::UniqueDescriptorPool descriptorPool = vk::su::createDescriptorPool(
vk::DescriptorPool descriptorPool = vk::su::createDescriptorPool(
device, { { vk::DescriptorType::eUniformBuffer, 1 }, { vk::DescriptorType::eCombinedImageSampler, 1 } } );
vk::UniqueDescriptorSet descriptorSet = std::move(
device->allocateDescriptorSetsUnique( vk::DescriptorSetAllocateInfo( *descriptorPool, *descriptorSetLayout ) )
.front() );
vk::DescriptorSetAllocateInfo descriptorSetAllocateInfo( descriptorPool, descriptorSetLayout );
vk::DescriptorSet descriptorSet = device.allocateDescriptorSets( descriptorSetAllocateInfo ).front();
vk::su::updateDescriptorSets(
device, descriptorSet, { { vk::DescriptorType::eUniformBuffer, uniformBufferData.buffer, {} } }, textureData );
vk::UniquePipelineCache pipelineCache = device->createPipelineCacheUnique( vk::PipelineCacheCreateInfo() );
vk::PipelineCache pipelineCache = device.createPipelineCache( vk::PipelineCacheCreateInfo() );
/* VULKAN_KEY_START */
@@ -132,9 +132,9 @@ int main( int /*argc*/, char ** /*argv*/ )
std::array<vk::PipelineShaderStageCreateInfo, 2> pipelineShaderStageCreateInfos = {
vk::PipelineShaderStageCreateInfo(
vk::PipelineShaderStageCreateFlags(), vk::ShaderStageFlagBits::eVertex, vertexShaderModule.get(), "main" ),
vk::PipelineShaderStageCreateFlags(), vk::ShaderStageFlagBits::eVertex, vertexShaderModule, "main" ),
vk::PipelineShaderStageCreateInfo(
vk::PipelineShaderStageCreateFlags(), vk::ShaderStageFlagBits::eFragment, fragmentShaderModule.get(), "main" )
vk::PipelineShaderStageCreateFlags(), vk::ShaderStageFlagBits::eFragment, fragmentShaderModule, "main" )
};
vk::VertexInputBindingDescription vertexInputBindingDescription( 0, sizeof( texturedCubeData[0] ) );
@@ -209,12 +209,12 @@ int main( int /*argc*/, char ** /*argv*/ )
&pipelineDepthStencilStateCreateInfo,
&pipelineColorBlendStateCreateInfo,
&pipelineDynamicStateCreateInfo,
pipelineLayout.get(),
renderPass.get() );
pipelineLayout,
renderPass );
vk::UniquePipeline basePipeline;
vk::ResultValue<vk::UniquePipeline> rvPipeline =
device->createGraphicsPipelineUnique( pipelineCache.get(), graphicsPipelineCreateInfo );
vk::Pipeline basePipeline;
vk::ResultValue<vk::Pipeline> rvPipeline =
device.createGraphicsPipeline( pipelineCache, graphicsPipelineCreateInfo );
switch ( rvPipeline.result )
{
case vk::Result::eSuccess: basePipeline = std::move( rvPipeline.value ); break;
@@ -241,20 +241,20 @@ void main()
// Convert GLSL to SPIR-V
glslang::InitializeProcess();
vk::UniqueShaderModule fragmentShaderModule2 =
vk::ShaderModule fragmentShaderModule2 =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eFragment, fragmentShaderText_T_C_2 );
glslang::FinalizeProcess();
// Modify pipeline info to reflect derivation
pipelineShaderStageCreateInfos[1] = vk::PipelineShaderStageCreateInfo(
vk::PipelineShaderStageCreateFlags(), vk::ShaderStageFlagBits::eFragment, fragmentShaderModule2.get(), "main" );
vk::PipelineShaderStageCreateFlags(), vk::ShaderStageFlagBits::eFragment, fragmentShaderModule2, "main" );
graphicsPipelineCreateInfo.flags = vk::PipelineCreateFlagBits::eDerivative;
graphicsPipelineCreateInfo.basePipelineHandle = basePipeline.get();
graphicsPipelineCreateInfo.basePipelineHandle = basePipeline;
graphicsPipelineCreateInfo.basePipelineIndex = -1;
// And create the derived pipeline
vk::UniquePipeline derivedPipeline;
rvPipeline = device->createGraphicsPipelineUnique( *pipelineCache, graphicsPipelineCreateInfo );
vk::Pipeline derivedPipeline;
rvPipeline = device.createGraphicsPipeline( pipelineCache, graphicsPipelineCreateInfo );
switch ( rvPipeline.result )
{
case vk::Result::eSuccess: derivedPipeline = std::move( rvPipeline.value ); break;
@@ -266,12 +266,12 @@ void main()
/* VULKAN_KEY_END */
vk::UniqueSemaphore imageAcquiredSemaphore =
device->createSemaphoreUnique( vk::SemaphoreCreateInfo( vk::SemaphoreCreateFlags() ) );
vk::Semaphore imageAcquiredSemaphore =
device.createSemaphore( vk::SemaphoreCreateInfo( vk::SemaphoreCreateFlags() ) );
// Get the index of the next available swapchain image
vk::ResultValue<uint32_t> currentBuffer =
device->acquireNextImageKHR( swapChainData.swapChain.get(), UINT64_MAX, imageAcquiredSemaphore.get(), nullptr );
device.acquireNextImageKHR( swapChainData.swapChain, UINT64_MAX, imageAcquiredSemaphore, nullptr );
assert( currentBuffer.result == vk::Result::eSuccess );
assert( currentBuffer.value < framebuffers.size() );
@@ -279,40 +279,38 @@ void main()
clearValues[0].color = vk::ClearColorValue( std::array<float, 4>( { { 0.2f, 0.2f, 0.2f, 0.2f } } ) );
clearValues[1].depthStencil = vk::ClearDepthStencilValue( 1.0f, 0 );
commandBuffer->beginRenderPass( vk::RenderPassBeginInfo( renderPass.get(),
framebuffers[currentBuffer.value].get(),
vk::Rect2D( vk::Offset2D(), surfaceData.extent ),
clearValues ),
vk::SubpassContents::eInline );
commandBuffer->bindPipeline( vk::PipelineBindPoint::eGraphics, derivedPipeline.get() );
commandBuffer->bindDescriptorSets(
vk::PipelineBindPoint::eGraphics, pipelineLayout.get(), 0, descriptorSet.get(), {} );
commandBuffer.beginRenderPass(
vk::RenderPassBeginInfo(
renderPass, framebuffers[currentBuffer.value], vk::Rect2D( vk::Offset2D(), surfaceData.extent ), clearValues ),
vk::SubpassContents::eInline );
commandBuffer.bindPipeline( vk::PipelineBindPoint::eGraphics, derivedPipeline );
commandBuffer.bindDescriptorSets( vk::PipelineBindPoint::eGraphics, pipelineLayout, 0, descriptorSet, {} );
commandBuffer->bindVertexBuffers( 0, *vertexBufferData.buffer, { 0 } );
commandBuffer->setViewport( 0,
vk::Viewport( 0.0f,
0.0f,
static_cast<float>( surfaceData.extent.width ),
static_cast<float>( surfaceData.extent.height ),
0.0f,
1.0f ) );
commandBuffer->setScissor( 0, vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ) );
commandBuffer.bindVertexBuffers( 0, vertexBufferData.buffer, { 0 } );
commandBuffer.setViewport( 0,
vk::Viewport( 0.0f,
0.0f,
static_cast<float>( surfaceData.extent.width ),
static_cast<float>( surfaceData.extent.height ),
0.0f,
1.0f ) );
commandBuffer.setScissor( 0, vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ) );
commandBuffer->draw( 12 * 3, 1, 0, 0 );
commandBuffer->endRenderPass();
commandBuffer->end();
commandBuffer.draw( 12 * 3, 1, 0, 0 );
commandBuffer.endRenderPass();
commandBuffer.end();
vk::UniqueFence drawFence = device->createFenceUnique( vk::FenceCreateInfo() );
vk::Fence drawFence = device.createFence( vk::FenceCreateInfo() );
vk::PipelineStageFlags waitDestinationStageMask( vk::PipelineStageFlagBits::eColorAttachmentOutput );
vk::SubmitInfo submitInfo( *imageAcquiredSemaphore, waitDestinationStageMask, *commandBuffer );
graphicsQueue.submit( submitInfo, drawFence.get() );
vk::SubmitInfo submitInfo( imageAcquiredSemaphore, waitDestinationStageMask, commandBuffer );
graphicsQueue.submit( submitInfo, drawFence );
while ( vk::Result::eTimeout == device->waitForFences( drawFence.get(), VK_TRUE, vk::su::FenceTimeout ) )
while ( vk::Result::eTimeout == device.waitForFences( drawFence, VK_TRUE, vk::su::FenceTimeout ) )
;
vk::Result result =
presentQueue.presentKHR( vk::PresentInfoKHR( {}, *swapChainData.swapChain, currentBuffer.value ) );
presentQueue.presentKHR( vk::PresentInfoKHR( {}, swapChainData.swapChain, currentBuffer.value ) );
switch ( result )
{
case vk::Result::eSuccess: break;
@@ -322,6 +320,35 @@ void main()
default: assert( false ); // an unexpected result is returned !
}
std::this_thread::sleep_for( std::chrono::milliseconds( 1000 ) );
device.destroyFence( drawFence );
device.destroySemaphore( imageAcquiredSemaphore );
device.destroyShaderModule( fragmentShaderModule2 );
device.destroyPipeline( derivedPipeline );
device.destroyPipeline( basePipeline );
device.destroyPipelineCache( pipelineCache );
device.freeDescriptorSets( descriptorPool, descriptorSet );
device.destroyDescriptorPool( descriptorPool );
vertexBufferData.clear( device );
for ( auto framebuffer : framebuffers )
{
device.destroyFramebuffer( framebuffer );
}
device.destroyShaderModule( fragmentShaderModule );
device.destroyShaderModule( vertexShaderModule );
device.destroyRenderPass( renderPass );
device.destroyPipelineLayout( pipelineLayout );
device.destroyDescriptorSetLayout( descriptorSetLayout );
uniformBufferData.clear( device );
textureData.clear( device );
depthBufferData.clear( device );
swapChainData.clear( device );
device.freeCommandBuffers( commandPool, commandBuffer );
device.destroyCommandPool( commandPool );
device.destroy();
instance.destroySurfaceKHR( surfaceData.surface );
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -81,36 +81,36 @@ int main( int /*argc*/, char ** /*argv*/ )
{
try
{
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
vk::Instance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
vk::PhysicalDevice physicalDevice = instance->enumeratePhysicalDevices().front();
vk::PhysicalDevice physicalDevice = instance.enumeratePhysicalDevices().front();
vk::su::SurfaceData surfaceData( instance, AppName, vk::Extent2D( 500, 500 ) );
std::pair<uint32_t, uint32_t> graphicsAndPresentQueueFamilyIndex =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, *surfaceData.surface );
vk::UniqueDevice device =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, surfaceData.surface );
vk::Device device =
vk::su::createDevice( physicalDevice, graphicsAndPresentQueueFamilyIndex.first, vk::su::getDeviceExtensions() );
vk::UniqueCommandPool commandPool = vk::su::createCommandPool( device, graphicsAndPresentQueueFamilyIndex.first );
vk::UniqueCommandBuffer commandBuffer = std::move( device
->allocateCommandBuffersUnique( vk::CommandBufferAllocateInfo(
commandPool.get(), vk::CommandBufferLevel::ePrimary, 1 ) )
.front() );
vk::CommandPool commandPool = vk::su::createCommandPool( device, graphicsAndPresentQueueFamilyIndex.first );
vk::CommandBuffer commandBuffer =
device.allocateCommandBuffers( vk::CommandBufferAllocateInfo( commandPool, vk::CommandBufferLevel::ePrimary, 1 ) )
.front();
vk::Queue graphicsQueue = device->getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
vk::Queue presentQueue = device->getQueue( graphicsAndPresentQueueFamilyIndex.second, 0 );
vk::Queue graphicsQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
vk::Queue presentQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.second, 0 );
vk::su::SwapChainData swapChainData( physicalDevice,
device,
*surfaceData.surface,
surfaceData.surface,
surfaceData.extent,
vk::ImageUsageFlagBits::eColorAttachment |
vk::ImageUsageFlagBits::eTransferSrc,
vk::UniqueSwapchainKHR(),
{},
graphicsAndPresentQueueFamilyIndex.first,
graphicsAndPresentQueueFamilyIndex.second );
@@ -118,22 +118,22 @@ int main( int /*argc*/, char ** /*argv*/ )
vk::su::BufferData uniformBufferData(
physicalDevice, device, sizeof( glm::mat4x4 ), vk::BufferUsageFlagBits::eUniformBuffer );
vk::su::copyToDevice(
device, uniformBufferData.deviceMemory, vk::su::createModelViewProjectionClipMatrix( surfaceData.extent ) );
glm::mat4x4 mvpcMatrix = vk::su::createModelViewProjectionClipMatrix( surfaceData.extent );
vk::su::copyToDevice( device, uniformBufferData.deviceMemory, mvpcMatrix );
vk::UniqueRenderPass renderPass = vk::su::createRenderPass(
vk::RenderPass renderPass = vk::su::createRenderPass(
device,
vk::su::pickSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( surfaceData.surface.get() ) ).format,
vk::su::pickSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( surfaceData.surface ) ).format,
depthBufferData.format );
glslang::InitializeProcess();
vk::UniqueShaderModule vertexShaderModule =
vk::ShaderModule vertexShaderModule =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eVertex, vertexShaderText_PT_T );
vk::UniqueShaderModule fragmentShaderModule =
vk::ShaderModule fragmentShaderModule =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eFragment, fragmentShaderText );
glslang::FinalizeProcess();
std::vector<vk::UniqueFramebuffer> framebuffers = vk::su::createFramebuffers(
std::vector<vk::Framebuffer> framebuffers = vk::su::createFramebuffers(
device, renderPass, swapChainData.imageViews, depthBufferData.imageView, surfaceData.extent );
vk::su::BufferData vertexBufferData(
@@ -145,32 +145,32 @@ int main( int /*argc*/, char ** /*argv*/ )
// Create binding and layout for the following, matching contents of shader
// binding 0 = uniform buffer (MVP)
vk::UniqueDescriptorSetLayout descriptorSetLayout = vk::su::createDescriptorSetLayout(
vk::DescriptorSetLayout descriptorSetLayout = vk::su::createDescriptorSetLayout(
device, { { vk::DescriptorType::eUniformBuffer, 1, vk::ShaderStageFlagBits::eVertex } } );
/* VULKAN_KEY_START */
// Set up our push constant range, which mirrors the declaration of
vk::PushConstantRange pushConstantRanges( vk::ShaderStageFlagBits::eFragment, 0, 8 );
vk::UniquePipelineLayout pipelineLayout = device->createPipelineLayoutUnique(
vk::PipelineLayoutCreateInfo( vk::PipelineLayoutCreateFlags(), *descriptorSetLayout, pushConstantRanges ) );
vk::PushConstantRange pushConstantRanges( vk::ShaderStageFlagBits::eFragment, 0, 8 );
vk::PipelineLayout pipelineLayout = device.createPipelineLayout(
vk::PipelineLayoutCreateInfo( vk::PipelineLayoutCreateFlags(), descriptorSetLayout, pushConstantRanges ) );
// Create a single pool to contain data for our descriptor set
std::array<vk::DescriptorPoolSize, 2> poolSizes = { vk::DescriptorPoolSize( vk::DescriptorType::eUniformBuffer, 1 ),
vk::DescriptorPoolSize(
vk::DescriptorType::eCombinedImageSampler, 1 ) };
vk::UniqueDescriptorPool descriptorPool = device->createDescriptorPoolUnique(
vk::DescriptorPool descriptorPool = device.createDescriptorPool(
vk::DescriptorPoolCreateInfo( vk::DescriptorPoolCreateFlagBits::eFreeDescriptorSet, 1, poolSizes ) );
// Populate descriptor sets
vk::UniqueDescriptorSet descriptorSet = std::move(
device->allocateDescriptorSetsUnique( vk::DescriptorSetAllocateInfo( *descriptorPool, *descriptorSetLayout ) )
.front() );
vk::DescriptorSetAllocateInfo descriptorSetAllocateInfo( descriptorPool, descriptorSetLayout );
vk::DescriptorSet descriptorSet = device.allocateDescriptorSets( descriptorSetAllocateInfo ).front();
// Populate with info about our uniform buffer for MVP
vk::DescriptorBufferInfo bufferInfo( uniformBufferData.buffer.get(), 0, sizeof( glm::mat4x4 ) );
device->updateDescriptorSets(
vk::WriteDescriptorSet( *descriptorSet, 0, 0, vk::DescriptorType::eUniformBuffer, {}, bufferInfo ), {} );
vk::DescriptorBufferInfo bufferInfo( uniformBufferData.buffer, 0, sizeof( glm::mat4x4 ) );
vk::WriteDescriptorSet writeDescriptorSet(
descriptorSet, 0, 0, vk::DescriptorType::eUniformBuffer, {}, bufferInfo );
device.updateDescriptorSets( writeDescriptorSet, nullptr );
// Create our push constant data, which matches shader expectations
std::array<unsigned, 2> pushConstants = { { (unsigned)2, (unsigned)0x3F800000 } };
@@ -178,18 +178,17 @@ int main( int /*argc*/, char ** /*argv*/ )
// Ensure we have enough room for push constant data
assert( ( sizeof( pushConstants ) <= physicalDevice.getProperties().limits.maxPushConstantsSize ) &&
"Too many push constants" );
commandBuffer->begin( vk::CommandBufferBeginInfo() );
commandBuffer->pushConstants<unsigned>(
pipelineLayout.get(), vk::ShaderStageFlagBits::eFragment, 0, pushConstants );
commandBuffer.begin( vk::CommandBufferBeginInfo() );
commandBuffer.pushConstants<unsigned>( pipelineLayout, vk::ShaderStageFlagBits::eFragment, 0, pushConstants );
/* VULKAN_KEY_END */
vk::UniquePipelineCache pipelineCache = device->createPipelineCacheUnique( vk::PipelineCacheCreateInfo() );
vk::UniquePipeline graphicsPipeline = vk::su::createGraphicsPipeline(
vk::PipelineCache pipelineCache = device.createPipelineCache( vk::PipelineCacheCreateInfo() );
vk::Pipeline graphicsPipeline = vk::su::createGraphicsPipeline(
device,
pipelineCache,
std::make_pair( *vertexShaderModule, nullptr ),
std::make_pair( *fragmentShaderModule, nullptr ),
std::make_pair( vertexShaderModule, nullptr ),
std::make_pair( fragmentShaderModule, nullptr ),
sizeof( texturedCubeData[0] ),
{ { vk::Format::eR32G32B32A32Sfloat, 0 }, { vk::Format::eR32G32B32A32Sfloat, 16 } },
vk::FrontFace::eClockwise,
@@ -197,9 +196,9 @@ int main( int /*argc*/, char ** /*argv*/ )
pipelineLayout,
renderPass );
vk::UniqueSemaphore imageAcquiredSemaphore = device->createSemaphoreUnique( vk::SemaphoreCreateInfo() );
vk::ResultValue<uint32_t> currentBuffer = device->acquireNextImageKHR(
swapChainData.swapChain.get(), vk::su::FenceTimeout, imageAcquiredSemaphore.get(), nullptr );
vk::Semaphore imageAcquiredSemaphore = device.createSemaphore( vk::SemaphoreCreateInfo() );
vk::ResultValue<uint32_t> currentBuffer =
device.acquireNextImageKHR( swapChainData.swapChain, vk::su::FenceTimeout, imageAcquiredSemaphore, nullptr );
assert( currentBuffer.result == vk::Result::eSuccess );
assert( currentBuffer.value < framebuffers.size() );
@@ -207,40 +206,39 @@ int main( int /*argc*/, char ** /*argv*/ )
clearValues[0].color = vk::ClearColorValue( std::array<float, 4>( { { 0.2f, 0.2f, 0.2f, 0.2f } } ) );
clearValues[1].depthStencil = vk::ClearDepthStencilValue( 1.0f, 0 );
vk::RenderPassBeginInfo renderPassBeginInfo( renderPass.get(),
framebuffers[currentBuffer.value].get(),
vk::RenderPassBeginInfo renderPassBeginInfo( renderPass,
framebuffers[currentBuffer.value],
vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ),
clearValues );
commandBuffer->beginRenderPass( renderPassBeginInfo, vk::SubpassContents::eInline );
commandBuffer->bindPipeline( vk::PipelineBindPoint::eGraphics, graphicsPipeline.get() );
commandBuffer->bindDescriptorSets(
vk::PipelineBindPoint::eGraphics, pipelineLayout.get(), 0, descriptorSet.get(), nullptr );
commandBuffer.beginRenderPass( renderPassBeginInfo, vk::SubpassContents::eInline );
commandBuffer.bindPipeline( vk::PipelineBindPoint::eGraphics, graphicsPipeline );
commandBuffer.bindDescriptorSets( vk::PipelineBindPoint::eGraphics, pipelineLayout, 0, descriptorSet, nullptr );
commandBuffer->bindVertexBuffers( 0, *vertexBufferData.buffer, { 0 } );
commandBuffer->setViewport( 0,
vk::Viewport( 0.0f,
0.0f,
static_cast<float>( surfaceData.extent.width ),
static_cast<float>( surfaceData.extent.height ),
0.0f,
1.0f ) );
commandBuffer->setScissor( 0, vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ) );
commandBuffer.bindVertexBuffers( 0, vertexBufferData.buffer, { 0 } );
commandBuffer.setViewport( 0,
vk::Viewport( 0.0f,
0.0f,
static_cast<float>( surfaceData.extent.width ),
static_cast<float>( surfaceData.extent.height ),
0.0f,
1.0f ) );
commandBuffer.setScissor( 0, vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ) );
commandBuffer->draw( 12 * 3, 1, 0, 0 );
commandBuffer->endRenderPass();
commandBuffer->end();
commandBuffer.draw( 12 * 3, 1, 0, 0 );
commandBuffer.endRenderPass();
commandBuffer.end();
vk::UniqueFence drawFence = device->createFenceUnique( vk::FenceCreateInfo() );
vk::Fence drawFence = device.createFence( vk::FenceCreateInfo() );
vk::PipelineStageFlags waitDestinationStageMask( vk::PipelineStageFlagBits::eColorAttachmentOutput );
vk::SubmitInfo submitInfo( *imageAcquiredSemaphore, waitDestinationStageMask, *commandBuffer );
graphicsQueue.submit( submitInfo, drawFence.get() );
vk::SubmitInfo submitInfo( imageAcquiredSemaphore, waitDestinationStageMask, commandBuffer );
graphicsQueue.submit( submitInfo, drawFence );
while ( vk::Result::eTimeout == device->waitForFences( drawFence.get(), VK_TRUE, vk::su::FenceTimeout ) )
while ( vk::Result::eTimeout == device.waitForFences( drawFence, VK_TRUE, vk::su::FenceTimeout ) )
;
vk::Result result =
presentQueue.presentKHR( vk::PresentInfoKHR( {}, *swapChainData.swapChain, currentBuffer.value ) );
presentQueue.presentKHR( vk::PresentInfoKHR( {}, swapChainData.swapChain, currentBuffer.value ) );
switch ( result )
{
case vk::Result::eSuccess: break;
@@ -250,6 +248,32 @@ int main( int /*argc*/, char ** /*argv*/ )
default: assert( false ); // an unexpected result is returned !
}
std::this_thread::sleep_for( std::chrono::milliseconds( 1000 ) );
device.destroyFence( drawFence );
device.destroySemaphore( imageAcquiredSemaphore );
device.destroyPipeline( graphicsPipeline );
device.destroyPipelineCache( pipelineCache );
device.freeDescriptorSets( descriptorPool, descriptorSet );
device.destroyDescriptorPool( descriptorPool );
vertexBufferData.clear( device );
for ( auto framebuffer : framebuffers )
{
device.destroyFramebuffer( framebuffer );
}
device.destroyShaderModule( fragmentShaderModule );
device.destroyShaderModule( vertexShaderModule );
device.destroyRenderPass( renderPass );
device.destroyPipelineLayout( pipelineLayout );
device.destroyDescriptorSetLayout( descriptorSetLayout );
uniformBufferData.clear( device );
depthBufferData.clear( device );
swapChainData.clear( device );
device.freeCommandBuffers( commandPool, commandBuffer );
device.destroyCommandPool( commandPool );
device.destroy();
instance.destroySurfaceKHR( surfaceData.surface );
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -44,9 +44,11 @@ int main( int /*argc*/, char ** /*argv*/ )
// To use PUSH_DESCRIPTOR, you must also specify GET_PHYSICAL_DEVICE_PROPERTIES_2
std::vector<vk::ExtensionProperties> extensionProperties = vk::enumerateInstanceExtensionProperties();
if ( std::find_if( extensionProperties.begin(), extensionProperties.end(), []( vk::ExtensionProperties ep ) {
return ( strcmp( ep.extensionName, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME ) == 0 );
} ) == extensionProperties.end() )
auto propertyIterator =
std::find_if( extensionProperties.begin(), extensionProperties.end(), []( vk::ExtensionProperties ep ) {
return ( strcmp( ep.extensionName, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME ) == 0 );
} );
if ( propertyIterator == extensionProperties.end() )
{
std::cout << "No GET_PHYSICAL_DEVICE_PROPERTIES_2 extension" << std::endl;
return 0;
@@ -55,18 +57,21 @@ int main( int /*argc*/, char ** /*argv*/ )
std::vector<std::string> instanceExtensions = vk::su::getInstanceExtensions();
instanceExtensions.push_back( VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME );
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName, {}, instanceExtensions );
vk::Instance instance = vk::su::createInstance( AppName, EngineName, {}, instanceExtensions );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
vk::PhysicalDevice physicalDevice = instance->enumeratePhysicalDevices().front();
vk::PhysicalDevice physicalDevice = instance.enumeratePhysicalDevices().front();
// Once instance is created, need to make sure the extension is available
extensionProperties = physicalDevice.enumerateDeviceExtensionProperties();
if ( std::find_if( extensionProperties.begin(), extensionProperties.end(), []( vk::ExtensionProperties ep ) {
return ( strcmp( ep.extensionName, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME ) == 0 );
} ) == extensionProperties.end() )
propertyIterator =
std::find_if( extensionProperties.begin(), extensionProperties.end(), []( vk::ExtensionProperties ep ) {
return ( strcmp( ep.extensionName, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME ) == 0 );
} );
if ( propertyIterator == extensionProperties.end() )
{
std::cout << "No extension for push descriptors" << std::endl;
return 0;
@@ -78,62 +83,61 @@ int main( int /*argc*/, char ** /*argv*/ )
vk::su::SurfaceData surfaceData( instance, AppName, vk::Extent2D( 500, 500 ) );
std::pair<uint32_t, uint32_t> graphicsAndPresentQueueFamilyIndex =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, *surfaceData.surface );
vk::UniqueDevice device =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, surfaceData.surface );
vk::Device device =
vk::su::createDevice( physicalDevice, graphicsAndPresentQueueFamilyIndex.first, deviceExtensions );
vk::UniqueCommandPool commandPool = vk::su::createCommandPool( device, graphicsAndPresentQueueFamilyIndex.first );
vk::UniqueCommandBuffer commandBuffer = std::move( device
->allocateCommandBuffersUnique( vk::CommandBufferAllocateInfo(
commandPool.get(), vk::CommandBufferLevel::ePrimary, 1 ) )
.front() );
vk::CommandPool commandPool = vk::su::createCommandPool( device, graphicsAndPresentQueueFamilyIndex.first );
vk::CommandBuffer commandBuffer =
device.allocateCommandBuffers( vk::CommandBufferAllocateInfo( commandPool, vk::CommandBufferLevel::ePrimary, 1 ) )
.front();
vk::Queue graphicsQueue = device->getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
vk::Queue presentQueue = device->getQueue( graphicsAndPresentQueueFamilyIndex.second, 0 );
vk::Queue graphicsQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
vk::Queue presentQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.second, 0 );
vk::su::SwapChainData swapChainData( physicalDevice,
device,
*surfaceData.surface,
surfaceData.surface,
surfaceData.extent,
vk::ImageUsageFlagBits::eColorAttachment |
vk::ImageUsageFlagBits::eTransferSrc,
vk::UniqueSwapchainKHR(),
{},
graphicsAndPresentQueueFamilyIndex.first,
graphicsAndPresentQueueFamilyIndex.second );
vk::su::DepthBufferData depthBufferData( physicalDevice, device, vk::Format::eD16Unorm, surfaceData.extent );
vk::su::TextureData textureData( physicalDevice, device );
commandBuffer->begin( vk::CommandBufferBeginInfo() );
commandBuffer.begin( vk::CommandBufferBeginInfo() );
textureData.setImage( device, commandBuffer, vk::su::CheckerboardImageGenerator() );
vk::su::BufferData uniformBufferData(
physicalDevice, device, sizeof( glm::mat4x4 ), vk::BufferUsageFlagBits::eUniformBuffer );
vk::su::copyToDevice(
device, uniformBufferData.deviceMemory, vk::su::createModelViewProjectionClipMatrix( surfaceData.extent ) );
glm::mat4x4 mvpcMatrix = vk::su::createModelViewProjectionClipMatrix( surfaceData.extent );
vk::su::copyToDevice( device, uniformBufferData.deviceMemory, mvpcMatrix );
// Need to specify that descriptor set layout will be for push descriptors
vk::UniqueDescriptorSetLayout descriptorSetLayout = vk::su::createDescriptorSetLayout(
vk::DescriptorSetLayout descriptorSetLayout = vk::su::createDescriptorSetLayout(
device,
{ { vk::DescriptorType::eUniformBuffer, 1, vk::ShaderStageFlagBits::eVertex },
{ vk::DescriptorType::eCombinedImageSampler, 1, vk::ShaderStageFlagBits::eFragment } },
vk::DescriptorSetLayoutCreateFlagBits::ePushDescriptorKHR );
vk::UniquePipelineLayout pipelineLayout = device->createPipelineLayoutUnique(
vk::PipelineLayoutCreateInfo( vk::PipelineLayoutCreateFlags(), *descriptorSetLayout ) );
vk::PipelineLayout pipelineLayout = device.createPipelineLayout(
vk::PipelineLayoutCreateInfo( vk::PipelineLayoutCreateFlags(), descriptorSetLayout ) );
vk::UniqueRenderPass renderPass = vk::su::createRenderPass(
vk::RenderPass renderPass = vk::su::createRenderPass(
device,
vk::su::pickSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( surfaceData.surface.get() ) ).format,
vk::su::pickSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( surfaceData.surface ) ).format,
depthBufferData.format );
glslang::InitializeProcess();
vk::UniqueShaderModule vertexShaderModule =
vk::ShaderModule vertexShaderModule =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eVertex, vertexShaderText_PT_T );
vk::UniqueShaderModule fragmentShaderModule =
vk::ShaderModule fragmentShaderModule =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eFragment, fragmentShaderText_T_C );
glslang::FinalizeProcess();
std::vector<vk::UniqueFramebuffer> framebuffers = vk::su::createFramebuffers(
std::vector<vk::Framebuffer> framebuffers = vk::su::createFramebuffers(
device, renderPass, swapChainData.imageViews, depthBufferData.imageView, surfaceData.extent );
vk::su::BufferData vertexBufferData(
@@ -143,12 +147,12 @@ int main( int /*argc*/, char ** /*argv*/ )
texturedCubeData,
sizeof( texturedCubeData ) / sizeof( texturedCubeData[0] ) );
vk::UniquePipelineCache pipelineCache = device->createPipelineCacheUnique( vk::PipelineCacheCreateInfo() );
vk::UniquePipeline graphicsPipeline =
vk::PipelineCache pipelineCache = device.createPipelineCache( vk::PipelineCacheCreateInfo() );
vk::Pipeline graphicsPipeline =
vk::su::createGraphicsPipeline( device,
pipelineCache,
std::make_pair( *vertexShaderModule, nullptr ),
std::make_pair( *fragmentShaderModule, nullptr ),
std::make_pair( vertexShaderModule, nullptr ),
std::make_pair( fragmentShaderModule, nullptr ),
sizeof( texturedCubeData[0] ),
{ { vk::Format::eR32G32B32A32Sfloat, 0 }, { vk::Format::eR32G32Sfloat, 16 } },
vk::FrontFace::eClockwise,
@@ -157,60 +161,59 @@ int main( int /*argc*/, char ** /*argv*/ )
renderPass );
// Get the index of the next available swapchain image:
vk::UniqueSemaphore imageAcquiredSemaphore = device->createSemaphoreUnique( vk::SemaphoreCreateInfo() );
vk::ResultValue<uint32_t> currentBuffer = device->acquireNextImageKHR(
swapChainData.swapChain.get(), vk::su::FenceTimeout, imageAcquiredSemaphore.get(), nullptr );
vk::Semaphore imageAcquiredSemaphore = device.createSemaphore( vk::SemaphoreCreateInfo() );
vk::ResultValue<uint32_t> currentBuffer =
device.acquireNextImageKHR( swapChainData.swapChain, vk::su::FenceTimeout, imageAcquiredSemaphore, nullptr );
assert( currentBuffer.result == vk::Result::eSuccess );
assert( currentBuffer.value < framebuffers.size() );
std::array<vk::ClearValue, 2> clearValues;
clearValues[0].color = vk::ClearColorValue( std::array<float, 4>( { { 0.2f, 0.2f, 0.2f, 0.2f } } ) );
clearValues[1].depthStencil = vk::ClearDepthStencilValue( 1.0f, 0 );
vk::RenderPassBeginInfo renderPassBeginInfo( renderPass.get(),
framebuffers[currentBuffer.value].get(),
vk::RenderPassBeginInfo renderPassBeginInfo( renderPass,
framebuffers[currentBuffer.value],
vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ),
clearValues );
commandBuffer->beginRenderPass( renderPassBeginInfo, vk::SubpassContents::eInline );
commandBuffer->bindPipeline( vk::PipelineBindPoint::eGraphics, graphicsPipeline.get() );
commandBuffer.beginRenderPass( renderPassBeginInfo, vk::SubpassContents::eInline );
commandBuffer.bindPipeline( vk::PipelineBindPoint::eGraphics, graphicsPipeline );
vk::DescriptorBufferInfo bufferInfo( uniformBufferData.buffer.get(), 0, sizeof( glm::mat4x4 ) );
vk::DescriptorImageInfo imageInfo( textureData.textureSampler.get(),
textureData.imageData->imageView.get(),
vk::ImageLayout::eShaderReadOnlyOptimal );
vk::WriteDescriptorSet writeDescriptorSets[2] = {
vk::DescriptorBufferInfo bufferInfo( uniformBufferData.buffer, 0, sizeof( glm::mat4x4 ) );
vk::DescriptorImageInfo imageInfo(
textureData.sampler, textureData.imageData->imageView, vk::ImageLayout::eShaderReadOnlyOptimal );
vk::WriteDescriptorSet writeDescriptorSets[2] = {
vk::WriteDescriptorSet( {}, 0, 0, vk::DescriptorType::eUniformBuffer, {}, bufferInfo ),
vk::WriteDescriptorSet( {}, 1, 0, vk::DescriptorType::eCombinedImageSampler, imageInfo )
};
// this call is from an extension and needs the dynamic dispatcher !!
commandBuffer->pushDescriptorSetKHR(
vk::PipelineBindPoint::eGraphics, *pipelineLayout, 0, { 2, writeDescriptorSets } );
commandBuffer.pushDescriptorSetKHR(
vk::PipelineBindPoint::eGraphics, pipelineLayout, 0, { 2, writeDescriptorSets } );
commandBuffer->bindVertexBuffers( 0, *vertexBufferData.buffer, { 0 } );
commandBuffer->setViewport( 0,
vk::Viewport( 0.0f,
0.0f,
static_cast<float>( surfaceData.extent.width ),
static_cast<float>( surfaceData.extent.height ),
0.0f,
1.0f ) );
commandBuffer->setScissor( 0, vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ) );
commandBuffer.bindVertexBuffers( 0, vertexBufferData.buffer, { 0 } );
commandBuffer.setViewport( 0,
vk::Viewport( 0.0f,
0.0f,
static_cast<float>( surfaceData.extent.width ),
static_cast<float>( surfaceData.extent.height ),
0.0f,
1.0f ) );
commandBuffer.setScissor( 0, vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ) );
commandBuffer->draw( 12 * 3, 1, 0, 0 );
commandBuffer->endRenderPass();
commandBuffer->end();
commandBuffer.draw( 12 * 3, 1, 0, 0 );
commandBuffer.endRenderPass();
commandBuffer.end();
vk::UniqueFence drawFence = device->createFenceUnique( vk::FenceCreateInfo() );
vk::Fence drawFence = device.createFence( vk::FenceCreateInfo() );
vk::PipelineStageFlags waitDestinationStageMask( vk::PipelineStageFlagBits::eColorAttachmentOutput );
vk::SubmitInfo submitInfo( *imageAcquiredSemaphore, waitDestinationStageMask, *commandBuffer );
graphicsQueue.submit( submitInfo, drawFence.get() );
vk::SubmitInfo submitInfo( imageAcquiredSemaphore, waitDestinationStageMask, commandBuffer );
graphicsQueue.submit( submitInfo, drawFence );
while ( vk::Result::eTimeout == device->waitForFences( drawFence.get(), VK_TRUE, vk::su::FenceTimeout ) )
while ( vk::Result::eTimeout == device.waitForFences( drawFence, VK_TRUE, vk::su::FenceTimeout ) )
;
vk::Result result =
presentQueue.presentKHR( vk::PresentInfoKHR( {}, *swapChainData.swapChain, currentBuffer.value ) );
presentQueue.presentKHR( vk::PresentInfoKHR( {}, swapChainData.swapChain, currentBuffer.value ) );
switch ( result )
{
case vk::Result::eSuccess: break;
@@ -223,7 +226,32 @@ int main( int /*argc*/, char ** /*argv*/ )
/* VULKAN_KEY_END */
device->waitIdle();
device.waitIdle();
device.destroyFence( drawFence );
device.destroySemaphore( imageAcquiredSemaphore );
device.destroyPipeline( graphicsPipeline );
device.destroyPipelineCache( pipelineCache );
vertexBufferData.clear( device );
for ( auto framebuffer : framebuffers )
{
device.destroyFramebuffer( framebuffer );
}
device.destroyShaderModule( fragmentShaderModule );
device.destroyShaderModule( vertexShaderModule );
device.destroyRenderPass( renderPass );
device.destroyPipelineLayout( pipelineLayout );
device.destroyDescriptorSetLayout( descriptorSetLayout );
textureData.clear( device );
uniformBufferData.clear( device );
depthBufferData.clear( device );
swapChainData.clear( device );
device.freeCommandBuffers( commandPool, commandBuffer );
device.destroyCommandPool( commandPool );
device.destroy();
instance.destroySurfaceKHR( surfaceData.surface );
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -81,16 +81,33 @@ static_assert( sizeof( GeometryInstanceData ) == 64, "GeometryInstanceData struc
struct AccelerationStructureData
{
vk::UniqueAccelerationStructureNV acclerationStructure;
void clear( vk::Device device )
{
device.destroyAccelerationStructureNV( accelerationStructure );
if ( scratchBufferData )
{
scratchBufferData->clear( device );
}
if ( resultBufferData )
{
resultBufferData->clear( device );
}
if ( instanceBufferData )
{
instanceBufferData->clear( device );
}
}
vk::AccelerationStructureNV accelerationStructure;
std::unique_ptr<vk::su::BufferData> scratchBufferData;
std::unique_ptr<vk::su::BufferData> resultBufferData;
std::unique_ptr<vk::su::BufferData> instanceBufferData;
};
AccelerationStructureData
createAccelerationStructureData( vk::PhysicalDevice const & physicalDevice,
vk::UniqueDevice const & device,
vk::UniqueCommandBuffer const & commandBuffer,
createAccelerationStructureData( vk::PhysicalDevice const & physicalDevice,
vk::Device const & device,
vk::CommandBuffer const & commandBuffer,
std::vector<std::pair<vk::AccelerationStructureNV, glm::mat4x4>> const & instances,
std::vector<vk::GeometryNV> const & geometries )
{
@@ -102,13 +119,13 @@ AccelerationStructureData
instances.empty() ? vk::AccelerationStructureTypeNV::eBottomLevel : vk::AccelerationStructureTypeNV::eTopLevel;
vk::AccelerationStructureInfoNV accelerationStructureInfo(
accelerationStructureType, {}, vk::su::checked_cast<uint32_t>( instances.size() ), geometries );
accelerationStructureData.acclerationStructure = device->createAccelerationStructureNVUnique(
vk::AccelerationStructureCreateInfoNV( 0, accelerationStructureInfo ) );
accelerationStructureData.accelerationStructure =
device.createAccelerationStructureNV( vk::AccelerationStructureCreateInfoNV( 0, accelerationStructureInfo ) );
vk::AccelerationStructureMemoryRequirementsInfoNV objectRequirements(
vk::AccelerationStructureMemoryRequirementsTypeNV::eObject, *accelerationStructureData.acclerationStructure );
vk::AccelerationStructureMemoryRequirementsTypeNV::eObject, accelerationStructureData.accelerationStructure );
vk::DeviceSize resultSizeInBytes =
device->getAccelerationStructureMemoryRequirementsNV( objectRequirements ).memoryRequirements.size;
device.getAccelerationStructureMemoryRequirementsNV( objectRequirements ).memoryRequirements.size;
assert( 0 < resultSizeInBytes );
accelerationStructureData.resultBufferData =
std::unique_ptr<vk::su::BufferData>( new vk::su::BufferData( physicalDevice,
@@ -118,13 +135,13 @@ AccelerationStructureData
vk::MemoryPropertyFlagBits::eDeviceLocal ) );
vk::AccelerationStructureMemoryRequirementsInfoNV buildScratchRequirements(
vk::AccelerationStructureMemoryRequirementsTypeNV::eBuildScratch, *accelerationStructureData.acclerationStructure );
vk::AccelerationStructureMemoryRequirementsTypeNV::eBuildScratch, accelerationStructureData.accelerationStructure );
vk::AccelerationStructureMemoryRequirementsInfoNV updateScratchRequirements(
vk::AccelerationStructureMemoryRequirementsTypeNV::eUpdateScratch,
*accelerationStructureData.acclerationStructure );
accelerationStructureData.accelerationStructure );
vk::DeviceSize scratchSizeInBytes = std::max(
device->getAccelerationStructureMemoryRequirementsNV( buildScratchRequirements ).memoryRequirements.size,
device->getAccelerationStructureMemoryRequirementsNV( updateScratchRequirements ).memoryRequirements.size );
device.getAccelerationStructureMemoryRequirementsNV( buildScratchRequirements ).memoryRequirements.size,
device.getAccelerationStructureMemoryRequirementsNV( updateScratchRequirements ).memoryRequirements.size );
assert( 0 < scratchSizeInBytes );
accelerationStructureData.scratchBufferData =
@@ -145,14 +162,14 @@ AccelerationStructureData
std::vector<GeometryInstanceData> geometryInstanceData;
for ( size_t i = 0; i < instances.size(); i++ )
{
uint64_t accelerationStructureHandle = device->getAccelerationStructureHandleNV<uint64_t>( instances[i].first );
uint64_t accelerationStructureHandle = device.getAccelerationStructureHandleNV<uint64_t>( instances[i].first );
// For each instance we set its instance index to its index i in the instance vector, and set
// its hit group index to 2*i. The hit group index defines which entry of the shader binding
// table will contain the hit group to be executed when hitting this instance. We set this
// index to 2*i due to the use of 2 types of rays in the scene: the camera rays and the shadow
// rays. For each instance, the SBT will then have 2 hit groups
geometryInstanceData.push_back(
geometryInstanceData.emplace_back(
GeometryInstanceData( glm::transpose( instances[i].second ),
static_cast<uint32_t>( i ),
0xFF,
@@ -163,40 +180,49 @@ AccelerationStructureData
accelerationStructureData.instanceBufferData->upload( device, geometryInstanceData );
}
device->bindAccelerationStructureMemoryNV( vk::BindAccelerationStructureMemoryInfoNV(
*accelerationStructureData.acclerationStructure, *accelerationStructureData.resultBufferData->deviceMemory ) );
device.bindAccelerationStructureMemoryNV( vk::BindAccelerationStructureMemoryInfoNV(
accelerationStructureData.accelerationStructure, accelerationStructureData.resultBufferData->deviceMemory ) );
commandBuffer->buildAccelerationStructureNV(
commandBuffer.buildAccelerationStructureNV(
vk::AccelerationStructureInfoNV(
accelerationStructureType, {}, vk::su::checked_cast<uint32_t>( instances.size() ), geometries ),
accelerationStructureData.instanceBufferData ? *accelerationStructureData.instanceBufferData->buffer : nullptr,
accelerationStructureData.instanceBufferData ? accelerationStructureData.instanceBufferData->buffer : nullptr,
0,
false,
*accelerationStructureData.acclerationStructure,
accelerationStructureData.accelerationStructure,
nullptr,
*accelerationStructureData.scratchBufferData->buffer,
accelerationStructureData.scratchBufferData->buffer,
0 );
commandBuffer->pipelineBarrier( vk::PipelineStageFlagBits::eAccelerationStructureBuildNV,
vk::PipelineStageFlagBits::eAccelerationStructureBuildNV,
{},
vk::MemoryBarrier( vk::AccessFlagBits::eAccelerationStructureWriteNV |
vk::AccessFlagBits::eAccelerationStructureReadNV,
vk::AccessFlagBits::eAccelerationStructureWriteNV |
vk::AccessFlagBits::eAccelerationStructureReadNV ),
{},
{} );
commandBuffer.pipelineBarrier( vk::PipelineStageFlagBits::eAccelerationStructureBuildNV,
vk::PipelineStageFlagBits::eAccelerationStructureBuildNV,
{},
vk::MemoryBarrier( vk::AccessFlagBits::eAccelerationStructureWriteNV |
vk::AccessFlagBits::eAccelerationStructureReadNV,
vk::AccessFlagBits::eAccelerationStructureWriteNV |
vk::AccessFlagBits::eAccelerationStructureReadNV ),
{},
{} );
return accelerationStructureData;
}
struct PerFrameData
{
vk::UniqueCommandPool commandPool;
vk::UniqueCommandBuffer commandBuffer;
vk::UniqueFence fence;
vk::UniqueSemaphore presentCompleteSemaphore;
vk::UniqueSemaphore renderCompleteSemaphore;
void clear( vk::Device device )
{
device.freeCommandBuffers( commandPool, commandBuffer );
device.destroyCommandPool( commandPool );
device.destroyFence( fence );
device.destroySemaphore( presentCompleteSemaphore );
device.destroySemaphore( renderCompleteSemaphore );
}
vk::CommandPool commandPool;
vk::CommandBuffer commandBuffer;
vk::Fence fence;
vk::Semaphore presentCompleteSemaphore;
vk::Semaphore renderCompleteSemaphore;
};
struct UniformBufferObject
@@ -709,17 +735,18 @@ int main( int /*argc*/, char ** /*argv*/ )
}
instanceExtensions.push_back( VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME );
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName, {}, instanceExtensions );
vk::Instance instance = vk::su::createInstance( AppName, EngineName, {}, instanceExtensions );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
vk::PhysicalDevice physicalDevice = instance->enumeratePhysicalDevices().front();
vk::PhysicalDevice physicalDevice = instance.enumeratePhysicalDevices().front();
// Create Window Surface (using glfw)
vk::SurfaceKHR surface;
VkResult err =
glfwCreateWindowSurface( VkInstance( *instance ), window, nullptr, reinterpret_cast<VkSurfaceKHR *>( &surface ) );
VkResult err = glfwCreateWindowSurface(
static_cast<VkInstance>( instance ), window, nullptr, reinterpret_cast<VkSurfaceKHR *>( &surface ) );
check_vk_result( err );
std::pair<uint32_t, uint32_t> graphicsAndPresentQueueFamilyIndex =
@@ -728,7 +755,7 @@ int main( int /*argc*/, char ** /*argv*/ )
// Create a Device with ray tracing support (besides some other extensions needed) and needed features
auto supportedFeatures =
physicalDevice.getFeatures2<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceDescriptorIndexingFeaturesEXT>();
vk::UniqueDevice device =
vk::Device device =
vk::su::createDevice( physicalDevice,
graphicsAndPresentQueueFamilyIndex.first,
{ VK_KHR_SWAPCHAIN_EXTENSION_NAME,
@@ -741,20 +768,19 @@ int main( int /*argc*/, char ** /*argv*/ )
std::array<PerFrameData, IMGUI_VK_QUEUED_FRAMES> perFrameData;
for ( int i = 0; i < IMGUI_VK_QUEUED_FRAMES; i++ )
{
perFrameData[i].commandPool = device->createCommandPoolUnique( vk::CommandPoolCreateInfo(
perFrameData[i].commandPool = device.createCommandPool( vk::CommandPoolCreateInfo(
vk::CommandPoolCreateFlagBits::eResetCommandBuffer, graphicsAndPresentQueueFamilyIndex.first ) );
perFrameData[i].commandBuffer =
std::move( device
->allocateCommandBuffersUnique( vk::CommandBufferAllocateInfo(
*perFrameData[i].commandPool, vk::CommandBufferLevel::ePrimary, 1 ) )
.front() );
perFrameData[i].fence = device->createFenceUnique( vk::FenceCreateInfo( vk::FenceCreateFlagBits::eSignaled ) );
perFrameData[i].presentCompleteSemaphore = device->createSemaphoreUnique( vk::SemaphoreCreateInfo() );
perFrameData[i].renderCompleteSemaphore = device->createSemaphoreUnique( vk::SemaphoreCreateInfo() );
perFrameData[i].commandBuffer = device
.allocateCommandBuffers( vk::CommandBufferAllocateInfo(
perFrameData[i].commandPool, vk::CommandBufferLevel::ePrimary, 1 ) )
.front();
perFrameData[i].fence = device.createFence( vk::FenceCreateInfo( vk::FenceCreateFlagBits::eSignaled ) );
perFrameData[i].presentCompleteSemaphore = device.createSemaphore( vk::SemaphoreCreateInfo() );
perFrameData[i].renderCompleteSemaphore = device.createSemaphore( vk::SemaphoreCreateInfo() );
}
vk::Queue graphicsQueue = device->getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
vk::Queue presentQueue = device->getQueue( graphicsAndPresentQueueFamilyIndex.second, 0 );
vk::Queue graphicsQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
vk::Queue presentQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.second, 0 );
// create a descriptor pool with a number of available descriptors
std::vector<vk::DescriptorPoolSize> poolSizes = {
@@ -762,7 +788,7 @@ int main( int /*argc*/, char ** /*argv*/ )
{ vk::DescriptorType::eUniformBuffer, 1000 },
{ vk::DescriptorType::eStorageBuffer, 1000 },
};
vk::UniqueDescriptorPool descriptorPool = vk::su::createDescriptorPool( device, poolSizes );
vk::DescriptorPool descriptorPool = vk::su::createDescriptorPool( device, poolSizes );
// setup swap chain, render pass, depth buffer and the frame buffers
vk::su::SwapChainData swapChainData( physicalDevice,
@@ -770,17 +796,17 @@ int main( int /*argc*/, char ** /*argv*/ )
surface,
windowExtent,
vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eStorage,
vk::UniqueSwapchainKHR(),
nullptr,
graphicsAndPresentQueueFamilyIndex.first,
graphicsAndPresentQueueFamilyIndex.second );
vk::SurfaceFormatKHR surfaceFormat = vk::su::pickSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( surface ) );
vk::Format depthFormat = vk::su::pickDepthFormat( physicalDevice );
// setup a render pass
vk::UniqueRenderPass renderPass = vk::su::createRenderPass( device, surfaceFormat.format, depthFormat );
vk::RenderPass renderPass = vk::su::createRenderPass( device, surfaceFormat.format, depthFormat );
vk::su::DepthBufferData depthBufferData( physicalDevice, device, depthFormat, windowExtent );
std::vector<vk::UniqueFramebuffer> framebuffers = vk::su::createFramebuffers(
vk::su::DepthBufferData depthBufferData( physicalDevice, device, depthFormat, windowExtent );
std::vector<vk::Framebuffer> framebuffers = vk::su::createFramebuffers(
device, renderPass, swapChainData.imageViews, depthBufferData.imageView, windowExtent );
bool samplerAnisotropy = !!supportedFeatures.get<vk::PhysicalDeviceFeatures2>().features.samplerAnisotropy;
@@ -791,16 +817,16 @@ int main( int /*argc*/, char ** /*argv*/ )
textures.reserve( textureCount );
for ( size_t i = 0; i < textureCount; i++ )
{
textures.push_back( vk::su::TextureData( physicalDevice,
device,
{ random<uint32_t>( 2, 8 ) * 16, random<uint32_t>( 2, 8 ) * 16 },
vk::ImageUsageFlagBits::eTransferDst | vk::ImageUsageFlagBits::eSampled,
{},
samplerAnisotropy,
true ) );
textures.emplace_back( physicalDevice,
device,
vk::Extent2D( random<uint32_t>( 2, 8 ) * 16, random<uint32_t>( 2, 8 ) * 16 ),
vk::ImageUsageFlagBits::eTransferDst | vk::ImageUsageFlagBits::eSampled,
vk::FormatFeatureFlags(),
samplerAnisotropy,
true );
}
vk::su::oneTimeSubmit(
device, perFrameData[0].commandPool, graphicsQueue, [&]( vk::UniqueCommandBuffer const & commandBuffer ) {
device, perFrameData[0].commandPool, graphicsQueue, [&]( vk::CommandBuffer const & commandBuffer ) {
for ( auto & t : textures )
{
t.setImage(
@@ -873,7 +899,7 @@ int main( int /*argc*/, char ** /*argv*/ )
glm::mat4x4 transform(
glm::mat4x4( 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f ) );
vk::UniqueDescriptorSetLayout descriptorSetLayout =
vk::DescriptorSetLayout descriptorSetLayout =
vk::su::createDescriptorSetLayout( device,
{ { vk::DescriptorType::eUniformBuffer, 1, vk::ShaderStageFlagBits::eVertex },
{ vk::DescriptorType::eStorageBuffer,
@@ -882,21 +908,21 @@ int main( int /*argc*/, char ** /*argv*/ )
{ vk::DescriptorType::eCombinedImageSampler,
static_cast<uint32_t>( textures.size() ),
vk::ShaderStageFlagBits::eFragment } } );
vk::UniquePipelineLayout pipelineLayout =
device->createPipelineLayoutUnique( vk::PipelineLayoutCreateInfo( {}, *descriptorSetLayout ) );
vk::PipelineLayout pipelineLayout =
device.createPipelineLayout( vk::PipelineLayoutCreateInfo( {}, descriptorSetLayout ) );
glslang::InitializeProcess();
vk::UniqueShaderModule vertexShaderModule =
vk::ShaderModule vertexShaderModule =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eVertex, vertexShaderText );
vk::UniqueShaderModule fragmentShaderModule =
vk::ShaderModule fragmentShaderModule =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eFragment, fragmentShaderText );
glslang::FinalizeProcess();
vk::UniquePipeline graphicsPipeline = vk::su::createGraphicsPipeline(
vk::Pipeline graphicsPipeline = vk::su::createGraphicsPipeline(
device,
vk::UniquePipelineCache(),
std::make_pair( *vertexShaderModule, nullptr ),
std::make_pair( *fragmentShaderModule, nullptr ),
{},
std::make_pair( vertexShaderModule, nullptr ),
std::make_pair( fragmentShaderModule, nullptr ),
VertexStride,
{ { vk::Format::eR32G32B32Sfloat, vk::su::checked_cast<uint32_t>( offsetof( Vertex, pos ) ) },
{ vk::Format::eR32G32B32Sfloat, vk::su::checked_cast<uint32_t>( offsetof( Vertex, nrm ) ) },
@@ -910,9 +936,8 @@ int main( int /*argc*/, char ** /*argv*/ )
vk::su::BufferData uniformBufferData(
physicalDevice, device, sizeof( UniformBufferObject ), vk::BufferUsageFlagBits::eUniformBuffer );
vk::UniqueDescriptorSet descriptorSet = std::move(
device->allocateDescriptorSetsUnique( vk::DescriptorSetAllocateInfo( *descriptorPool, *descriptorSetLayout ) )
.front() );
vk::DescriptorSetAllocateInfo descriptorSetAllocateInfo( descriptorPool, descriptorSetLayout );
vk::DescriptorSet descriptorSet = device.allocateDescriptorSets( descriptorSetAllocateInfo ).front();
vk::su::updateDescriptorSets( device,
descriptorSet,
{ { vk::DescriptorType::eUniformBuffer, uniformBufferData.buffer, {} },
@@ -924,13 +949,13 @@ int main( int /*argc*/, char ** /*argv*/ )
// create acceleration structures: one top-level, and just one bottom-level
AccelerationStructureData topLevelAS, bottomLevelAS;
vk::su::oneTimeSubmit(
device, perFrameData[0].commandPool, graphicsQueue, [&]( vk::UniqueCommandBuffer const & commandBuffer ) {
vk::GeometryDataNV geometryDataNV( vk::GeometryTrianglesNV( *vertexBufferData.buffer,
device, perFrameData[0].commandPool, graphicsQueue, [&]( vk::CommandBuffer const & commandBuffer ) {
vk::GeometryDataNV geometryDataNV( vk::GeometryTrianglesNV( vertexBufferData.buffer,
0,
vk::su::checked_cast<uint32_t>( vertices.size() ),
VertexStride,
vk::Format::eR32G32B32Sfloat,
*indexBufferData.buffer,
indexBufferData.buffer,
0,
vk::su::checked_cast<uint32_t>( indices.size() ),
vk::IndexType::eUint32 ),
@@ -946,91 +971,89 @@ int main( int /*argc*/, char ** /*argv*/ )
createAccelerationStructureData( physicalDevice,
device,
commandBuffer,
{ std::make_pair( *bottomLevelAS.acclerationStructure, transform ) },
{ std::make_pair( bottomLevelAS.accelerationStructure, transform ) },
std::vector<vk::GeometryNV>() );
} );
// create raytracing descriptor set
vk::su::oneTimeSubmit(
device, perFrameData[0].commandPool, graphicsQueue, [&]( vk::UniqueCommandBuffer const & commandBuffer ) {
device, perFrameData[0].commandPool, graphicsQueue, [&]( vk::CommandBuffer const & commandBuffer ) {
vk::BufferMemoryBarrier bufferMemoryBarrier( {},
vk::AccessFlagBits::eShaderRead,
VK_QUEUE_FAMILY_IGNORED,
VK_QUEUE_FAMILY_IGNORED,
*vertexBufferData.buffer,
vertexBufferData.buffer,
0,
VK_WHOLE_SIZE );
commandBuffer->pipelineBarrier( vk::PipelineStageFlagBits::eAllCommands,
vk::PipelineStageFlagBits::eAllCommands,
{},
nullptr,
bufferMemoryBarrier,
nullptr );
commandBuffer.pipelineBarrier( vk::PipelineStageFlagBits::eAllCommands,
vk::PipelineStageFlagBits::eAllCommands,
{},
nullptr,
bufferMemoryBarrier,
nullptr );
bufferMemoryBarrier.buffer = *indexBufferData.buffer;
commandBuffer->pipelineBarrier( vk::PipelineStageFlagBits::eAllCommands,
vk::PipelineStageFlagBits::eAllCommands,
{},
nullptr,
bufferMemoryBarrier,
nullptr );
bufferMemoryBarrier.buffer = indexBufferData.buffer;
commandBuffer.pipelineBarrier( vk::PipelineStageFlagBits::eAllCommands,
vk::PipelineStageFlagBits::eAllCommands,
{},
nullptr,
bufferMemoryBarrier,
nullptr );
} );
std::vector<vk::DescriptorSetLayoutBinding> bindings;
bindings.push_back(
vk::DescriptorSetLayoutBinding( 0,
vk::DescriptorType::eAccelerationStructureNV,
1,
vk::ShaderStageFlagBits::eRaygenNV | vk::ShaderStageFlagBits::eClosestHitNV ) );
bindings.push_back( vk::DescriptorSetLayoutBinding(
1, vk::DescriptorType::eStorageImage, 1, vk::ShaderStageFlagBits::eRaygenNV ) ); // raytracing output
bindings.push_back( vk::DescriptorSetLayoutBinding(
2, vk::DescriptorType::eUniformBuffer, 1, vk::ShaderStageFlagBits::eRaygenNV ) ); // camera information
bindings.push_back( vk::DescriptorSetLayoutBinding(
3, vk::DescriptorType::eStorageBuffer, 1, vk::ShaderStageFlagBits::eClosestHitNV ) ); // vertex buffer
bindings.push_back( vk::DescriptorSetLayoutBinding(
4, vk::DescriptorType::eStorageBuffer, 1, vk::ShaderStageFlagBits::eClosestHitNV ) ); // index buffer
bindings.push_back( vk::DescriptorSetLayoutBinding(
5, vk::DescriptorType::eStorageBuffer, 1, vk::ShaderStageFlagBits::eClosestHitNV ) ); // material buffer
bindings.push_back( vk::DescriptorSetLayoutBinding( 6,
vk::DescriptorType::eCombinedImageSampler,
vk::su::checked_cast<uint32_t>( textures.size() ),
vk::ShaderStageFlagBits::eClosestHitNV ) ); // textures
bindings.emplace_back( 0,
vk::DescriptorType::eAccelerationStructureNV,
1,
vk::ShaderStageFlagBits::eRaygenNV | vk::ShaderStageFlagBits::eClosestHitNV );
bindings.emplace_back(
1, vk::DescriptorType::eStorageImage, 1, vk::ShaderStageFlagBits::eRaygenNV ); // raytracing output
bindings.emplace_back(
2, vk::DescriptorType::eUniformBuffer, 1, vk::ShaderStageFlagBits::eRaygenNV ); // camera information
bindings.emplace_back(
3, vk::DescriptorType::eStorageBuffer, 1, vk::ShaderStageFlagBits::eClosestHitNV ); // vertex buffer
bindings.emplace_back(
4, vk::DescriptorType::eStorageBuffer, 1, vk::ShaderStageFlagBits::eClosestHitNV ); // index buffer
bindings.emplace_back(
5, vk::DescriptorType::eStorageBuffer, 1, vk::ShaderStageFlagBits::eClosestHitNV ); // material buffer
bindings.emplace_back( 6,
vk::DescriptorType::eCombinedImageSampler,
vk::su::checked_cast<uint32_t>( textures.size() ),
vk::ShaderStageFlagBits::eClosestHitNV ); // textures
std::vector<vk::DescriptorPoolSize> descriptorPoolSizes;
descriptorPoolSizes.reserve( bindings.size() );
for ( const auto & b : bindings )
{
descriptorPoolSizes.push_back( vk::DescriptorPoolSize(
b.descriptorType, vk::su::checked_cast<uint32_t>( swapChainData.images.size() ) * b.descriptorCount ) );
descriptorPoolSizes.emplace_back(
b.descriptorType, vk::su::checked_cast<uint32_t>( swapChainData.images.size() ) * b.descriptorCount );
}
vk::DescriptorPoolCreateInfo descriptorPoolCreateInfo(
vk::DescriptorPoolCreateFlagBits::eFreeDescriptorSet,
vk::su::checked_cast<uint32_t>( swapChainData.images.size() ),
descriptorPoolSizes );
vk::UniqueDescriptorPool rayTracingDescriptorPool = device->createDescriptorPoolUnique( descriptorPoolCreateInfo );
vk::UniqueDescriptorSetLayout rayTracingDescriptorSetLayout =
device->createDescriptorSetLayoutUnique( vk::DescriptorSetLayoutCreateInfo( {}, bindings ) );
vk::DescriptorPool rayTracingDescriptorPool = device.createDescriptorPool( descriptorPoolCreateInfo );
vk::DescriptorSetLayout rayTracingDescriptorSetLayout =
device.createDescriptorSetLayout( vk::DescriptorSetLayoutCreateInfo( {}, bindings ) );
std::vector<vk::DescriptorSetLayout> layouts;
for ( size_t i = 0; i < swapChainData.images.size(); i++ )
{
layouts.push_back( *rayTracingDescriptorSetLayout );
layouts.push_back( rayTracingDescriptorSetLayout );
}
vk::DescriptorSetAllocateInfo descriptorSetAllocateInfo( *rayTracingDescriptorPool, layouts );
std::vector<vk::UniqueDescriptorSet> rayTracingDescriptorSets =
device->allocateDescriptorSetsUnique( descriptorSetAllocateInfo );
descriptorSetAllocateInfo = vk::DescriptorSetAllocateInfo( rayTracingDescriptorPool, layouts );
std::vector<vk::DescriptorSet> rayTracingDescriptorSets =
device.allocateDescriptorSets( descriptorSetAllocateInfo );
// Bind ray tracing specific descriptor sets into pNext of a vk::WriteDescriptorSet
vk::WriteDescriptorSetAccelerationStructureNV writeDescriptorSetAcceleration( 1,
&*topLevelAS.acclerationStructure );
&topLevelAS.accelerationStructure );
std::vector<vk::WriteDescriptorSet> accelerationDescriptionSets;
for ( size_t i = 0; i < rayTracingDescriptorSets.size(); i++ )
{
accelerationDescriptionSets.push_back(
vk::WriteDescriptorSet( *rayTracingDescriptorSets[i], 0, 0, 1, bindings[0].descriptorType ) );
accelerationDescriptionSets.emplace_back( rayTracingDescriptorSets[i], 0, 0, 1, bindings[0].descriptorType );
accelerationDescriptionSets.back().pNext = &writeDescriptorSetAcceleration;
}
device->updateDescriptorSets( accelerationDescriptionSets, {} );
device.updateDescriptorSets( accelerationDescriptionSets, nullptr );
// Bind all the other buffers and images, starting with dstBinding == 2 (dstBinding == 1 is used by the backBuffer
// view)
@@ -1048,13 +1071,13 @@ int main( int /*argc*/, char ** /*argv*/ )
// create the ray-tracing shader modules
glslang::InitializeProcess();
vk::UniqueShaderModule raygenShaderModule =
vk::ShaderModule raygenShaderModule =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eRaygenNV, raygenShaderText );
vk::UniqueShaderModule missShaderModule =
vk::ShaderModule missShaderModule =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eMissNV, missShaderText );
vk::UniqueShaderModule shadowMissShaderModule =
vk::ShaderModule shadowMissShaderModule =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eMissNV, shadowMissShaderText );
vk::UniqueShaderModule closestHitShaderModule =
vk::ShaderModule closestHitShaderModule =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eClosestHitNV, closestHitShaderText );
glslang::FinalizeProcess();
@@ -1063,46 +1086,46 @@ int main( int /*argc*/, char ** /*argv*/ )
std::vector<vk::RayTracingShaderGroupCreateInfoNV> shaderGroups;
// We use only one ray generation, that will implement the camera model
shaderStages.push_back(
vk::PipelineShaderStageCreateInfo( {}, vk::ShaderStageFlagBits::eRaygenNV, *raygenShaderModule, "main" ) );
shaderGroups.push_back( vk::RayTracingShaderGroupCreateInfoNV(
vk::RayTracingShaderGroupTypeNV::eGeneral, 0, VK_SHADER_UNUSED_NV, VK_SHADER_UNUSED_NV, VK_SHADER_UNUSED_NV ) );
shaderStages.emplace_back(
vk::PipelineShaderStageCreateFlags(), vk::ShaderStageFlagBits::eRaygenNV, raygenShaderModule, "main" );
shaderGroups.emplace_back(
vk::RayTracingShaderGroupTypeNV::eGeneral, 0, VK_SHADER_UNUSED_NV, VK_SHADER_UNUSED_NV, VK_SHADER_UNUSED_NV );
// The first miss shader is used to look-up the environment in case the rays from the camera miss the geometry
shaderStages.push_back(
vk::PipelineShaderStageCreateInfo( {}, vk::ShaderStageFlagBits::eMissNV, *missShaderModule, "main" ) );
shaderGroups.push_back( vk::RayTracingShaderGroupCreateInfoNV(
vk::RayTracingShaderGroupTypeNV::eGeneral, 1, VK_SHADER_UNUSED_NV, VK_SHADER_UNUSED_NV, VK_SHADER_UNUSED_NV ) );
shaderStages.emplace_back(
vk::PipelineShaderStageCreateFlags(), vk::ShaderStageFlagBits::eMissNV, missShaderModule, "main" );
shaderGroups.emplace_back(
vk::RayTracingShaderGroupTypeNV::eGeneral, 1, VK_SHADER_UNUSED_NV, VK_SHADER_UNUSED_NV, VK_SHADER_UNUSED_NV );
// The second miss shader is invoked when a shadow ray misses the geometry. It simply indicates that no occlusion
// has been found
shaderStages.push_back(
vk::PipelineShaderStageCreateInfo( {}, vk::ShaderStageFlagBits::eMissNV, *shadowMissShaderModule, "main" ) );
shaderGroups.push_back( vk::RayTracingShaderGroupCreateInfoNV(
vk::RayTracingShaderGroupTypeNV::eGeneral, 2, VK_SHADER_UNUSED_NV, VK_SHADER_UNUSED_NV, VK_SHADER_UNUSED_NV ) );
shaderStages.emplace_back(
vk::PipelineShaderStageCreateFlags(), vk::ShaderStageFlagBits::eMissNV, shadowMissShaderModule, "main" );
shaderGroups.emplace_back(
vk::RayTracingShaderGroupTypeNV::eGeneral, 2, VK_SHADER_UNUSED_NV, VK_SHADER_UNUSED_NV, VK_SHADER_UNUSED_NV );
// The first hit group defines the shaders invoked when a ray shot from the camera hit the geometry. In this case we
// only specify the closest hit shader, and rely on the build-in triangle intersection and pass-through any-hit
// shader. However, explicit intersection and any hit shaders could be added as well.
shaderStages.push_back( vk::PipelineShaderStageCreateInfo(
{}, vk::ShaderStageFlagBits::eClosestHitNV, *closestHitShaderModule, "main" ) );
shaderGroups.push_back( vk::RayTracingShaderGroupCreateInfoNV( vk::RayTracingShaderGroupTypeNV::eTrianglesHitGroup,
VK_SHADER_UNUSED_NV,
3,
VK_SHADER_UNUSED_NV,
VK_SHADER_UNUSED_NV ) );
shaderStages.emplace_back(
vk::PipelineShaderStageCreateFlags(), vk::ShaderStageFlagBits::eClosestHitNV, closestHitShaderModule, "main" );
shaderGroups.emplace_back( vk::RayTracingShaderGroupTypeNV::eTrianglesHitGroup,
VK_SHADER_UNUSED_NV,
3,
VK_SHADER_UNUSED_NV,
VK_SHADER_UNUSED_NV );
// The second hit group defines the shaders invoked when a shadow ray hits the geometry. For simple shadows we do
// not need any shader in that group: we will rely on initializing the payload and update it only in the miss shader
shaderGroups.push_back( vk::RayTracingShaderGroupCreateInfoNV( vk::RayTracingShaderGroupTypeNV::eTrianglesHitGroup,
VK_SHADER_UNUSED_NV,
VK_SHADER_UNUSED_NV,
VK_SHADER_UNUSED_NV,
VK_SHADER_UNUSED_NV ) );
shaderGroups.emplace_back( vk::RayTracingShaderGroupTypeNV::eTrianglesHitGroup,
VK_SHADER_UNUSED_NV,
VK_SHADER_UNUSED_NV,
VK_SHADER_UNUSED_NV,
VK_SHADER_UNUSED_NV );
// Create the layout of the pipeline following the provided descriptor set layout
vk::UniquePipelineLayout rayTracingPipelineLayout =
device->createPipelineLayoutUnique( vk::PipelineLayoutCreateInfo( {}, *rayTracingDescriptorSetLayout ) );
vk::PipelineLayout rayTracingPipelineLayout =
device.createPipelineLayout( vk::PipelineLayoutCreateInfo( {}, rayTracingDescriptorSetLayout ) );
// Assemble the shader stages and recursion depth info into the raytracing pipeline
// The ray tracing process can shoot rays from the camera, and a shadow ray can be shot from the
@@ -1111,13 +1134,13 @@ int main( int /*argc*/, char ** /*argv*/ )
// in the ray generation to avoid deep recursion.
uint32_t maxRecursionDepth = 2;
vk::RayTracingPipelineCreateInfoNV rayTracingPipelineCreateInfo(
{}, shaderStages, shaderGroups, maxRecursionDepth, *rayTracingPipelineLayout );
vk::UniquePipeline rayTracingPipeline;
vk::ResultValue<vk::UniquePipeline> rvPipeline =
device->createRayTracingPipelineNVUnique( nullptr, rayTracingPipelineCreateInfo );
{}, shaderStages, shaderGroups, maxRecursionDepth, rayTracingPipelineLayout );
vk::Pipeline rayTracingPipeline;
vk::ResultValue<vk::Pipeline> rvPipeline =
device.createRayTracingPipelineNV( nullptr, rayTracingPipelineCreateInfo );
switch ( rvPipeline.result )
{
case vk::Result::eSuccess: rayTracingPipeline = std::move( rvPipeline.value ); break;
case vk::Result::eSuccess: rayTracingPipeline = rvPipeline.value; break;
case vk::Result::ePipelineCompileRequiredEXT:
// something meaningfull here
break;
@@ -1144,12 +1167,12 @@ int main( int /*argc*/, char ** /*argv*/ )
uint32_t shaderBindingTableSize = hitShaderBindingOffset + hitShaderTableSize;
std::vector<uint8_t> shaderHandleStorage( shaderBindingTableSize );
(void)device->getRayTracingShaderGroupHandlesNV(
*rayTracingPipeline, 0, 1, raygenShaderTableSize, &shaderHandleStorage[raygenShaderBindingOffset] );
(void)device->getRayTracingShaderGroupHandlesNV(
*rayTracingPipeline, 1, 2, missShaderTableSize, &shaderHandleStorage[missShaderBindingOffset] );
(void)device->getRayTracingShaderGroupHandlesNV(
*rayTracingPipeline, 3, 2, hitShaderTableSize, &shaderHandleStorage[hitShaderBindingOffset] );
(void)device.getRayTracingShaderGroupHandlesNV(
rayTracingPipeline, 0, 1, raygenShaderTableSize, &shaderHandleStorage[raygenShaderBindingOffset] );
(void)device.getRayTracingShaderGroupHandlesNV(
rayTracingPipeline, 1, 2, missShaderTableSize, &shaderHandleStorage[missShaderBindingOffset] );
(void)device.getRayTracingShaderGroupHandlesNV(
rayTracingPipeline, 3, 2, hitShaderTableSize, &shaderHandleStorage[hitShaderBindingOffset] );
vk::su::BufferData shaderBindingTableBufferData( physicalDevice,
device,
@@ -1175,7 +1198,7 @@ int main( int /*argc*/, char ** /*argv*/ )
double startTime = glfwGetTime();
glfwPollEvents();
vk::UniqueCommandBuffer const & commandBuffer = perFrameData[frameIndex].commandBuffer;
vk::CommandBuffer const & commandBuffer = perFrameData[frameIndex].commandBuffer;
int w, h;
glfwGetWindowSize( window, &w, &h );
@@ -1183,7 +1206,7 @@ int main( int /*argc*/, char ** /*argv*/ )
{
windowExtent.width = w;
windowExtent.height = h;
device->waitIdle();
device.waitIdle();
swapChainData =
vk::su::SwapChainData( physicalDevice,
device,
@@ -1196,9 +1219,9 @@ int main( int /*argc*/, char ** /*argv*/ )
depthBufferData =
vk::su::DepthBufferData( physicalDevice, device, vk::su::pickDepthFormat( physicalDevice ), windowExtent );
vk::su::oneTimeSubmit( commandBuffer, graphicsQueue, [&]( vk::UniqueCommandBuffer const & commandBuffer ) {
vk::su::oneTimeSubmit( commandBuffer, graphicsQueue, [&]( vk::CommandBuffer const & commandBuffer ) {
vk::su::setImageLayout( commandBuffer,
*depthBufferData.image,
depthBufferData.image,
depthFormat,
vk::ImageLayout::eUndefined,
vk::ImageLayout::eDepthStencilAttachmentOptimal );
@@ -1219,53 +1242,50 @@ int main( int /*argc*/, char ** /*argv*/ )
uniformBufferData.upload( device, uniformBufferObject );
// frame begin
vk::ResultValue<uint32_t> rv = device->acquireNextImageKHR(
*swapChainData.swapChain, UINT64_MAX, *perFrameData[frameIndex].presentCompleteSemaphore, nullptr );
vk::ResultValue<uint32_t> rv = device.acquireNextImageKHR(
swapChainData.swapChain, UINT64_MAX, perFrameData[frameIndex].presentCompleteSemaphore, nullptr );
assert( rv.result == vk::Result::eSuccess );
uint32_t backBufferIndex = rv.value;
while ( vk::Result::eTimeout ==
device->waitForFences( *perFrameData[frameIndex].fence, VK_TRUE, vk::su::FenceTimeout ) )
device.waitForFences( perFrameData[frameIndex].fence, VK_TRUE, vk::su::FenceTimeout ) )
;
device->resetFences( *perFrameData[frameIndex].fence );
device.resetFences( perFrameData[frameIndex].fence );
commandBuffer->begin( vk::CommandBufferBeginInfo( vk::CommandBufferUsageFlagBits::eOneTimeSubmit ) );
commandBuffer.begin( vk::CommandBufferBeginInfo( vk::CommandBufferUsageFlagBits::eOneTimeSubmit ) );
if ( appInfo.useRasterRender )
{
commandBuffer->beginRenderPass( vk::RenderPassBeginInfo( *renderPass,
*framebuffers[backBufferIndex],
vk::Rect2D( vk::Offset2D( 0, 0 ), windowExtent ),
clearValues ),
vk::SubpassContents::eInline );
commandBuffer.beginRenderPass(
vk::RenderPassBeginInfo(
renderPass, framebuffers[backBufferIndex], vk::Rect2D( vk::Offset2D( 0, 0 ), windowExtent ), clearValues ),
vk::SubpassContents::eInline );
commandBuffer->bindPipeline( vk::PipelineBindPoint::eGraphics, *graphicsPipeline );
commandBuffer->bindDescriptorSets(
vk::PipelineBindPoint::eGraphics, *pipelineLayout, 0, *descriptorSet, nullptr );
commandBuffer.bindPipeline( vk::PipelineBindPoint::eGraphics, graphicsPipeline );
commandBuffer.bindDescriptorSets( vk::PipelineBindPoint::eGraphics, pipelineLayout, 0, descriptorSet, nullptr );
commandBuffer->setViewport( 0,
vk::Viewport( 0.0f,
0.0f,
static_cast<float>( windowExtent.width ),
static_cast<float>( windowExtent.height ),
0.0f,
1.0f ) );
commandBuffer->setScissor( 0, vk::Rect2D( vk::Offset2D( 0, 0 ), windowExtent ) );
commandBuffer.setViewport( 0,
vk::Viewport( 0.0f,
0.0f,
static_cast<float>( windowExtent.width ),
static_cast<float>( windowExtent.height ),
0.0f,
1.0f ) );
commandBuffer.setScissor( 0, vk::Rect2D( vk::Offset2D( 0, 0 ), windowExtent ) );
commandBuffer->bindVertexBuffers( 0, *vertexBufferData.buffer, { 0 } );
commandBuffer->bindIndexBuffer( *indexBufferData.buffer, 0, vk::IndexType::eUint32 );
commandBuffer->drawIndexed( vk::su::checked_cast<uint32_t>( indices.size() ), 1, 0, 0, 0 );
commandBuffer.bindVertexBuffers( 0, vertexBufferData.buffer, { 0 } );
commandBuffer.bindIndexBuffer( indexBufferData.buffer, 0, vk::IndexType::eUint32 );
commandBuffer.drawIndexed( vk::su::checked_cast<uint32_t>( indices.size() ), 1, 0, 0, 0 );
commandBuffer->endRenderPass();
commandBuffer.endRenderPass();
}
else
{
vk::DescriptorImageInfo imageInfo(
nullptr, *swapChainData.imageViews[backBufferIndex], vk::ImageLayout::eGeneral );
device->updateDescriptorSets(
vk::WriteDescriptorSet(
*rayTracingDescriptorSets[backBufferIndex], 1, 0, bindings[1].descriptorType, imageInfo ),
{} );
nullptr, swapChainData.imageViews[backBufferIndex], vk::ImageLayout::eGeneral );
vk::WriteDescriptorSet writeDescriptorSet(
rayTracingDescriptorSets[backBufferIndex], 1, 0, bindings[1].descriptorType, imageInfo );
device.updateDescriptorSets( writeDescriptorSet, nullptr );
vk::su::setImageLayout( commandBuffer,
swapChainData.images[backBufferIndex],
@@ -1273,28 +1293,28 @@ int main( int /*argc*/, char ** /*argv*/ )
vk::ImageLayout::eUndefined,
vk::ImageLayout::eGeneral );
commandBuffer->bindPipeline( vk::PipelineBindPoint::eRayTracingNV, *rayTracingPipeline );
commandBuffer.bindPipeline( vk::PipelineBindPoint::eRayTracingNV, rayTracingPipeline );
commandBuffer->bindDescriptorSets( vk::PipelineBindPoint::eRayTracingNV,
*rayTracingPipelineLayout,
0,
*rayTracingDescriptorSets[backBufferIndex],
nullptr );
commandBuffer.bindDescriptorSets( vk::PipelineBindPoint::eRayTracingNV,
rayTracingPipelineLayout,
0,
rayTracingDescriptorSets[backBufferIndex],
nullptr );
commandBuffer->traceRaysNV( *shaderBindingTableBufferData.buffer,
raygenShaderBindingOffset,
*shaderBindingTableBufferData.buffer,
missShaderBindingOffset,
missShaderBindingStride,
*shaderBindingTableBufferData.buffer,
hitShaderBindingOffset,
hitShaderBindingStride,
nullptr,
0,
0,
windowExtent.width,
windowExtent.height,
1 );
commandBuffer.traceRaysNV( shaderBindingTableBufferData.buffer,
raygenShaderBindingOffset,
shaderBindingTableBufferData.buffer,
missShaderBindingOffset,
missShaderBindingStride,
shaderBindingTableBufferData.buffer,
hitShaderBindingOffset,
hitShaderBindingStride,
nullptr,
0,
0,
windowExtent.width,
windowExtent.height,
1 );
vk::su::setImageLayout( commandBuffer,
swapChainData.images[backBufferIndex],
@@ -1304,18 +1324,18 @@ int main( int /*argc*/, char ** /*argv*/ )
}
// frame end
commandBuffer->end();
commandBuffer.end();
const vk::PipelineStageFlags waitDstStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput;
graphicsQueue.submit( vk::SubmitInfo( 1,
&( *perFrameData[frameIndex].presentCompleteSemaphore ),
&( perFrameData[frameIndex].presentCompleteSemaphore ),
&waitDstStageMask,
1,
&( *commandBuffer ),
&commandBuffer,
1,
&( *perFrameData[frameIndex].renderCompleteSemaphore ) ),
*perFrameData[frameIndex].fence );
&( perFrameData[frameIndex].renderCompleteSemaphore ) ),
perFrameData[frameIndex].fence );
vk::Result result = presentQueue.presentKHR( vk::PresentInfoKHR(
*perFrameData[frameIndex].renderCompleteSemaphore, *swapChainData.swapChain, backBufferIndex ) );
perFrameData[frameIndex].renderCompleteSemaphore, swapChainData.swapChain, backBufferIndex ) );
switch ( result )
{
case vk::Result::eSuccess: break;
@@ -1345,9 +1365,51 @@ int main( int /*argc*/, char ** /*argv*/ )
}
// Cleanup
device->waitIdle();
swapChainData.swapChain.reset(); // need to reset swapChain before destroying the surface !
VULKAN_HPP_DEFAULT_DISPATCHER.vkDestroySurfaceKHR( VkInstance( *instance ), VkSurfaceKHR( surface ), nullptr );
device.waitIdle();
shaderBindingTableBufferData.clear( device );
device.destroyPipeline( rayTracingPipeline );
device.destroyPipelineLayout( rayTracingPipelineLayout );
device.destroyShaderModule( closestHitShaderModule );
device.destroyShaderModule( shadowMissShaderModule );
device.destroyShaderModule( missShaderModule );
device.destroyShaderModule( raygenShaderModule );
device.freeDescriptorSets( rayTracingDescriptorPool, rayTracingDescriptorSets );
device.destroyDescriptorSetLayout( rayTracingDescriptorSetLayout );
device.destroyDescriptorPool( rayTracingDescriptorPool );
topLevelAS.clear( device );
bottomLevelAS.clear( device );
device.freeDescriptorSets( descriptorPool, descriptorSet );
uniformBufferData.clear( device );
device.destroyPipeline( graphicsPipeline );
device.destroyShaderModule( fragmentShaderModule );
device.destroyShaderModule( vertexShaderModule );
device.destroyPipelineLayout( pipelineLayout );
device.destroyDescriptorSetLayout( descriptorSetLayout );
indexBufferData.clear( device );
vertexBufferData.clear( device );
materialBufferData.clear( device );
for ( auto & texture : textures )
{
texture.clear( device );
}
for ( auto framebuffer : framebuffers )
{
device.destroyFramebuffer( framebuffer );
}
depthBufferData.clear( device );
device.destroyRenderPass( renderPass );
swapChainData.clear( device );
device.destroyDescriptorPool( descriptorPool );
for ( int i = 0; i < IMGUI_VK_QUEUED_FRAMES; i++ )
{
perFrameData[i].clear( device );
}
device.destroy();
instance.destroySurfaceKHR( surface );
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
glfwDestroyWindow( window );
glfwTerminate();
}

View File

@@ -42,36 +42,36 @@ int main( int /*argc*/, char ** /*argv*/ )
{
try
{
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
vk::Instance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
vk::PhysicalDevice physicalDevice = instance->enumeratePhysicalDevices().front();
vk::PhysicalDevice physicalDevice = instance.enumeratePhysicalDevices().front();
vk::su::SurfaceData surfaceData( instance, AppName, vk::Extent2D( 500, 500 ) );
std::pair<uint32_t, uint32_t> graphicsAndPresentQueueFamilyIndex =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, *surfaceData.surface );
vk::UniqueDevice device =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, surfaceData.surface );
vk::Device device =
vk::su::createDevice( physicalDevice, graphicsAndPresentQueueFamilyIndex.first, vk::su::getDeviceExtensions() );
vk::UniqueCommandPool commandPool = vk::su::createCommandPool( device, graphicsAndPresentQueueFamilyIndex.first );
vk::UniqueCommandBuffer commandBuffer = std::move( device
->allocateCommandBuffersUnique( vk::CommandBufferAllocateInfo(
commandPool.get(), vk::CommandBufferLevel::ePrimary, 1 ) )
.front() );
vk::CommandPool commandPool = vk::su::createCommandPool( device, graphicsAndPresentQueueFamilyIndex.first );
vk::CommandBuffer commandBuffer =
device.allocateCommandBuffers( vk::CommandBufferAllocateInfo( commandPool, vk::CommandBufferLevel::ePrimary, 1 ) )
.front();
vk::Queue graphicsQueue = device->getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
vk::Queue presentQueue = device->getQueue( graphicsAndPresentQueueFamilyIndex.second, 0 );
vk::Queue graphicsQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
vk::Queue presentQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.second, 0 );
vk::su::SwapChainData swapChainData( physicalDevice,
device,
*surfaceData.surface,
surfaceData.surface,
surfaceData.extent,
vk::ImageUsageFlagBits::eColorAttachment |
vk::ImageUsageFlagBits::eTransferSrc,
vk::UniqueSwapchainKHR(),
{},
graphicsAndPresentQueueFamilyIndex.first,
graphicsAndPresentQueueFamilyIndex.second );
@@ -79,31 +79,31 @@ int main( int /*argc*/, char ** /*argv*/ )
vk::su::BufferData uniformBufferData(
physicalDevice, device, sizeof( glm::mat4x4 ), vk::BufferUsageFlagBits::eUniformBuffer );
vk::su::copyToDevice(
device, uniformBufferData.deviceMemory, vk::su::createModelViewProjectionClipMatrix( surfaceData.extent ) );
glm::mat4x4 mvpcMatrix = vk::su::createModelViewProjectionClipMatrix( surfaceData.extent );
vk::su::copyToDevice( device, uniformBufferData.deviceMemory, mvpcMatrix );
vk::UniqueDescriptorSetLayout descriptorSetLayout = vk::su::createDescriptorSetLayout(
vk::DescriptorSetLayout descriptorSetLayout = vk::su::createDescriptorSetLayout(
device,
{ { vk::DescriptorType::eUniformBuffer, 1, vk::ShaderStageFlagBits::eVertex },
{ vk::DescriptorType::eCombinedImageSampler, 1, vk::ShaderStageFlagBits::eFragment } } );
vk::UniquePipelineLayout pipelineLayout = device->createPipelineLayoutUnique(
vk::PipelineLayoutCreateInfo( vk::PipelineLayoutCreateFlags(), *descriptorSetLayout ) );
vk::PipelineLayout pipelineLayout = device.createPipelineLayout(
vk::PipelineLayoutCreateInfo( vk::PipelineLayoutCreateFlags(), descriptorSetLayout ) );
vk::UniqueRenderPass renderPass = vk::su::createRenderPass(
vk::RenderPass renderPass = vk::su::createRenderPass(
device,
vk::su::pickSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( surfaceData.surface.get() ) ).format,
vk::su::pickSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( surfaceData.surface ) ).format,
depthBufferData.format,
vk::AttachmentLoadOp::eClear,
vk::ImageLayout::eColorAttachmentOptimal );
glslang::InitializeProcess();
vk::UniqueShaderModule vertexShaderModule =
vk::ShaderModule vertexShaderModule =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eVertex, vertexShaderText_PT_T );
vk::UniqueShaderModule fragmentShaderModule =
vk::ShaderModule fragmentShaderModule =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eFragment, fragmentShaderText_T_C );
glslang::FinalizeProcess();
std::vector<vk::UniqueFramebuffer> framebuffers = vk::su::createFramebuffers(
std::vector<vk::Framebuffer> framebuffers = vk::su::createFramebuffers(
device, renderPass, swapChainData.imageViews, depthBufferData.imageView, surfaceData.extent );
vk::su::BufferData vertexBufferData(
@@ -113,13 +113,13 @@ int main( int /*argc*/, char ** /*argv*/ )
texturedCubeData,
sizeof( texturedCubeData ) / sizeof( texturedCubeData[0] ) );
vk::UniquePipelineCache pipelineCache = device->createPipelineCacheUnique( vk::PipelineCacheCreateInfo() );
vk::PipelineCache pipelineCache = device.createPipelineCache( vk::PipelineCacheCreateInfo() );
vk::UniquePipeline graphicsPipeline =
vk::Pipeline graphicsPipeline =
vk::su::createGraphicsPipeline( device,
pipelineCache,
std::make_pair( *vertexShaderModule, nullptr ),
std::make_pair( *fragmentShaderModule, nullptr ),
std::make_pair( vertexShaderModule, nullptr ),
std::make_pair( fragmentShaderModule, nullptr ),
sizeof( texturedCubeData[0] ),
{ { vk::Format::eR32G32B32A32Sfloat, 0 }, { vk::Format::eR32G32Sfloat, 16 } },
vk::FrontFace::eClockwise,
@@ -127,7 +127,7 @@ int main( int /*argc*/, char ** /*argv*/ )
pipelineLayout,
renderPass );
commandBuffer->begin( vk::CommandBufferBeginInfo() );
commandBuffer.begin( vk::CommandBufferBeginInfo() );
vk::su::TextureData greenTextureData( physicalDevice, device );
greenTextureData.setImage( device, commandBuffer, vk::su::MonochromeImageGenerator( { 118, 185, 0 } ) );
@@ -136,12 +136,12 @@ int main( int /*argc*/, char ** /*argv*/ )
checkeredTextureData.setImage( device, commandBuffer, vk::su::CheckerboardImageGenerator() );
// create two identical descriptor sets, each with a different texture but identical UBOs
vk::UniqueDescriptorPool descriptorPool = vk::su::createDescriptorPool(
vk::DescriptorPool descriptorPool = vk::su::createDescriptorPool(
device, { { vk::DescriptorType::eUniformBuffer, 2 }, { vk::DescriptorType::eCombinedImageSampler, 2 } } );
std::array<vk::DescriptorSetLayout, 2> layouts = { descriptorSetLayout.get(), descriptorSetLayout.get() };
std::vector<vk::UniqueDescriptorSet> descriptorSets =
device->allocateDescriptorSetsUnique( vk::DescriptorSetAllocateInfo( descriptorPool.get(), layouts ) );
std::array<vk::DescriptorSetLayout, 2> layouts = { descriptorSetLayout, descriptorSetLayout };
vk::DescriptorSetAllocateInfo descriptorSetAllocateInfo( descriptorPool, layouts );
std::vector<vk::DescriptorSet> descriptorSets = device.allocateDescriptorSets( descriptorSetAllocateInfo );
assert( descriptorSets.size() == 2 );
vk::su::updateDescriptorSets( device,
@@ -156,13 +156,13 @@ int main( int /*argc*/, char ** /*argv*/ )
/* VULKAN_KEY_START */
// create four secondary command buffers, for each quadrant of the screen
std::vector<vk::UniqueCommandBuffer> secondaryCommandBuffers = device->allocateCommandBuffersUnique(
vk::CommandBufferAllocateInfo( commandPool.get(), vk::CommandBufferLevel::eSecondary, 4 ) );
std::vector<vk::CommandBuffer> secondaryCommandBuffers = device.allocateCommandBuffers(
vk::CommandBufferAllocateInfo( commandPool, vk::CommandBufferLevel::eSecondary, 4 ) );
// Get the index of the next available swapchain image:
vk::UniqueSemaphore imageAcquiredSemaphore = device->createSemaphoreUnique( vk::SemaphoreCreateInfo() );
vk::ResultValue<uint32_t> currentBuffer = device->acquireNextImageKHR(
swapChainData.swapChain.get(), vk::su::FenceTimeout, imageAcquiredSemaphore.get(), nullptr );
vk::Semaphore imageAcquiredSemaphore = device.createSemaphore( vk::SemaphoreCreateInfo() );
vk::ResultValue<uint32_t> currentBuffer =
device.acquireNextImageKHR( swapChainData.swapChain, vk::su::FenceTimeout, imageAcquiredSemaphore, nullptr );
assert( currentBuffer.result == vk::Result::eSuccess );
assert( currentBuffer.value < framebuffers.size() );
@@ -177,9 +177,8 @@ int main( int /*argc*/, char ** /*argv*/ )
vk::Rect2D scissor( vk::Offset2D( 0, 0 ), vk::Extent2D( surfaceData.extent ) );
// now we record four separate command buffers, one for each quadrant of the screen
vk::CommandBufferInheritanceInfo commandBufferInheritanceInfo(
renderPass.get(), 0, framebuffers[currentBuffer.value].get() );
vk::CommandBufferBeginInfo secondaryBeginInfo( vk::CommandBufferUsageFlagBits::eOneTimeSubmit |
vk::CommandBufferInheritanceInfo commandBufferInheritanceInfo( renderPass, 0, framebuffers[currentBuffer.value] );
vk::CommandBufferBeginInfo secondaryBeginInfo( vk::CommandBufferUsageFlagBits::eOneTimeSubmit |
vk::CommandBufferUsageFlagBits::eRenderPassContinue,
&commandBufferInheritanceInfo );
@@ -188,30 +187,30 @@ int main( int /*argc*/, char ** /*argv*/ )
viewport.x = 25.0f + 250.0f * ( i % 2 );
viewport.y = 25.0f + 250.0f * ( i / 2 );
secondaryCommandBuffers[i]->begin( secondaryBeginInfo );
secondaryCommandBuffers[i]->bindPipeline( vk::PipelineBindPoint::eGraphics, graphicsPipeline.get() );
secondaryCommandBuffers[i]->bindDescriptorSets(
vk::PipelineBindPoint::eGraphics, pipelineLayout.get(), 0, descriptorSets[i == 0 || i == 3].get(), nullptr );
secondaryCommandBuffers[i]->bindVertexBuffers( 0, vertexBufferData.buffer.get(), offset );
secondaryCommandBuffers[i]->setViewport( 0, viewport );
secondaryCommandBuffers[i]->setScissor( 0, scissor );
secondaryCommandBuffers[i]->draw( 12 * 3, 1, 0, 0 );
secondaryCommandBuffers[i]->end();
secondaryCommandBuffers[i].begin( secondaryBeginInfo );
secondaryCommandBuffers[i].bindPipeline( vk::PipelineBindPoint::eGraphics, graphicsPipeline );
secondaryCommandBuffers[i].bindDescriptorSets(
vk::PipelineBindPoint::eGraphics, pipelineLayout, 0, descriptorSets[i == 0 || i == 3], nullptr );
secondaryCommandBuffers[i].bindVertexBuffers( 0, vertexBufferData.buffer, offset );
secondaryCommandBuffers[i].setViewport( 0, viewport );
secondaryCommandBuffers[i].setScissor( 0, scissor );
secondaryCommandBuffers[i].draw( 12 * 3, 1, 0, 0 );
secondaryCommandBuffers[i].end();
}
std::array<vk::ClearValue, 2> clearValues;
clearValues[0].color = vk::ClearColorValue( std::array<float, 4>( { { 0.2f, 0.2f, 0.2f, 0.2f } } ) );
clearValues[1].depthStencil = vk::ClearDepthStencilValue( 1.0f, 0 );
vk::RenderPassBeginInfo renderPassBeginInfo( renderPass.get(),
framebuffers[currentBuffer.value].get(),
vk::RenderPassBeginInfo renderPassBeginInfo( renderPass,
framebuffers[currentBuffer.value],
vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ),
clearValues );
// specifying VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS means this render pass may ONLY call
// vkCmdExecuteCommands
commandBuffer->beginRenderPass( renderPassBeginInfo, vk::SubpassContents::eSecondaryCommandBuffers );
commandBuffer->executeCommands( vk::uniqueToRaw( secondaryCommandBuffers ) );
commandBuffer->endRenderPass();
commandBuffer.beginRenderPass( renderPassBeginInfo, vk::SubpassContents::eSecondaryCommandBuffers );
commandBuffer.executeCommands( secondaryCommandBuffers );
commandBuffer.endRenderPass();
vk::ImageMemoryBarrier prePresentBarrier(
vk::AccessFlagBits::eColorAttachmentWrite,
@@ -222,25 +221,25 @@ int main( int /*argc*/, char ** /*argv*/ )
VK_QUEUE_FAMILY_IGNORED,
swapChainData.images[currentBuffer.value],
vk::ImageSubresourceRange( vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 ) );
commandBuffer->pipelineBarrier( vk::PipelineStageFlagBits::eColorAttachmentOutput,
vk::PipelineStageFlagBits::eBottomOfPipe,
vk::DependencyFlags(),
nullptr,
nullptr,
prePresentBarrier );
commandBuffer->end();
commandBuffer.pipelineBarrier( vk::PipelineStageFlagBits::eColorAttachmentOutput,
vk::PipelineStageFlagBits::eBottomOfPipe,
vk::DependencyFlags(),
nullptr,
nullptr,
prePresentBarrier );
commandBuffer.end();
vk::UniqueFence drawFence = device->createFenceUnique( vk::FenceCreateInfo() );
vk::Fence drawFence = device.createFence( vk::FenceCreateInfo() );
vk::PipelineStageFlags waitDestinationStageMask( vk::PipelineStageFlagBits::eColorAttachmentOutput );
vk::SubmitInfo submitInfo( *imageAcquiredSemaphore, waitDestinationStageMask, *commandBuffer );
graphicsQueue.submit( submitInfo, drawFence.get() );
vk::SubmitInfo submitInfo( imageAcquiredSemaphore, waitDestinationStageMask, commandBuffer );
graphicsQueue.submit( submitInfo, drawFence );
while ( vk::Result::eTimeout == device->waitForFences( drawFence.get(), VK_TRUE, vk::su::FenceTimeout ) )
while ( vk::Result::eTimeout == device.waitForFences( drawFence, VK_TRUE, vk::su::FenceTimeout ) )
;
vk::Result result =
presentQueue.presentKHR( vk::PresentInfoKHR( {}, *swapChainData.swapChain, currentBuffer.value ) );
presentQueue.presentKHR( vk::PresentInfoKHR( {}, swapChainData.swapChain, currentBuffer.value ) );
switch ( result )
{
case vk::Result::eSuccess: break;
@@ -253,7 +252,35 @@ int main( int /*argc*/, char ** /*argv*/ )
/* VULKAN_KEY_END */
device->waitIdle();
device.waitIdle();
device.destroyFence( drawFence );
device.destroySemaphore( imageAcquiredSemaphore );
device.destroyPipeline( graphicsPipeline );
device.destroyPipelineCache( pipelineCache );
device.freeDescriptorSets( descriptorPool, descriptorSets );
device.destroyDescriptorPool( descriptorPool );
vertexBufferData.clear( device );
for ( auto framebuffer : framebuffers )
{
device.destroyFramebuffer( framebuffer );
}
device.destroyShaderModule( fragmentShaderModule );
device.destroyShaderModule( vertexShaderModule );
device.destroyRenderPass( renderPass );
device.destroyPipelineLayout( pipelineLayout );
device.destroyDescriptorSetLayout( descriptorSetLayout );
uniformBufferData.clear( device );
checkeredTextureData.clear( device );
greenTextureData.clear( device );
depthBufferData.clear( device );
swapChainData.clear( device );
device.freeCommandBuffers( commandPool, commandBuffer );
device.destroyCommandPool( commandPool );
device.destroy();
instance.destroySurfaceKHR( surfaceData.surface );
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -70,36 +70,36 @@ int main( int /*argc*/, char ** /*argv*/ )
{
try
{
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
vk::Instance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
vk::PhysicalDevice physicalDevice = instance->enumeratePhysicalDevices().front();
vk::PhysicalDevice physicalDevice = instance.enumeratePhysicalDevices().front();
vk::su::SurfaceData surfaceData( instance, AppName, vk::Extent2D( 500, 500 ) );
std::pair<uint32_t, uint32_t> graphicsAndPresentQueueFamilyIndex =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, *surfaceData.surface );
vk::UniqueDevice device =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, surfaceData.surface );
vk::Device device =
vk::su::createDevice( physicalDevice, graphicsAndPresentQueueFamilyIndex.first, vk::su::getDeviceExtensions() );
vk::UniqueCommandPool commandPool = vk::su::createCommandPool( device, graphicsAndPresentQueueFamilyIndex.first );
vk::UniqueCommandBuffer commandBuffer = std::move( device
->allocateCommandBuffersUnique( vk::CommandBufferAllocateInfo(
commandPool.get(), vk::CommandBufferLevel::ePrimary, 1 ) )
.front() );
vk::CommandPool commandPool = vk::su::createCommandPool( device, graphicsAndPresentQueueFamilyIndex.first );
vk::CommandBuffer commandBuffer =
device.allocateCommandBuffers( vk::CommandBufferAllocateInfo( commandPool, vk::CommandBufferLevel::ePrimary, 1 ) )
.front();
vk::Queue graphicsQueue = device->getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
vk::Queue presentQueue = device->getQueue( graphicsAndPresentQueueFamilyIndex.second, 0 );
vk::Queue graphicsQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
vk::Queue presentQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.second, 0 );
vk::su::SwapChainData swapChainData( physicalDevice,
device,
*surfaceData.surface,
surfaceData.surface,
surfaceData.extent,
vk::ImageUsageFlagBits::eColorAttachment |
vk::ImageUsageFlagBits::eTransferSrc,
vk::UniqueSwapchainKHR(),
{},
graphicsAndPresentQueueFamilyIndex.first,
graphicsAndPresentQueueFamilyIndex.second );
@@ -107,23 +107,23 @@ int main( int /*argc*/, char ** /*argv*/ )
vk::su::BufferData uniformBufferData(
physicalDevice, device, sizeof( glm::mat4x4 ), vk::BufferUsageFlagBits::eUniformBuffer );
vk::su::copyToDevice(
device, uniformBufferData.deviceMemory, vk::su::createModelViewProjectionClipMatrix( surfaceData.extent ) );
glm::mat4x4 mvpcMatrix = vk::su::createModelViewProjectionClipMatrix( surfaceData.extent );
vk::su::copyToDevice( device, uniformBufferData.deviceMemory, mvpcMatrix );
vk::UniqueRenderPass renderPass = vk::su::createRenderPass(
vk::RenderPass renderPass = vk::su::createRenderPass(
device,
vk::su::pickSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( surfaceData.surface.get() ) ).format,
vk::su::pickSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( surfaceData.surface ) ).format,
depthBufferData.format,
vk::AttachmentLoadOp::eClear );
glslang::InitializeProcess();
vk::UniqueShaderModule vertexShaderModule =
vk::ShaderModule vertexShaderModule =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eVertex, vertexShaderText_PT_T );
vk::UniqueShaderModule fragmentShaderModule =
vk::ShaderModule fragmentShaderModule =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eFragment, fragmentShaderTextTS_T_C );
glslang::FinalizeProcess();
std::vector<vk::UniqueFramebuffer> framebuffers = vk::su::createFramebuffers(
std::vector<vk::Framebuffer> framebuffers = vk::su::createFramebuffers(
device, renderPass, swapChainData.imageViews, depthBufferData.imageView, surfaceData.extent );
vk::su::BufferData vertexBufferData(
@@ -135,29 +135,28 @@ int main( int /*argc*/, char ** /*argv*/ )
/* VULKAN_KEY_START */
commandBuffer->begin( vk::CommandBufferBeginInfo() );
commandBuffer.begin( vk::CommandBufferBeginInfo() );
// Create the separate image
vk::su::TextureData textureData( physicalDevice, device );
textureData.setImage( device, commandBuffer, vk::su::MonochromeImageGenerator( { 118, 185, 0 } ) );
// Create the separate sampler
vk::UniqueSampler sampler =
device->createSamplerUnique( vk::SamplerCreateInfo( vk::SamplerCreateFlags(),
vk::Filter::eNearest,
vk::Filter::eNearest,
vk::SamplerMipmapMode::eNearest,
vk::SamplerAddressMode::eClampToEdge,
vk::SamplerAddressMode::eClampToEdge,
vk::SamplerAddressMode::eClampToEdge,
0.0f,
false,
1.0f,
false,
vk::CompareOp::eNever,
0.0f,
0.0f,
vk::BorderColor::eFloatOpaqueWhite ) );
vk::Sampler sampler = device.createSampler( vk::SamplerCreateInfo( vk::SamplerCreateFlags(),
vk::Filter::eNearest,
vk::Filter::eNearest,
vk::SamplerMipmapMode::eNearest,
vk::SamplerAddressMode::eClampToEdge,
vk::SamplerAddressMode::eClampToEdge,
vk::SamplerAddressMode::eClampToEdge,
0.0f,
false,
1.0f,
false,
vk::CompareOp::eNever,
0.0f,
0.0f,
vk::BorderColor::eFloatOpaqueWhite ) );
// Create binding and layout for the following, matching contents of shader
// binding 0 = uniform buffer (MVP)
@@ -168,12 +167,12 @@ int main( int /*argc*/, char ** /*argv*/ )
vk::DescriptorSetLayoutBinding( 1, vk::DescriptorType::eSampledImage, 1, vk::ShaderStageFlagBits::eFragment ),
vk::DescriptorSetLayoutBinding( 2, vk::DescriptorType::eSampler, 1, vk::ShaderStageFlagBits::eFragment ) }
};
vk::UniqueDescriptorSetLayout descriptorSetLayout = device->createDescriptorSetLayoutUnique(
vk::DescriptorSetLayout descriptorSetLayout = device.createDescriptorSetLayout(
vk::DescriptorSetLayoutCreateInfo( vk::DescriptorSetLayoutCreateFlags(), resourceBindings ) );
// Create pipeline layout
vk::UniquePipelineLayout pipelineLayout = device->createPipelineLayoutUnique(
vk::PipelineLayoutCreateInfo( vk::PipelineLayoutCreateFlags(), *descriptorSetLayout ) );
vk::PipelineLayout pipelineLayout = device.createPipelineLayout(
vk::PipelineLayoutCreateInfo( vk::PipelineLayoutCreateFlags(), descriptorSetLayout ) );
// Create a single pool to contain data for the descriptor set
std::array<vk::DescriptorPoolSize, 3> poolSizes = {
@@ -181,35 +180,33 @@ int main( int /*argc*/, char ** /*argv*/ )
vk::DescriptorPoolSize( vk::DescriptorType::eSampledImage, 1 ),
vk::DescriptorPoolSize( vk::DescriptorType::eSampler, 1 ) }
};
vk::UniqueDescriptorPool descriptorPool = device->createDescriptorPoolUnique(
vk::DescriptorPool descriptorPool = device.createDescriptorPool(
vk::DescriptorPoolCreateInfo( vk::DescriptorPoolCreateFlagBits::eFreeDescriptorSet, 1, poolSizes ) );
// Populate descriptor sets
vk::UniqueDescriptorSet descriptorSet = std::move(
device->allocateDescriptorSetsUnique( vk::DescriptorSetAllocateInfo( *descriptorPool, *descriptorSetLayout ) )
.front() );
vk::DescriptorSetAllocateInfo descriptorSetAllocateInfo( descriptorPool, descriptorSetLayout );
vk::DescriptorSet descriptorSet = device.allocateDescriptorSets( descriptorSetAllocateInfo ).front();
vk::DescriptorBufferInfo bufferInfo( uniformBufferData.buffer.get(), 0, sizeof( glm::mat4x4 ) );
vk::DescriptorImageInfo imageInfo( textureData.textureSampler.get(),
textureData.imageData->imageView.get(),
vk::ImageLayout::eShaderReadOnlyOptimal );
vk::DescriptorImageInfo samplerInfo( sampler.get(), {}, {} );
vk::DescriptorBufferInfo bufferInfo( uniformBufferData.buffer, 0, sizeof( glm::mat4x4 ) );
vk::DescriptorImageInfo imageInfo(
textureData.sampler, textureData.imageData->imageView, vk::ImageLayout::eShaderReadOnlyOptimal );
vk::DescriptorImageInfo samplerInfo( sampler, {}, {} );
std::array<vk::WriteDescriptorSet, 3> descriptorWrites = {
{ vk::WriteDescriptorSet( *descriptorSet, 0, 0, vk::DescriptorType::eUniformBuffer, {}, bufferInfo ),
vk::WriteDescriptorSet( *descriptorSet, 1, 0, vk::DescriptorType::eSampledImage, imageInfo ),
vk::WriteDescriptorSet( *descriptorSet, 2, 0, vk::DescriptorType::eSampler, samplerInfo ) }
{ vk::WriteDescriptorSet( descriptorSet, 0, 0, vk::DescriptorType::eUniformBuffer, {}, bufferInfo ),
vk::WriteDescriptorSet( descriptorSet, 1, 0, vk::DescriptorType::eSampledImage, imageInfo ),
vk::WriteDescriptorSet( descriptorSet, 2, 0, vk::DescriptorType::eSampler, samplerInfo ) }
};
device->updateDescriptorSets( descriptorWrites, nullptr );
device.updateDescriptorSets( descriptorWrites, nullptr );
/* VULKAN_KEY_END */
vk::UniquePipelineCache pipelineCache = device->createPipelineCacheUnique( vk::PipelineCacheCreateInfo() );
vk::PipelineCache pipelineCache = device.createPipelineCache( vk::PipelineCacheCreateInfo() );
vk::UniquePipeline graphicsPipeline =
vk::Pipeline graphicsPipeline =
vk::su::createGraphicsPipeline( device,
pipelineCache,
std::make_pair( *vertexShaderModule, nullptr ),
std::make_pair( *fragmentShaderModule, nullptr ),
std::make_pair( vertexShaderModule, nullptr ),
std::make_pair( fragmentShaderModule, nullptr ),
sizeof( texturedCubeData[0] ),
{ { vk::Format::eR32G32B32A32Sfloat, 0 }, { vk::Format::eR32G32Sfloat, 16 } },
vk::FrontFace::eClockwise,
@@ -218,9 +215,9 @@ int main( int /*argc*/, char ** /*argv*/ )
renderPass );
// Get the index of the next available swapchain image:
vk::UniqueSemaphore imageAcquiredSemaphore = device->createSemaphoreUnique( vk::SemaphoreCreateInfo() );
vk::ResultValue<uint32_t> currentBuffer = device->acquireNextImageKHR(
swapChainData.swapChain.get(), vk::su::FenceTimeout, imageAcquiredSemaphore.get(), nullptr );
vk::Semaphore imageAcquiredSemaphore = device.createSemaphore( vk::SemaphoreCreateInfo() );
vk::ResultValue<uint32_t> currentBuffer =
device.acquireNextImageKHR( swapChainData.swapChain, vk::su::FenceTimeout, imageAcquiredSemaphore, nullptr );
assert( currentBuffer.result == vk::Result::eSuccess );
assert( currentBuffer.value < framebuffers.size() );
@@ -228,41 +225,40 @@ int main( int /*argc*/, char ** /*argv*/ )
clearValues[0].color = vk::ClearColorValue( std::array<float, 4>( { { 0.2f, 0.2f, 0.2f, 0.2f } } ) );
clearValues[1].depthStencil = vk::ClearDepthStencilValue( 1.0f, 0 );
vk::RenderPassBeginInfo renderPassBeginInfo( renderPass.get(),
framebuffers[currentBuffer.value].get(),
vk::RenderPassBeginInfo renderPassBeginInfo( renderPass,
framebuffers[currentBuffer.value],
vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ),
clearValues );
commandBuffer->beginRenderPass( renderPassBeginInfo, vk::SubpassContents::eInline );
commandBuffer.beginRenderPass( renderPassBeginInfo, vk::SubpassContents::eInline );
commandBuffer->bindPipeline( vk::PipelineBindPoint::eGraphics, graphicsPipeline.get() );
commandBuffer->bindDescriptorSets(
vk::PipelineBindPoint::eGraphics, pipelineLayout.get(), 0, descriptorSet.get(), nullptr );
commandBuffer.bindPipeline( vk::PipelineBindPoint::eGraphics, graphicsPipeline );
commandBuffer.bindDescriptorSets( vk::PipelineBindPoint::eGraphics, pipelineLayout, 0, descriptorSet, nullptr );
commandBuffer->bindVertexBuffers( 0, *vertexBufferData.buffer, { 0 } );
commandBuffer->setViewport( 0,
vk::Viewport( 0.0f,
0.0f,
static_cast<float>( surfaceData.extent.width ),
static_cast<float>( surfaceData.extent.height ),
0.0f,
1.0f ) );
commandBuffer->setScissor( 0, vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ) );
commandBuffer.bindVertexBuffers( 0, vertexBufferData.buffer, { 0 } );
commandBuffer.setViewport( 0,
vk::Viewport( 0.0f,
0.0f,
static_cast<float>( surfaceData.extent.width ),
static_cast<float>( surfaceData.extent.height ),
0.0f,
1.0f ) );
commandBuffer.setScissor( 0, vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ) );
commandBuffer->draw( 12 * 3, 1, 0, 0 );
commandBuffer->endRenderPass();
commandBuffer->end();
commandBuffer.draw( 12 * 3, 1, 0, 0 );
commandBuffer.endRenderPass();
commandBuffer.end();
vk::UniqueFence drawFence = device->createFenceUnique( vk::FenceCreateInfo() );
vk::Fence drawFence = device.createFence( vk::FenceCreateInfo() );
vk::PipelineStageFlags waitDestinationStageMask( vk::PipelineStageFlagBits::eColorAttachmentOutput );
vk::SubmitInfo submitInfo( *imageAcquiredSemaphore, waitDestinationStageMask, *commandBuffer );
graphicsQueue.submit( submitInfo, drawFence.get() );
vk::SubmitInfo submitInfo( imageAcquiredSemaphore, waitDestinationStageMask, commandBuffer );
graphicsQueue.submit( submitInfo, drawFence );
while ( vk::Result::eTimeout == device->waitForFences( drawFence.get(), VK_TRUE, vk::su::FenceTimeout ) )
while ( vk::Result::eTimeout == device.waitForFences( drawFence, VK_TRUE, vk::su::FenceTimeout ) )
;
vk::Result result =
presentQueue.presentKHR( vk::PresentInfoKHR( {}, *swapChainData.swapChain, currentBuffer.value ) );
presentQueue.presentKHR( vk::PresentInfoKHR( {}, swapChainData.swapChain, currentBuffer.value ) );
switch ( result )
{
case vk::Result::eSuccess: break;
@@ -273,7 +269,35 @@ int main( int /*argc*/, char ** /*argv*/ )
}
std::this_thread::sleep_for( std::chrono::milliseconds( 1000 ) );
device->waitIdle();
device.waitIdle();
device.destroyFence( drawFence );
device.destroySemaphore( imageAcquiredSemaphore );
device.destroyPipeline( graphicsPipeline );
device.destroyPipelineCache( pipelineCache );
device.freeDescriptorSets( descriptorPool, descriptorSet );
device.destroyDescriptorPool( descriptorPool );
vertexBufferData.clear( device );
for ( auto framebuffer : framebuffers )
{
device.destroyFramebuffer( framebuffer );
}
device.destroyShaderModule( fragmentShaderModule );
device.destroyShaderModule( vertexShaderModule );
device.destroyRenderPass( renderPass );
device.destroyPipelineLayout( pipelineLayout );
device.destroyDescriptorSetLayout( descriptorSetLayout );
uniformBufferData.clear( device );
textureData.clear( device );
device.destroySampler( sampler );
depthBufferData.clear( device );
swapChainData.clear( device );
device.freeCommandBuffers( commandPool, commandBuffer );
device.destroyCommandPool( commandPool );
device.destroy();
instance.destroySurfaceKHR( surfaceData.surface );
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -67,12 +67,11 @@ int main( int /*argc*/, char ** /*argv*/ )
#endif
std::vector<vk::ExtensionProperties> instanceExtensionProperties = vk::enumerateInstanceExtensionProperties();
bool supportsGetSurfaceCapabilities2 =
( std::find_if( instanceExtensionProperties.begin(),
instanceExtensionProperties.end(),
[]( vk::ExtensionProperties const & ep ) {
return strcmp( ep.extensionName, VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME ) == 0;
} ) != instanceExtensionProperties.end() );
auto propertyIterator = std::find_if(
instanceExtensionProperties.begin(), instanceExtensionProperties.end(), []( vk::ExtensionProperties const & ep ) {
return strcmp( ep.extensionName, VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME ) == 0;
} );
bool supportsGetSurfaceCapabilities2 = ( propertyIterator != instanceExtensionProperties.end() );
std::vector<std::string> extensions = vk::su::getInstanceExtensions();
if ( supportsGetSurfaceCapabilities2 )
@@ -80,13 +79,14 @@ int main( int /*argc*/, char ** /*argv*/ )
extensions.push_back( VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME );
}
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName, {}, extensions );
vk::Instance instance = vk::su::createInstance( AppName, EngineName, {}, extensions );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
// enumerate the physicalDevices
std::vector<vk::PhysicalDevice> physicalDevices = instance->enumeratePhysicalDevices();
std::vector<vk::PhysicalDevice> physicalDevices = instance.enumeratePhysicalDevices();
vk::su::SurfaceData surfaceData( instance, AppName, vk::Extent2D( 500, 500 ) );
@@ -108,7 +108,7 @@ int main( int /*argc*/, char ** /*argv*/ )
vk::DisplayNativeHdrSurfaceCapabilitiesAMD,
vk::SharedPresentSurfaceCapabilitiesKHR,
vk::SurfaceCapabilitiesFullScreenExclusiveEXT,
vk::SurfaceProtectedCapabilitiesKHR>( *surfaceData.surface );
vk::SurfaceProtectedCapabilitiesKHR>( surfaceData.surface );
vk::SurfaceCapabilitiesKHR const & surfaceCapabilities =
surfaceCapabilities2.get<vk::SurfaceCapabilities2KHR>().surfaceCapabilities;
@@ -159,12 +159,16 @@ int main( int /*argc*/, char ** /*argv*/ )
else
{
vk::SurfaceCapabilitiesKHR surfaceCapabilities =
physicalDevices[i].getSurfaceCapabilitiesKHR( *surfaceData.surface );
physicalDevices[i].getSurfaceCapabilitiesKHR( surfaceData.surface );
cout( surfaceCapabilities );
}
}
/* VULKAN_KEY_END */
instance.destroySurfaceKHR( surfaceData.surface );
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -29,13 +29,14 @@ int main( int /*argc*/, char ** /*argv*/ )
{
try
{
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
vk::Instance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
// enumerate the physicalDevices
std::vector<vk::PhysicalDevice> physicalDevices = instance->enumeratePhysicalDevices();
std::vector<vk::PhysicalDevice> physicalDevices = instance.enumeratePhysicalDevices();
vk::su::SurfaceData surfaceData( instance, AppName, vk::Extent2D( 500, 500 ) );
@@ -46,7 +47,7 @@ int main( int /*argc*/, char ** /*argv*/ )
{
std::cout << "PhysicalDevice " << i << "\n";
std::vector<vk::SurfaceFormatKHR> surfaceFormats =
physicalDevices[i].getSurfaceFormatsKHR( *surfaceData.surface );
physicalDevices[i].getSurfaceFormatsKHR( surfaceData.surface );
for ( size_t j = 0; j < surfaceFormats.size(); j++ )
{
std::cout << "\tFormat " << j << "\n";
@@ -59,6 +60,10 @@ int main( int /*argc*/, char ** /*argv*/ )
}
/* VULKAN_KEY_END */
instance.destroySurfaceKHR( surfaceData.surface );
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
// VulkanHpp Samples : Template
// Template sample to start from. Draw textured cube with mostly helpers.
// VulkanHpp Samples : DrawTexturedCube
// Draw a textured cube
#include "../utils/geometries.hpp"
#include "../utils/math.hpp"
@@ -25,43 +25,43 @@
#include <iostream>
#include <thread>
static char const * AppName = "Template";
static char const * AppName = "DrawTexturedCube";
static char const * EngineName = "Vulkan.hpp";
int main( int /*argc*/, char ** /*argv*/ )
{
try
{
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
vk::Instance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
vk::PhysicalDevice physicalDevice = instance->enumeratePhysicalDevices().front();
vk::PhysicalDevice physicalDevice = instance.enumeratePhysicalDevices().front();
vk::su::SurfaceData surfaceData( instance, AppName, vk::Extent2D( 500, 500 ) );
std::pair<uint32_t, uint32_t> graphicsAndPresentQueueFamilyIndex =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, *surfaceData.surface );
vk::UniqueDevice device =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, surfaceData.surface );
vk::Device device =
vk::su::createDevice( physicalDevice, graphicsAndPresentQueueFamilyIndex.first, vk::su::getDeviceExtensions() );
vk::UniqueCommandPool commandPool = vk::su::createCommandPool( device, graphicsAndPresentQueueFamilyIndex.first );
vk::UniqueCommandBuffer commandBuffer = std::move( device
->allocateCommandBuffersUnique( vk::CommandBufferAllocateInfo(
commandPool.get(), vk::CommandBufferLevel::ePrimary, 1 ) )
.front() );
vk::CommandPool commandPool = vk::su::createCommandPool( device, graphicsAndPresentQueueFamilyIndex.first );
vk::CommandBuffer commandBuffer =
device.allocateCommandBuffers( vk::CommandBufferAllocateInfo( commandPool, vk::CommandBufferLevel::ePrimary, 1 ) )
.front();
vk::Queue graphicsQueue = device->getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
vk::Queue presentQueue = device->getQueue( graphicsAndPresentQueueFamilyIndex.second, 0 );
vk::Queue graphicsQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
vk::Queue presentQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.second, 0 );
vk::su::SwapChainData swapChainData( physicalDevice,
device,
*surfaceData.surface,
surfaceData.surface,
surfaceData.extent,
vk::ImageUsageFlagBits::eColorAttachment |
vk::ImageUsageFlagBits::eTransferSrc,
vk::UniqueSwapchainKHR(),
{},
graphicsAndPresentQueueFamilyIndex.first,
graphicsAndPresentQueueFamilyIndex.second );
@@ -69,34 +69,34 @@ int main( int /*argc*/, char ** /*argv*/ )
vk::su::TextureData textureData( physicalDevice, device );
commandBuffer->begin( vk::CommandBufferBeginInfo() );
commandBuffer.begin( vk::CommandBufferBeginInfo() );
textureData.setImage( device, commandBuffer, vk::su::CheckerboardImageGenerator() );
vk::su::BufferData uniformBufferData(
physicalDevice, device, sizeof( glm::mat4x4 ), vk::BufferUsageFlagBits::eUniformBuffer );
vk::su::copyToDevice(
device, uniformBufferData.deviceMemory, vk::su::createModelViewProjectionClipMatrix( surfaceData.extent ) );
glm::mat4x4 mvpcMatrix = vk::su::createModelViewProjectionClipMatrix( surfaceData.extent );
vk::su::copyToDevice( device, uniformBufferData.deviceMemory, mvpcMatrix );
vk::UniqueDescriptorSetLayout descriptorSetLayout = vk::su::createDescriptorSetLayout(
vk::DescriptorSetLayout descriptorSetLayout = vk::su::createDescriptorSetLayout(
device,
{ { vk::DescriptorType::eUniformBuffer, 1, vk::ShaderStageFlagBits::eVertex },
{ vk::DescriptorType::eCombinedImageSampler, 1, vk::ShaderStageFlagBits::eFragment } } );
vk::UniquePipelineLayout pipelineLayout = device->createPipelineLayoutUnique(
vk::PipelineLayoutCreateInfo( vk::PipelineLayoutCreateFlags(), *descriptorSetLayout ) );
vk::PipelineLayout pipelineLayout = device.createPipelineLayout(
vk::PipelineLayoutCreateInfo( vk::PipelineLayoutCreateFlags(), descriptorSetLayout ) );
vk::UniqueRenderPass renderPass = vk::su::createRenderPass(
vk::RenderPass renderPass = vk::su::createRenderPass(
device,
vk::su::pickSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( surfaceData.surface.get() ) ).format,
vk::su::pickSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( surfaceData.surface ) ).format,
depthBufferData.format );
glslang::InitializeProcess();
vk::UniqueShaderModule vertexShaderModule =
vk::ShaderModule vertexShaderModule =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eVertex, vertexShaderText_PT_T );
vk::UniqueShaderModule fragmentShaderModule =
vk::ShaderModule fragmentShaderModule =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eFragment, fragmentShaderText_T_C );
glslang::FinalizeProcess();
std::vector<vk::UniqueFramebuffer> framebuffers = vk::su::createFramebuffers(
std::vector<vk::Framebuffer> framebuffers = vk::su::createFramebuffers(
device, renderPass, swapChainData.imageViews, depthBufferData.imageView, surfaceData.extent );
vk::su::BufferData vertexBufferData(
@@ -106,20 +106,20 @@ int main( int /*argc*/, char ** /*argv*/ )
texturedCubeData,
sizeof( texturedCubeData ) / sizeof( texturedCubeData[0] ) );
vk::UniqueDescriptorPool descriptorPool = vk::su::createDescriptorPool(
vk::DescriptorPool descriptorPool = vk::su::createDescriptorPool(
device, { { vk::DescriptorType::eUniformBuffer, 1 }, { vk::DescriptorType::eCombinedImageSampler, 1 } } );
vk::UniqueDescriptorSet descriptorSet = std::move(
device->allocateDescriptorSetsUnique( vk::DescriptorSetAllocateInfo( *descriptorPool, *descriptorSetLayout ) )
.front() );
vk::DescriptorSetAllocateInfo descriptorSetAllocateInfo( descriptorPool, descriptorSetLayout );
vk::DescriptorSet descriptorSet = device.allocateDescriptorSets( descriptorSetAllocateInfo ).front();
vk::su::updateDescriptorSets(
device, descriptorSet, { { vk::DescriptorType::eUniformBuffer, uniformBufferData.buffer, {} } }, textureData );
vk::UniquePipelineCache pipelineCache = device->createPipelineCacheUnique( vk::PipelineCacheCreateInfo() );
vk::UniquePipeline graphicsPipeline =
vk::PipelineCache pipelineCache = device.createPipelineCache( vk::PipelineCacheCreateInfo() );
vk::Pipeline graphicsPipeline =
vk::su::createGraphicsPipeline( device,
pipelineCache,
std::make_pair( *vertexShaderModule, nullptr ),
std::make_pair( *fragmentShaderModule, nullptr ),
std::make_pair( vertexShaderModule, nullptr ),
std::make_pair( fragmentShaderModule, nullptr ),
sizeof( texturedCubeData[0] ),
{ { vk::Format::eR32G32B32A32Sfloat, 0 }, { vk::Format::eR32G32Sfloat, 16 } },
vk::FrontFace::eClockwise,
@@ -128,50 +128,48 @@ int main( int /*argc*/, char ** /*argv*/ )
renderPass );
// Get the index of the next available swapchain image:
vk::UniqueSemaphore imageAcquiredSemaphore = device->createSemaphoreUnique( vk::SemaphoreCreateInfo() );
vk::ResultValue<uint32_t> currentBuffer = device->acquireNextImageKHR(
swapChainData.swapChain.get(), vk::su::FenceTimeout, imageAcquiredSemaphore.get(), nullptr );
vk::Semaphore imageAcquiredSemaphore = device.createSemaphore( vk::SemaphoreCreateInfo() );
vk::ResultValue<uint32_t> currentBuffer =
device.acquireNextImageKHR( swapChainData.swapChain, vk::su::FenceTimeout, imageAcquiredSemaphore, nullptr );
assert( currentBuffer.result == vk::Result::eSuccess );
assert( currentBuffer.value < framebuffers.size() );
std::array<vk::ClearValue, 2> clearValues;
clearValues[0].color = vk::ClearColorValue( std::array<float, 4>( { { 0.2f, 0.2f, 0.2f, 0.2f } } ) );
clearValues[1].depthStencil = vk::ClearDepthStencilValue( 1.0f, 0 );
vk::RenderPassBeginInfo renderPassBeginInfo( renderPass.get(),
framebuffers[currentBuffer.value].get(),
vk::RenderPassBeginInfo renderPassBeginInfo( renderPass,
framebuffers[currentBuffer.value],
vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ),
clearValues );
commandBuffer.beginRenderPass( renderPassBeginInfo, vk::SubpassContents::eInline );
commandBuffer.bindPipeline( vk::PipelineBindPoint::eGraphics, graphicsPipeline );
commandBuffer.bindDescriptorSets( vk::PipelineBindPoint::eGraphics, pipelineLayout, 0, descriptorSet, nullptr );
commandBuffer->beginRenderPass( renderPassBeginInfo, vk::SubpassContents::eInline );
commandBuffer->bindPipeline( vk::PipelineBindPoint::eGraphics, graphicsPipeline.get() );
commandBuffer->bindDescriptorSets(
vk::PipelineBindPoint::eGraphics, pipelineLayout.get(), 0, descriptorSet.get(), nullptr );
commandBuffer.bindVertexBuffers( 0, vertexBufferData.buffer, { 0 } );
commandBuffer.setViewport( 0,
vk::Viewport( 0.0f,
0.0f,
static_cast<float>( surfaceData.extent.width ),
static_cast<float>( surfaceData.extent.height ),
0.0f,
1.0f ) );
commandBuffer.setScissor( 0, vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ) );
commandBuffer->bindVertexBuffers( 0, *vertexBufferData.buffer, { 0 } );
commandBuffer->setViewport( 0,
vk::Viewport( 0.0f,
0.0f,
static_cast<float>( surfaceData.extent.width ),
static_cast<float>( surfaceData.extent.height ),
0.0f,
1.0f ) );
commandBuffer->setScissor( 0, vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ) );
commandBuffer.draw( 12 * 3, 1, 0, 0 );
commandBuffer.endRenderPass();
commandBuffer.end();
commandBuffer->draw( 12 * 3, 1, 0, 0 );
commandBuffer->endRenderPass();
commandBuffer->end();
vk::UniqueFence drawFence = device->createFenceUnique( vk::FenceCreateInfo() );
vk::Fence drawFence = device.createFence( vk::FenceCreateInfo() );
vk::PipelineStageFlags waitDestinationStageMask( vk::PipelineStageFlagBits::eColorAttachmentOutput );
vk::SubmitInfo submitInfo( *imageAcquiredSemaphore, waitDestinationStageMask, *commandBuffer );
graphicsQueue.submit( submitInfo, drawFence.get() );
vk::SubmitInfo submitInfo( imageAcquiredSemaphore, waitDestinationStageMask, commandBuffer );
graphicsQueue.submit( submitInfo, drawFence );
while ( vk::Result::eTimeout == device->waitForFences( drawFence.get(), VK_TRUE, vk::su::FenceTimeout ) )
while ( vk::Result::eTimeout == device.waitForFences( drawFence, VK_TRUE, vk::su::FenceTimeout ) )
;
vk::Result result =
presentQueue.presentKHR( vk::PresentInfoKHR( {}, *swapChainData.swapChain, currentBuffer.value ) );
presentQueue.presentKHR( vk::PresentInfoKHR( {}, swapChainData.swapChain, currentBuffer.value ) );
switch ( result )
{
case vk::Result::eSuccess: break;
@@ -182,7 +180,36 @@ int main( int /*argc*/, char ** /*argv*/ )
}
std::this_thread::sleep_for( std::chrono::milliseconds( 1000 ) );
device->waitIdle();
/* VULKAN_KEY_END */
device.waitIdle();
device.destroyFence( drawFence );
device.destroySemaphore( imageAcquiredSemaphore );
device.destroyPipeline( graphicsPipeline );
device.destroyPipelineCache( pipelineCache );
device.freeDescriptorSets( descriptorPool, descriptorSet );
device.destroyDescriptorPool( descriptorPool );
vertexBufferData.clear( device );
for ( auto framebuffer : framebuffers )
{
device.destroyFramebuffer( framebuffer );
}
device.destroyShaderModule( fragmentShaderModule );
device.destroyShaderModule( vertexShaderModule );
device.destroyRenderPass( renderPass );
device.destroyPipelineLayout( pipelineLayout );
device.destroyDescriptorSetLayout( descriptorSetLayout );
uniformBufferData.clear( device );
textureData.clear( device );
depthBufferData.clear( device );
swapChainData.clear( device );
device.freeCommandBuffers( commandPool, commandBuffer );
device.destroyCommandPool( commandPool );
device.destroy();
instance.destroySurfaceKHR( surfaceData.surface );
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -59,12 +59,13 @@ int main( int /*argc*/, char ** /*argv*/ )
try
{
vk::UniqueInstance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
vk::Instance instance = vk::su::createInstance( AppName, EngineName, {}, vk::su::getInstanceExtensions() );
#if !defined( NDEBUG )
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger = vk::su::createDebugUtilsMessenger( instance );
vk::DebugUtilsMessengerEXT debugUtilsMessenger =
instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
#endif
vk::PhysicalDevice physicalDevice = instance->enumeratePhysicalDevices().front();
vk::PhysicalDevice physicalDevice = instance.enumeratePhysicalDevices().front();
vk::PhysicalDeviceProperties physicalDeviceProperties = physicalDevice.getProperties();
if ( physicalDeviceProperties.limits.maxTexelBufferElements < 4 )
@@ -84,26 +85,25 @@ int main( int /*argc*/, char ** /*argv*/ )
vk::su::SurfaceData surfaceData( instance, AppName, vk::Extent2D( 500, 500 ) );
std::pair<uint32_t, uint32_t> graphicsAndPresentQueueFamilyIndex =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, *surfaceData.surface );
vk::UniqueDevice device =
vk::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, surfaceData.surface );
vk::Device device =
vk::su::createDevice( physicalDevice, graphicsAndPresentQueueFamilyIndex.first, vk::su::getDeviceExtensions() );
vk::UniqueCommandPool commandPool = vk::su::createCommandPool( device, graphicsAndPresentQueueFamilyIndex.first );
vk::UniqueCommandBuffer commandBuffer = std::move( device
->allocateCommandBuffersUnique( vk::CommandBufferAllocateInfo(
commandPool.get(), vk::CommandBufferLevel::ePrimary, 1 ) )
.front() );
vk::CommandPool commandPool = vk::su::createCommandPool( device, graphicsAndPresentQueueFamilyIndex.first );
vk::CommandBuffer commandBuffer =
device.allocateCommandBuffers( vk::CommandBufferAllocateInfo( commandPool, vk::CommandBufferLevel::ePrimary, 1 ) )
.front();
vk::Queue graphicsQueue = device->getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
vk::Queue presentQueue = device->getQueue( graphicsAndPresentQueueFamilyIndex.second, 0 );
vk::Queue graphicsQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.first, 0 );
vk::Queue presentQueue = device.getQueue( graphicsAndPresentQueueFamilyIndex.second, 0 );
vk::su::SwapChainData swapChainData( physicalDevice,
device,
*surfaceData.surface,
surfaceData.surface,
surfaceData.extent,
vk::ImageUsageFlagBits::eColorAttachment |
vk::ImageUsageFlagBits::eTransferSrc,
vk::UniqueSwapchainKHR(),
{},
graphicsAndPresentQueueFamilyIndex.first,
graphicsAndPresentQueueFamilyIndex.second );
@@ -111,100 +111,97 @@ int main( int /*argc*/, char ** /*argv*/ )
physicalDevice, device, sizeof( texels ), vk::BufferUsageFlagBits::eUniformTexelBuffer );
texelBufferData.upload( device, texels );
vk::UniqueBufferView texelBufferView = device->createBufferViewUnique(
vk::BufferViewCreateInfo( {}, *texelBufferData.buffer, texelFormat, 0, sizeof( texels ) ) );
vk::BufferView texelBufferView = device.createBufferView(
vk::BufferViewCreateInfo( {}, texelBufferData.buffer, texelFormat, 0, sizeof( texels ) ) );
vk::UniqueDescriptorSetLayout descriptorSetLayout = vk::su::createDescriptorSetLayout(
vk::DescriptorSetLayout descriptorSetLayout = vk::su::createDescriptorSetLayout(
device, { { vk::DescriptorType::eUniformTexelBuffer, 1, vk::ShaderStageFlagBits::eVertex } } );
vk::UniquePipelineLayout pipelineLayout = device->createPipelineLayoutUnique(
vk::PipelineLayoutCreateInfo( vk::PipelineLayoutCreateFlags(), *descriptorSetLayout ) );
vk::PipelineLayout pipelineLayout = device.createPipelineLayout(
vk::PipelineLayoutCreateInfo( vk::PipelineLayoutCreateFlags(), descriptorSetLayout ) );
vk::UniqueRenderPass renderPass = vk::su::createRenderPass(
vk::RenderPass renderPass = vk::su::createRenderPass(
device,
vk::su::pickSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( surfaceData.surface.get() ) ).format,
vk::su::pickSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( surfaceData.surface ) ).format,
vk::Format::eUndefined );
glslang::InitializeProcess();
vk::UniqueShaderModule vertexShaderModule =
vk::ShaderModule vertexShaderModule =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eVertex, vertexShaderText );
vk::UniqueShaderModule fragmentShaderModule =
vk::ShaderModule fragmentShaderModule =
vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eFragment, fragmentShaderText_C_C );
glslang::FinalizeProcess();
std::vector<vk::UniqueFramebuffer> framebuffers = vk::su::createFramebuffers(
device, renderPass, swapChainData.imageViews, vk::UniqueImageView(), surfaceData.extent );
std::vector<vk::Framebuffer> framebuffers =
vk::su::createFramebuffers( device, renderPass, swapChainData.imageViews, vk::ImageView(), surfaceData.extent );
vk::UniqueDescriptorPool descriptorPool =
vk::DescriptorPool descriptorPool =
vk::su::createDescriptorPool( device, { { vk::DescriptorType::eUniformTexelBuffer, 1 } } );
vk::UniqueDescriptorSet descriptorSet = std::move(
device->allocateDescriptorSetsUnique( vk::DescriptorSetAllocateInfo( *descriptorPool, *descriptorSetLayout ) )
.front() );
vk::DescriptorSetAllocateInfo descriptorSetAllocateInfo( descriptorPool, descriptorSetLayout );
vk::DescriptorSet descriptorSet = device.allocateDescriptorSets( descriptorSetAllocateInfo ).front();
vk::su::updateDescriptorSets(
device,
descriptorSet,
{ { vk::DescriptorType::eUniformTexelBuffer, texelBufferData.buffer, texelBufferView } },
{} );
vk::UniquePipelineCache pipelineCache = device->createPipelineCacheUnique( vk::PipelineCacheCreateInfo() );
vk::UniquePipeline graphicsPipeline =
vk::su::createGraphicsPipeline( device,
pipelineCache,
std::make_pair( *vertexShaderModule, nullptr ),
std::make_pair( *fragmentShaderModule, nullptr ),
0,
{},
vk::FrontFace::eClockwise,
false,
pipelineLayout,
renderPass );
vk::PipelineCache pipelineCache = device.createPipelineCache( vk::PipelineCacheCreateInfo() );
vk::Pipeline graphicsPipeline = vk::su::createGraphicsPipeline( device,
pipelineCache,
std::make_pair( vertexShaderModule, nullptr ),
std::make_pair( fragmentShaderModule, nullptr ),
0,
{},
vk::FrontFace::eClockwise,
false,
pipelineLayout,
renderPass );
/* VULKAN_KEY_START */
// Get the index of the next available swapchain image:
vk::UniqueSemaphore imageAcquiredSemaphore = device->createSemaphoreUnique( vk::SemaphoreCreateInfo() );
vk::ResultValue<uint32_t> currentBuffer = device->acquireNextImageKHR(
swapChainData.swapChain.get(), vk::su::FenceTimeout, imageAcquiredSemaphore.get(), nullptr );
vk::Semaphore imageAcquiredSemaphore = device.createSemaphore( vk::SemaphoreCreateInfo() );
vk::ResultValue<uint32_t> currentBuffer =
device.acquireNextImageKHR( swapChainData.swapChain, vk::su::FenceTimeout, imageAcquiredSemaphore, nullptr );
assert( currentBuffer.result == vk::Result::eSuccess );
assert( currentBuffer.value < framebuffers.size() );
commandBuffer->begin( vk::CommandBufferBeginInfo() );
commandBuffer.begin( vk::CommandBufferBeginInfo() );
vk::ClearValue clearValue;
clearValue.color = vk::ClearColorValue( std::array<float, 4>( { { 0.2f, 0.2f, 0.2f, 0.2f } } ) );
vk::RenderPassBeginInfo renderPassBeginInfo( renderPass.get(),
framebuffers[currentBuffer.value].get(),
vk::RenderPassBeginInfo renderPassBeginInfo( renderPass,
framebuffers[currentBuffer.value],
vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ),
clearValue );
commandBuffer->beginRenderPass( renderPassBeginInfo, vk::SubpassContents::eInline );
commandBuffer->bindPipeline( vk::PipelineBindPoint::eGraphics, graphicsPipeline.get() );
commandBuffer->bindDescriptorSets(
vk::PipelineBindPoint::eGraphics, pipelineLayout.get(), 0, descriptorSet.get(), nullptr );
commandBuffer.beginRenderPass( renderPassBeginInfo, vk::SubpassContents::eInline );
commandBuffer.bindPipeline( vk::PipelineBindPoint::eGraphics, graphicsPipeline );
commandBuffer.bindDescriptorSets( vk::PipelineBindPoint::eGraphics, pipelineLayout, 0, descriptorSet, nullptr );
commandBuffer->setViewport( 0,
vk::Viewport( 0.0f,
0.0f,
static_cast<float>( surfaceData.extent.width ),
static_cast<float>( surfaceData.extent.height ),
0.0f,
1.0f ) );
commandBuffer->setScissor( 0, vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ) );
commandBuffer.setViewport( 0,
vk::Viewport( 0.0f,
0.0f,
static_cast<float>( surfaceData.extent.width ),
static_cast<float>( surfaceData.extent.height ),
0.0f,
1.0f ) );
commandBuffer.setScissor( 0, vk::Rect2D( vk::Offset2D( 0, 0 ), surfaceData.extent ) );
commandBuffer->draw( 3, 1, 0, 0 );
commandBuffer->endRenderPass();
commandBuffer->end();
commandBuffer.draw( 3, 1, 0, 0 );
commandBuffer.endRenderPass();
commandBuffer.end();
vk::UniqueFence drawFence = device->createFenceUnique( vk::FenceCreateInfo() );
vk::Fence drawFence = device.createFence( vk::FenceCreateInfo() );
vk::PipelineStageFlags waitDestinationStageMask( vk::PipelineStageFlagBits::eColorAttachmentOutput );
vk::SubmitInfo submitInfo( *imageAcquiredSemaphore, waitDestinationStageMask, *commandBuffer );
graphicsQueue.submit( submitInfo, drawFence.get() );
vk::SubmitInfo submitInfo( imageAcquiredSemaphore, waitDestinationStageMask, commandBuffer );
graphicsQueue.submit( submitInfo, drawFence );
while ( vk::Result::eTimeout == device->waitForFences( drawFence.get(), VK_TRUE, vk::su::FenceTimeout ) )
while ( vk::Result::eTimeout == device.waitForFences( drawFence, VK_TRUE, vk::su::FenceTimeout ) )
;
vk::Result result =
presentQueue.presentKHR( vk::PresentInfoKHR( {}, *swapChainData.swapChain, currentBuffer.value ) );
presentQueue.presentKHR( vk::PresentInfoKHR( {}, swapChainData.swapChain, currentBuffer.value ) );
switch ( result )
{
case vk::Result::eSuccess: break;
@@ -217,7 +214,32 @@ int main( int /*argc*/, char ** /*argv*/ )
/* VULKAN_KEY_END */
device->waitIdle();
device.waitIdle();
device.destroyFence( drawFence );
device.destroySemaphore( imageAcquiredSemaphore );
device.destroyPipeline( graphicsPipeline );
device.destroyPipelineCache( pipelineCache );
device.freeDescriptorSets( descriptorPool, descriptorSet );
device.destroyDescriptorPool( descriptorPool );
for ( auto framebuffer : framebuffers )
{
device.destroyFramebuffer( framebuffer );
}
device.destroyShaderModule( fragmentShaderModule );
device.destroyShaderModule( vertexShaderModule );
device.destroyRenderPass( renderPass );
device.destroyPipelineLayout( pipelineLayout );
device.destroyDescriptorSetLayout( descriptorSetLayout );
device.destroyBufferView( texelBufferView );
texelBufferData.clear( device );
swapChainData.clear( device );
device.freeCommandBuffers( commandPool, commandBuffer );
device.destroyCommandPool( commandPool );
device.destroy();
instance.destroySurfaceKHR( surfaceData.surface );
instance.destroyDebugUtilsMessengerEXT( debugUtilsMessenger );
instance.destroy();
}
catch ( vk::SystemError & err )
{

View File

@@ -40,22 +40,12 @@ namespace vk
glm::mat4x4 view =
glm::lookAt( glm::vec3( -5.0f, 3.0f, -10.0f ), glm::vec3( 0.0f, 0.0f, 0.0f ), glm::vec3( 0.0f, -1.0f, 0.0f ) );
glm::mat4x4 projection = glm::perspective( fov, 1.0f, 0.1f, 100.0f );
glm::mat4x4 clip = glm::mat4x4( 1.0f,
0.0f,
0.0f,
0.0f,
0.0f,
-1.0f,
0.0f,
0.0f,
0.0f,
0.0f,
0.5f,
0.0f,
0.0f,
0.0f,
0.5f,
1.0f ); // vulkan clip space has inverted y and half z !
// clang-format off
glm::mat4x4 clip = glm::mat4x4( 1.0f, 0.0f, 0.0f, 0.0f,
0.0f, -1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.5f, 0.0f,
0.0f, 0.0f, 0.5f, 1.0f ); // vulkan clip space has inverted y and half z !
// clang-format on
return clip * projection * view * model;
}
} // namespace su

View File

@@ -86,9 +86,9 @@ namespace vk
return true;
}
vk::UniqueShaderModule createShaderModule( vk::UniqueDevice & device,
vk::ShaderStageFlagBits shaderStage,
std::string const & shaderText )
vk::ShaderModule createShaderModule( vk::Device const & device,
vk::ShaderStageFlagBits shaderStage,
std::string const & shaderText )
{
std::vector<unsigned int> shaderSPV;
if ( !GLSLtoSPV( shaderStage, shaderText, shaderSPV ) )
@@ -96,7 +96,7 @@ namespace vk
throw std::runtime_error( "Could not convert glsl shader to spir-v -> terminating" );
}
return device->createShaderModuleUnique( vk::ShaderModuleCreateInfo( vk::ShaderModuleCreateFlags(), shaderSPV ) );
return device.createShaderModule( vk::ShaderModuleCreateInfo( vk::ShaderModuleCreateFlags(), shaderSPV ) );
}
} // namespace su
} // namespace vk

View File

@@ -22,9 +22,9 @@ namespace vk
{
namespace su
{
vk::UniqueShaderModule createShaderModule( vk::UniqueDevice & device,
vk::ShaderStageFlagBits shaderStage,
std::string const & shaderText );
vk::ShaderModule createShaderModule( vk::Device const & device,
vk::ShaderStageFlagBits shaderStage,
std::string const & shaderText );
bool GLSLtoSPV( const vk::ShaderStageFlagBits shaderType,
std::string const & glslShader,

View File

@@ -38,7 +38,7 @@ namespace vk
{
namespace su
{
vk::UniqueDeviceMemory allocateMemory( vk::UniqueDevice const & device,
vk::DeviceMemory allocateDeviceMemory( vk::Device const & device,
vk::PhysicalDeviceMemoryProperties const & memoryProperties,
vk::MemoryRequirements const & memoryRequirements,
vk::MemoryPropertyFlags memoryPropertyFlags )
@@ -46,38 +46,32 @@ namespace vk
uint32_t memoryTypeIndex =
findMemoryType( memoryProperties, memoryRequirements.memoryTypeBits, memoryPropertyFlags );
return device->allocateMemoryUnique( vk::MemoryAllocateInfo( memoryRequirements.size, memoryTypeIndex ) );
return device.allocateMemory( vk::MemoryAllocateInfo( memoryRequirements.size, memoryTypeIndex ) );
}
bool contains( std::vector<vk::ExtensionProperties> const & extensionProperties, std::string const & extensionName )
{
return std::find_if( extensionProperties.begin(),
extensionProperties.end(),
[&extensionName]( vk::ExtensionProperties const & ep ) {
return extensionName == ep.extensionName;
} ) != extensionProperties.end();
auto propertyIterator = std::find_if(
extensionProperties.begin(), extensionProperties.end(), [&extensionName]( vk::ExtensionProperties const & ep ) {
return extensionName == ep.extensionName;
} );
return ( propertyIterator != extensionProperties.end() );
}
vk::UniqueCommandPool createCommandPool( vk::UniqueDevice & device, uint32_t queueFamilyIndex )
vk::CommandPool createCommandPool( vk::Device const & device, uint32_t queueFamilyIndex )
{
vk::CommandPoolCreateInfo commandPoolCreateInfo( vk::CommandPoolCreateFlagBits::eResetCommandBuffer,
queueFamilyIndex );
return device->createCommandPoolUnique( commandPoolCreateInfo );
return device.createCommandPool( commandPoolCreateInfo );
}
vk::UniqueDebugUtilsMessengerEXT createDebugUtilsMessenger( vk::UniqueInstance & instance )
vk::DebugUtilsMessengerEXT createDebugUtilsMessengerEXT( vk::Instance const & instance )
{
vk::DebugUtilsMessageSeverityFlagsEXT severityFlags( vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning |
vk::DebugUtilsMessageSeverityFlagBitsEXT::eError );
vk::DebugUtilsMessageTypeFlagsEXT messageTypeFlags( vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral |
vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance |
vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation );
return instance->createDebugUtilsMessengerEXTUnique( vk::DebugUtilsMessengerCreateInfoEXT(
{}, severityFlags, messageTypeFlags, &vk::su::debugUtilsMessengerCallback ) );
return instance.createDebugUtilsMessengerEXT( vk::su::makeDebugUtilsMessengerCreateInfoEXT() );
}
vk::UniqueDescriptorPool createDescriptorPool( vk::UniqueDevice & device,
std::vector<vk::DescriptorPoolSize> const & poolSizes )
vk::DescriptorPool createDescriptorPool( vk::Device const & device,
std::vector<vk::DescriptorPoolSize> const & poolSizes )
{
assert( !poolSizes.empty() );
uint32_t maxSets =
@@ -88,11 +82,11 @@ namespace vk
vk::DescriptorPoolCreateInfo descriptorPoolCreateInfo(
vk::DescriptorPoolCreateFlagBits::eFreeDescriptorSet, maxSets, poolSizes );
return device->createDescriptorPoolUnique( descriptorPoolCreateInfo );
return device.createDescriptorPool( descriptorPoolCreateInfo );
}
vk::UniqueDescriptorSetLayout createDescriptorSetLayout(
vk::UniqueDevice const & device,
vk::DescriptorSetLayout createDescriptorSetLayout(
vk::Device const & device,
std::vector<std::tuple<vk::DescriptorType, uint32_t, vk::ShaderStageFlags>> const & bindingData,
vk::DescriptorSetLayoutCreateFlags flags )
{
@@ -104,14 +98,14 @@ namespace vk
std::get<1>( bindingData[i] ),
std::get<2>( bindingData[i] ) );
}
return device->createDescriptorSetLayoutUnique( vk::DescriptorSetLayoutCreateInfo( flags, bindings ) );
return device.createDescriptorSetLayout( vk::DescriptorSetLayoutCreateInfo( flags, bindings ) );
}
vk::UniqueDevice createDevice( vk::PhysicalDevice physicalDevice,
uint32_t queueFamilyIndex,
std::vector<std::string> const & extensions,
vk::PhysicalDeviceFeatures const * physicalDeviceFeatures,
void const * pNext )
vk::Device createDevice( vk::PhysicalDevice const & physicalDevice,
uint32_t queueFamilyIndex,
std::vector<std::string> const & extensions,
vk::PhysicalDeviceFeatures const * physicalDeviceFeatures,
void const * pNext )
{
std::vector<char const *> enabledExtensions;
enabledExtensions.reserve( extensions.size() );
@@ -120,54 +114,47 @@ namespace vk
enabledExtensions.push_back( ext.data() );
}
// create a UniqueDevice
float queuePriority = 0.0f;
vk::DeviceQueueCreateInfo deviceQueueCreateInfo(
vk::DeviceQueueCreateFlags(), queueFamilyIndex, 1, &queuePriority );
vk::DeviceCreateInfo deviceCreateInfo(
vk::DeviceCreateFlags(), deviceQueueCreateInfo, {}, enabledExtensions, physicalDeviceFeatures );
vk::DeviceQueueCreateInfo deviceQueueCreateInfo( {}, queueFamilyIndex, 1, &queuePriority );
vk::DeviceCreateInfo deviceCreateInfo( {}, deviceQueueCreateInfo, {}, enabledExtensions, physicalDeviceFeatures );
deviceCreateInfo.pNext = pNext;
return physicalDevice.createDeviceUnique( deviceCreateInfo );
return physicalDevice.createDevice( deviceCreateInfo );
}
std::vector<vk::UniqueFramebuffer> createFramebuffers( vk::UniqueDevice & device,
vk::UniqueRenderPass & renderPass,
std::vector<vk::UniqueImageView> const & imageViews,
vk::UniqueImageView const & depthImageView,
vk::Extent2D const & extent )
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 )
{
vk::ImageView attachments[2];
attachments[1] = depthImageView.get();
attachments[1] = depthImageView;
vk::FramebufferCreateInfo framebufferCreateInfo( vk::FramebufferCreateFlags(),
*renderPass,
depthImageView ? 2 : 1,
attachments,
extent.width,
extent.height,
1 );
std::vector<vk::UniqueFramebuffer> framebuffers;
vk::FramebufferCreateInfo framebufferCreateInfo(
vk::FramebufferCreateFlags(), renderPass, depthImageView ? 2 : 1, attachments, extent.width, extent.height, 1 );
std::vector<vk::Framebuffer> framebuffers;
framebuffers.reserve( imageViews.size() );
for ( auto const & view : imageViews )
{
attachments[0] = view.get();
framebuffers.push_back( device->createFramebufferUnique( framebufferCreateInfo ) );
attachments[0] = view;
framebuffers.push_back( device.createFramebuffer( framebufferCreateInfo ) );
}
return framebuffers;
}
vk::UniquePipeline
createGraphicsPipeline( vk::UniqueDevice const & device,
vk::UniquePipelineCache const & pipelineCache,
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::UniquePipelineLayout const & pipelineLayout,
vk::UniqueRenderPass const & renderPass )
vk::PipelineLayout const & pipelineLayout,
vk::RenderPass const & renderPass )
{
std::array<vk::PipelineShaderStageCreateInfo, 2> pipelineShaderStageCreateInfos = {
vk::PipelineShaderStageCreateInfo( vk::PipelineShaderStageCreateFlags(),
@@ -191,8 +178,8 @@ namespace vk
vertexInputAttributeDescriptions.reserve( vertexInputAttributeFormatOffset.size() );
for ( uint32_t i = 0; i < vertexInputAttributeFormatOffset.size(); i++ )
{
vertexInputAttributeDescriptions.push_back( vk::VertexInputAttributeDescription(
i, 0, vertexInputAttributeFormatOffset[i].first, vertexInputAttributeFormatOffset[i].second ) );
vertexInputAttributeDescriptions.emplace_back(
i, 0, vertexInputAttributeFormatOffset[i].first, vertexInputAttributeFormatOffset[i].second );
}
pipelineVertexInputStateCreateInfo.setVertexBindingDescriptions( vertexInputBindingDescription );
pipelineVertexInputStateCreateInfo.setVertexAttributeDescriptions( vertexInputAttributeDescriptions );
@@ -262,53 +249,21 @@ namespace vk
&pipelineDepthStencilStateCreateInfo,
&pipelineColorBlendStateCreateInfo,
&pipelineDynamicStateCreateInfo,
pipelineLayout.get(),
renderPass.get() );
pipelineLayout,
renderPass );
auto result = device->createGraphicsPipelineUnique( pipelineCache.get(), graphicsPipelineCreateInfo );
auto result = device.createGraphicsPipeline( pipelineCache, graphicsPipelineCreateInfo );
assert( result.result == vk::Result::eSuccess );
return std::move( result.value );
return result.value;
}
vk::UniqueInstance createInstance( std::string const & appName,
std::string const & engineName,
std::vector<std::string> const & layers,
std::vector<std::string> const & extensions,
uint32_t apiVersion )
std::vector<char const *> gatherExtensions( std::vector<std::string> const & extensions
#if !defined( NDEBUG )
,
std::vector<vk::ExtensionProperties> const & extensionProperties
#endif
)
{
#if ( VULKAN_HPP_DISPATCH_LOADER_DYNAMIC == 1 )
static vk::DynamicLoader dl;
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
dl.getProcAddress<PFN_vkGetInstanceProcAddr>( "vkGetInstanceProcAddr" );
VULKAN_HPP_DEFAULT_DISPATCHER.init( vkGetInstanceProcAddr );
#endif
#if !defined( NDEBUG )
std::vector<vk::LayerProperties> layerProperties = vk::enumerateInstanceLayerProperties();
std::vector<vk::ExtensionProperties> extensionProperties = vk::enumerateInstanceExtensionProperties();
#endif
std::vector<char const *> enabledLayers;
enabledLayers.reserve( layers.size() );
for ( auto const & layer : layers )
{
assert(
std::find_if( layerProperties.begin(), layerProperties.end(), [layer]( vk::LayerProperties const & lp ) {
return layer == lp.layerName;
} ) != layerProperties.end() );
enabledLayers.push_back( layer.data() );
}
#if !defined( NDEBUG )
// Enable standard validation layer to find as much errors as possible!
if ( std::find( layers.begin(), layers.end(), "VK_LAYER_KHRONOS_validation" ) == layers.end() &&
std::find_if( layerProperties.begin(), layerProperties.end(), []( vk::LayerProperties const & lp ) {
return ( strcmp( "VK_LAYER_KHRONOS_validation", lp.layerName ) == 0 );
} ) != layerProperties.end() )
{
enabledLayers.push_back( "VK_LAYER_KHRONOS_validation" );
}
#endif
std::vector<char const *> enabledExtensions;
enabledExtensions.reserve( extensions.size() );
for ( auto const & ext : extensions )
@@ -329,9 +284,57 @@ namespace vk
enabledExtensions.push_back( VK_EXT_DEBUG_UTILS_EXTENSION_NAME );
}
#endif
return enabledExtensions;
}
std::vector<char const *> gatherLayers( std::vector<std::string> const & layers
#if !defined( NDEBUG )
,
std::vector<vk::LayerProperties> const & layerProperties
#endif
)
{
std::vector<char const *> enabledLayers;
enabledLayers.reserve( layers.size() );
for ( auto const & layer : layers )
{
assert(
std::find_if( layerProperties.begin(), layerProperties.end(), [layer]( vk::LayerProperties const & lp ) {
return layer == lp.layerName;
} ) != layerProperties.end() );
enabledLayers.push_back( layer.data() );
}
#if !defined( NDEBUG )
// Enable standard validation layer to find as much errors as possible!
if ( std::find( layers.begin(), layers.end(), "VK_LAYER_KHRONOS_validation" ) == layers.end() &&
std::find_if( layerProperties.begin(), layerProperties.end(), []( vk::LayerProperties const & lp ) {
return ( strcmp( "VK_LAYER_KHRONOS_validation", lp.layerName ) == 0 );
} ) != layerProperties.end() )
{
enabledLayers.push_back( "VK_LAYER_KHRONOS_validation" );
}
#endif
return enabledLayers;
}
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 )
{
#if ( VULKAN_HPP_DISPATCH_LOADER_DYNAMIC == 1 )
static vk::DynamicLoader dl;
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
dl.getProcAddress<PFN_vkGetInstanceProcAddr>( "vkGetInstanceProcAddr" );
VULKAN_HPP_DEFAULT_DISPATCHER.init( vkGetInstanceProcAddr );
#endif
vk::ApplicationInfo applicationInfo( appName.c_str(), 1, engineName.c_str(), 1, apiVersion );
std::vector<char const *> enabledLayers = vk::su::gatherLayers( layers, vk::enumerateInstanceLayerProperties() );
std::vector<char const *> enabledExtensions =
vk::su::gatherExtensions( extensions, vk::enumerateInstanceExtensionProperties() );
// create a UniqueInstance
vk::ApplicationInfo applicationInfo( appName.c_str(), 1, engineName.c_str(), 1, apiVersion );
#if defined( NDEBUG )
// in non-debug mode just use the InstanceCreateInfo for instance creation
vk::StructureChain<vk::InstanceCreateInfo> instanceCreateInfo(
@@ -355,45 +358,47 @@ namespace vk
{ {}, severityFlags, messageTypeFlags, &vk::su::debugUtilsMessengerCallback } );
# endif
#endif
vk::UniqueInstance instance = vk::createInstanceUnique( instanceCreateInfo.get<vk::InstanceCreateInfo>() );
vk::Instance instance =
vk::createInstance( makeInstanceCreateInfoChain( applicationInfo, enabledLayers, enabledExtensions )
.get<vk::InstanceCreateInfo>() );
#if ( VULKAN_HPP_DISPATCH_LOADER_DYNAMIC == 1 )
// initialize function pointers for instance
VULKAN_HPP_DEFAULT_DISPATCHER.init( *instance );
VULKAN_HPP_DEFAULT_DISPATCHER.init( instance );
#endif
return instance;
}
vk::UniqueRenderPass createRenderPass( vk::UniqueDevice & device,
vk::Format colorFormat,
vk::Format depthFormat,
vk::AttachmentLoadOp loadOp,
vk::ImageLayout colorFinalLayout )
vk::RenderPass createRenderPass( vk::Device const & device,
vk::Format colorFormat,
vk::Format depthFormat,
vk::AttachmentLoadOp loadOp,
vk::ImageLayout colorFinalLayout )
{
std::vector<vk::AttachmentDescription> attachmentDescriptions;
assert( colorFormat != vk::Format::eUndefined );
attachmentDescriptions.push_back( vk::AttachmentDescription( vk::AttachmentDescriptionFlags(),
colorFormat,
vk::SampleCountFlagBits::e1,
loadOp,
vk::AttachmentStoreOp::eStore,
vk::AttachmentLoadOp::eDontCare,
vk::AttachmentStoreOp::eDontCare,
vk::ImageLayout::eUndefined,
colorFinalLayout ) );
attachmentDescriptions.emplace_back( vk::AttachmentDescriptionFlags(),
colorFormat,
vk::SampleCountFlagBits::e1,
loadOp,
vk::AttachmentStoreOp::eStore,
vk::AttachmentLoadOp::eDontCare,
vk::AttachmentStoreOp::eDontCare,
vk::ImageLayout::eUndefined,
colorFinalLayout );
if ( depthFormat != vk::Format::eUndefined )
{
attachmentDescriptions.push_back(
vk::AttachmentDescription( vk::AttachmentDescriptionFlags(),
depthFormat,
vk::SampleCountFlagBits::e1,
loadOp,
vk::AttachmentStoreOp::eDontCare,
vk::AttachmentLoadOp::eDontCare,
vk::AttachmentStoreOp::eDontCare,
vk::ImageLayout::eUndefined,
vk::ImageLayout::eDepthStencilAttachmentOptimal ) );
attachmentDescriptions.emplace_back( vk::AttachmentDescriptionFlags(),
depthFormat,
vk::SampleCountFlagBits::e1,
loadOp,
vk::AttachmentStoreOp::eDontCare,
vk::AttachmentLoadOp::eDontCare,
vk::AttachmentStoreOp::eDontCare,
vk::ImageLayout::eUndefined,
vk::ImageLayout::eDepthStencilAttachmentOptimal );
}
vk::AttachmentReference colorAttachment( 0, vk::ImageLayout::eColorAttachmentOptimal );
vk::AttachmentReference depthAttachment( 1, vk::ImageLayout::eDepthStencilAttachmentOptimal );
@@ -404,7 +409,7 @@ namespace vk
{},
( depthFormat != vk::Format::eUndefined ) ? &depthAttachment
: nullptr );
return device->createRenderPassUnique(
return device.createRenderPass(
vk::RenderPassCreateInfo( vk::RenderPassCreateFlags(), attachmentDescriptions, subpassDescription ) );
}
@@ -414,7 +419,7 @@ namespace vk
VkDebugUtilsMessengerCallbackDataEXT const * pCallbackData,
void * /*pUserData*/ )
{
#if !defined(NDEBUG)
#if !defined( NDEBUG )
if ( pCallbackData->messageIdNumber == 648835635 )
{
// UNASSIGNED-khronos-Validation-debug-build-warning-message
@@ -481,15 +486,12 @@ namespace vk
uint32_t findGraphicsQueueFamilyIndex( std::vector<vk::QueueFamilyProperties> const & queueFamilyProperties )
{
// get the first index into queueFamiliyProperties which supports graphics
size_t graphicsQueueFamilyIndex = std::distance(
queueFamilyProperties.begin(),
std::find_if(
queueFamilyProperties.begin(), queueFamilyProperties.end(), []( vk::QueueFamilyProperties const & qfp ) {
return qfp.queueFlags & vk::QueueFlagBits::eGraphics;
} ) );
assert( graphicsQueueFamilyIndex < queueFamilyProperties.size() );
return checked_cast<uint32_t>( graphicsQueueFamilyIndex );
std::vector<vk::QueueFamilyProperties>::const_iterator graphicsQueueFamilyProperty = std::find_if(
queueFamilyProperties.begin(), queueFamilyProperties.end(), []( vk::QueueFamilyProperties const & qfp ) {
return qfp.queueFlags & vk::QueueFlagBits::eGraphics;
} );
assert( graphicsQueueFamilyProperty != queueFamilyProperties.end() );
return static_cast<uint32_t>( std::distance( queueFamilyProperties.begin(), graphicsQueueFamilyProperty ) );
}
std::pair<uint32_t, uint32_t> findGraphicsAndPresentQueueFamilyIndex( vk::PhysicalDevice physicalDevice,
@@ -655,11 +657,11 @@ namespace vk
return pickedFormat;
}
void setImageLayout( vk::UniqueCommandBuffer const & commandBuffer,
vk::Image image,
vk::Format format,
vk::ImageLayout oldImageLayout,
vk::ImageLayout newImageLayout )
void setImageLayout( vk::CommandBuffer const & commandBuffer,
vk::Image image,
vk::Format format,
vk::ImageLayout oldImageLayout,
vk::ImageLayout newImageLayout )
{
vk::AccessFlags sourceAccessMask;
switch ( oldImageLayout )
@@ -741,24 +743,24 @@ namespace vk
VK_QUEUE_FAMILY_IGNORED,
image,
imageSubresourceRange );
return commandBuffer->pipelineBarrier( sourceStage, destinationStage, {}, nullptr, nullptr, imageMemoryBarrier );
return commandBuffer.pipelineBarrier( sourceStage, destinationStage, {}, nullptr, nullptr, imageMemoryBarrier );
}
void submitAndWait( vk::UniqueDevice & device, vk::Queue queue, vk::UniqueCommandBuffer & commandBuffer )
void submitAndWait( vk::Device const & device, vk::Queue const & queue, vk::CommandBuffer const & commandBuffer )
{
vk::UniqueFence fence = device->createFenceUnique( vk::FenceCreateInfo() );
queue.submit( vk::SubmitInfo( {}, {}, *commandBuffer ), fence.get() );
while ( vk::Result::eTimeout == device->waitForFences( fence.get(), VK_TRUE, vk::su::FenceTimeout ) )
vk::Fence fence = device.createFence( vk::FenceCreateInfo() );
queue.submit( vk::SubmitInfo( 0, nullptr, nullptr, 1, &commandBuffer ), fence );
while ( vk::Result::eTimeout == device.waitForFences( fence, VK_TRUE, vk::su::FenceTimeout ) )
;
device.destroyFence( fence );
}
void updateDescriptorSets(
vk::UniqueDevice const & device,
vk::UniqueDescriptorSet const & descriptorSet,
std::vector<std::tuple<vk::DescriptorType, vk::UniqueBuffer const &, vk::UniqueBufferView const &>> const &
bufferData,
vk::su::TextureData const & textureData,
uint32_t bindingOffset )
vk::Device const & device,
vk::DescriptorSet const & descriptorSet,
std::vector<std::tuple<vk::DescriptorType, vk::Buffer const &, vk::BufferView const &>> const & bufferData,
vk::su::TextureData const & textureData,
uint32_t bindingOffset )
{
std::vector<vk::DescriptorBufferInfo> bufferInfos;
bufferInfos.reserve( bufferData.size() );
@@ -768,32 +770,25 @@ namespace vk
uint32_t dstBinding = bindingOffset;
for ( auto const & bd : bufferData )
{
bufferInfos.push_back( vk::DescriptorBufferInfo( *std::get<1>( bd ), 0, VK_WHOLE_SIZE ) );
writeDescriptorSets.push_back( vk::WriteDescriptorSet( *descriptorSet,
dstBinding++,
0,
1,
std::get<0>( bd ),
nullptr,
&bufferInfos.back(),
std::get<2>( bd ) ? &*std::get<2>( bd ) : nullptr ) );
bufferInfos.emplace_back( std::get<1>( bd ), 0, VK_WHOLE_SIZE );
writeDescriptorSets.emplace_back(
descriptorSet, dstBinding++, 0, 1, std::get<0>( bd ), nullptr, &bufferInfos.back(), &std::get<2>( bd ) );
}
vk::DescriptorImageInfo imageInfo(
*textureData.textureSampler, *textureData.imageData->imageView, vk::ImageLayout::eShaderReadOnlyOptimal );
writeDescriptorSets.push_back( vk::WriteDescriptorSet(
*descriptorSet, dstBinding, 0, vk::DescriptorType::eCombinedImageSampler, imageInfo, {}, nullptr ) );
textureData.sampler, textureData.imageData->imageView, vk::ImageLayout::eShaderReadOnlyOptimal );
writeDescriptorSets.emplace_back(
descriptorSet, dstBinding, 0, vk::DescriptorType::eCombinedImageSampler, imageInfo, nullptr, nullptr );
device->updateDescriptorSets( writeDescriptorSets, nullptr );
device.updateDescriptorSets( writeDescriptorSets, nullptr );
}
void updateDescriptorSets(
vk::UniqueDevice const & device,
vk::UniqueDescriptorSet const & descriptorSet,
std::vector<std::tuple<vk::DescriptorType, vk::UniqueBuffer const &, vk::UniqueBufferView const &>> const &
bufferData,
std::vector<vk::su::TextureData> const & textureData,
uint32_t bindingOffset )
vk::Device const & device,
vk::DescriptorSet const & descriptorSet,
std::vector<std::tuple<vk::DescriptorType, vk::Buffer const &, vk::BufferView const &>> const & bufferData,
std::vector<vk::su::TextureData> const & textureData,
uint32_t bindingOffset )
{
std::vector<vk::DescriptorBufferInfo> bufferInfos;
bufferInfos.reserve( bufferData.size() );
@@ -803,15 +798,9 @@ namespace vk
uint32_t dstBinding = bindingOffset;
for ( auto const & bd : bufferData )
{
bufferInfos.push_back( vk::DescriptorBufferInfo( *std::get<1>( bd ), 0, VK_WHOLE_SIZE ) );
writeDescriptorSets.push_back( vk::WriteDescriptorSet( *descriptorSet,
dstBinding++,
0,
1,
std::get<0>( bd ),
nullptr,
&bufferInfos.back(),
std::get<2>( bd ) ? &*std::get<2>( bd ) : nullptr ) );
bufferInfos.emplace_back( std::get<1>( bd ), 0, VK_WHOLE_SIZE );
writeDescriptorSets.emplace_back(
descriptorSet, dstBinding++, 0, 1, std::get<0>( bd ), nullptr, &bufferInfos.back(), &std::get<2>( bd ) );
}
std::vector<vk::DescriptorImageInfo> imageInfos;
@@ -820,24 +809,23 @@ namespace vk
imageInfos.reserve( textureData.size() );
for ( auto const & td : textureData )
{
imageInfos.push_back( vk::DescriptorImageInfo(
*td.textureSampler, *td.imageData->imageView, vk::ImageLayout::eShaderReadOnlyOptimal ) );
imageInfos.emplace_back( td.sampler, td.imageData->imageView, vk::ImageLayout::eShaderReadOnlyOptimal );
}
writeDescriptorSets.push_back( vk::WriteDescriptorSet( *descriptorSet,
dstBinding,
0,
checked_cast<uint32_t>( imageInfos.size() ),
vk::DescriptorType::eCombinedImageSampler,
imageInfos.data(),
nullptr,
nullptr ) );
writeDescriptorSets.emplace_back( descriptorSet,
dstBinding,
0,
checked_cast<uint32_t>( imageInfos.size() ),
vk::DescriptorType::eCombinedImageSampler,
imageInfos.data(),
nullptr,
nullptr );
}
device->updateDescriptorSets( writeDescriptorSets, nullptr );
device.updateDescriptorSets( writeDescriptorSets, nullptr );
}
BufferData::BufferData( vk::PhysicalDevice const & physicalDevice,
vk::UniqueDevice const & device,
vk::Device const & device,
vk::DeviceSize size,
vk::BufferUsageFlags usage,
vk::MemoryPropertyFlags propertyFlags )
@@ -845,18 +833,16 @@ namespace vk
: m_size( size ), m_usage( usage ), m_propertyFlags( propertyFlags )
#endif
{
buffer = device->createBufferUnique( vk::BufferCreateInfo( vk::BufferCreateFlags(), size, usage ) );
deviceMemory = vk::su::allocateMemory( device,
physicalDevice.getMemoryProperties(),
device->getBufferMemoryRequirements( buffer.get() ),
propertyFlags );
device->bindBufferMemory( buffer.get(), deviceMemory.get(), 0 );
buffer = device.createBuffer( vk::BufferCreateInfo( vk::BufferCreateFlags(), size, usage ) );
deviceMemory = vk::su::allocateDeviceMemory(
device, physicalDevice.getMemoryProperties(), device.getBufferMemoryRequirements( buffer ), propertyFlags );
device.bindBufferMemory( buffer, deviceMemory, 0 );
}
DepthBufferData::DepthBufferData( vk::PhysicalDevice & physicalDevice,
vk::UniqueDevice & device,
vk::Format format,
vk::Extent2D const & extent )
DepthBufferData::DepthBufferData( vk::PhysicalDevice const & physicalDevice,
vk::Device const & device,
vk::Format format,
vk::Extent2D const & extent )
: ImageData( physicalDevice,
device,
format,
@@ -869,7 +855,7 @@ namespace vk
{}
ImageData::ImageData( vk::PhysicalDevice const & physicalDevice,
vk::UniqueDevice const & device,
vk::Device const & device,
vk::Format format_,
vk::Extent2D const & extent,
vk::ImageTiling tiling,
@@ -891,47 +877,41 @@ namespace vk
vk::SharingMode::eExclusive,
{},
initialLayout );
image = device->createImageUnique( imageCreateInfo );
image = device.createImage( imageCreateInfo );
deviceMemory = vk::su::allocateMemory( device,
physicalDevice.getMemoryProperties(),
device->getImageMemoryRequirements( image.get() ),
memoryProperties );
deviceMemory = vk::su::allocateDeviceMemory(
device, physicalDevice.getMemoryProperties(), device.getImageMemoryRequirements( image ), memoryProperties );
device->bindImageMemory( image.get(), deviceMemory.get(), 0 );
device.bindImageMemory( image, deviceMemory, 0 );
vk::ComponentMapping componentMapping(
ComponentSwizzle::eR, ComponentSwizzle::eG, ComponentSwizzle::eB, ComponentSwizzle::eA );
vk::ImageViewCreateInfo imageViewCreateInfo( vk::ImageViewCreateFlags(),
image.get(),
vk::ImageViewType::e2D,
format,
componentMapping,
vk::ImageSubresourceRange( aspectMask, 0, 1, 0, 1 ) );
imageView = device->createImageViewUnique( imageViewCreateInfo );
vk::ImageSubresourceRange imageSubresourceRange( aspectMask, 0, 1, 0, 1 );
vk::ImageViewCreateInfo imageViewCreateInfo(
{}, image, vk::ImageViewType::e2D, format, componentMapping, imageSubresourceRange );
imageView = device.createImageView( imageViewCreateInfo );
}
SurfaceData::SurfaceData( vk::UniqueInstance & instance,
SurfaceData::SurfaceData( vk::Instance const & instance,
std::string const & windowName,
vk::Extent2D const & extent_ )
: extent( extent_ ), window( vk::su::createWindow( windowName, extent ) )
{
VkSurfaceKHR _surface;
VkResult err = glfwCreateWindowSurface( VkInstance( instance.get() ), window.handle, nullptr, &_surface );
VkResult err = glfwCreateWindowSurface( static_cast<VkInstance>( instance ), window.handle, nullptr, &_surface );
if ( err != VK_SUCCESS )
throw std::runtime_error( "Failed to create window!" );
vk::ObjectDestroy<vk::Instance, VULKAN_HPP_DEFAULT_DISPATCHER_TYPE> _deleter( instance.get() );
surface = vk::UniqueSurfaceKHR( vk::SurfaceKHR( _surface ), _deleter );
surface = vk::SurfaceKHR( _surface );
}
SwapChainData::SwapChainData( vk::PhysicalDevice const & physicalDevice,
vk::UniqueDevice const & device,
vk::SurfaceKHR const & surface,
vk::Extent2D const & extent,
vk::ImageUsageFlags usage,
vk::UniqueSwapchainKHR const & oldSwapChain,
uint32_t graphicsQueueFamilyIndex,
uint32_t presentQueueFamilyIndex )
SwapChainData::SwapChainData( vk::PhysicalDevice const & physicalDevice,
vk::Device const & device,
vk::SurfaceKHR const & surface,
vk::Extent2D const & extent,
vk::ImageUsageFlags usage,
vk::SwapchainKHR const & oldSwapChain,
uint32_t graphicsQueueFamilyIndex,
uint32_t presentQueueFamilyIndex )
{
vk::SurfaceFormatKHR surfaceFormat = vk::su::pickSurfaceFormat( physicalDevice.getSurfaceFormatsKHR( surface ) );
colorFormat = surfaceFormat.format;
@@ -978,7 +958,7 @@ namespace vk
compositeAlpha,
presentMode,
true,
*oldSwapChain );
oldSwapChain );
if ( graphicsQueueFamilyIndex != presentQueueFamilyIndex )
{
uint32_t queueFamilyIndices[2] = { graphicsQueueFamilyIndex, presentQueueFamilyIndex };
@@ -989,9 +969,9 @@ namespace vk
swapChainCreateInfo.queueFamilyIndexCount = 2;
swapChainCreateInfo.pQueueFamilyIndices = queueFamilyIndices;
}
swapChain = device->createSwapchainKHRUnique( swapChainCreateInfo );
swapChain = device.createSwapchainKHR( swapChainCreateInfo );
images = device->getSwapchainImagesKHR( swapChain.get() );
images = device.getSwapchainImagesKHR( swapChain );
imageViews.reserve( images.size() );
vk::ComponentMapping componentMapping(
@@ -1001,7 +981,7 @@ namespace vk
{
vk::ImageViewCreateInfo imageViewCreateInfo(
vk::ImageViewCreateFlags(), image, vk::ImageViewType::e2D, colorFormat, componentMapping, subResourceRange );
imageViews.push_back( device->createImageViewUnique( imageViewCreateInfo ) );
imageViews.push_back( device.createImageView( imageViewCreateInfo ) );
}
}
@@ -1062,7 +1042,7 @@ namespace vk
}
TextureData::TextureData( vk::PhysicalDevice const & physicalDevice,
vk::UniqueDevice const & device,
vk::Device const & device,
vk::Extent2D const & extent_,
vk::ImageUsageFlags usageFlags,
vk::FormatFeatureFlags formatFeatureFlags,
@@ -1103,21 +1083,21 @@ namespace vk
requirements,
vk::ImageAspectFlagBits::eColor ) );
textureSampler = device->createSamplerUnique( vk::SamplerCreateInfo( vk::SamplerCreateFlags(),
vk::Filter::eLinear,
vk::Filter::eLinear,
vk::SamplerMipmapMode::eLinear,
vk::SamplerAddressMode::eRepeat,
vk::SamplerAddressMode::eRepeat,
vk::SamplerAddressMode::eRepeat,
0.0f,
anisotropyEnable,
16.0f,
false,
vk::CompareOp::eNever,
0.0f,
0.0f,
vk::BorderColor::eFloatOpaqueBlack ) );
sampler = device.createSampler( vk::SamplerCreateInfo( vk::SamplerCreateFlags(),
vk::Filter::eLinear,
vk::Filter::eLinear,
vk::SamplerMipmapMode::eLinear,
vk::SamplerAddressMode::eRepeat,
vk::SamplerAddressMode::eRepeat,
vk::SamplerAddressMode::eRepeat,
0.0f,
anisotropyEnable,
16.0f,
false,
vk::CompareOp::eNever,
0.0f,
0.0f,
vk::BorderColor::eFloatOpaqueBlack ) );
}
UUID::UUID( uint8_t const data[VK_UUID_SIZE] )
@@ -1167,6 +1147,43 @@ namespace vk
GLFWwindow * window = glfwCreateWindow( extent.width, extent.height, windowName.c_str(), nullptr, nullptr );
return WindowData( window, windowName, extent );
}
vk::DebugUtilsMessengerCreateInfoEXT makeDebugUtilsMessengerCreateInfoEXT()
{
return { {},
vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning | vk::DebugUtilsMessageSeverityFlagBitsEXT::eError,
vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral | vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance |
vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation,
&vk::su::debugUtilsMessengerCallback };
}
#if defined( NDEBUG )
vk::StructureChain<vk::InstanceCreateInfo>
#else
vk::StructureChain<vk::InstanceCreateInfo, vk::DebugUtilsMessengerCreateInfoEXT>
#endif
makeInstanceCreateInfoChain( vk::ApplicationInfo const & applicationInfo,
std::vector<char const *> const & layers,
std::vector<char const *> const & extensions )
{
#if defined( NDEBUG )
// in non-debug mode just use the InstanceCreateInfo for instance creation
vk::StructureChain<vk::InstanceCreateInfo> instanceCreateInfo(
{ {}, &applicationInfo, enabledLayers, enabledExtensions } );
#else
// in debug mode, addionally use the debugUtilsMessengerCallback in instance creation!
vk::DebugUtilsMessageSeverityFlagsEXT severityFlags( vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning |
vk::DebugUtilsMessageSeverityFlagBitsEXT::eError );
vk::DebugUtilsMessageTypeFlagsEXT messageTypeFlags( vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral |
vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance |
vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation );
vk::StructureChain<vk::InstanceCreateInfo, vk::DebugUtilsMessengerCreateInfoEXT> instanceCreateInfo(
{ {}, &applicationInfo, layers, extensions },
{ {}, severityFlags, messageTypeFlags, &vk::su::debugUtilsMessengerCallback } );
#endif
return instanceCreateInfo;
}
} // namespace su
} // namespace vk

View File

@@ -29,38 +29,37 @@ namespace vk
const uint64_t FenceTimeout = 100000000;
template <typename Func>
void oneTimeSubmit( vk::UniqueCommandBuffer const & commandBuffer, vk::Queue const & queue, Func const & func )
void oneTimeSubmit( vk::CommandBuffer const & commandBuffer, vk::Queue const & queue, Func const & func )
{
commandBuffer->begin( vk::CommandBufferBeginInfo( vk::CommandBufferUsageFlagBits::eOneTimeSubmit ) );
commandBuffer.begin( vk::CommandBufferBeginInfo( vk::CommandBufferUsageFlagBits::eOneTimeSubmit ) );
func( commandBuffer );
commandBuffer->end();
queue.submit( vk::SubmitInfo( 0, nullptr, nullptr, 1, &( *commandBuffer ) ), nullptr );
commandBuffer.end();
queue.submit( vk::SubmitInfo( 0, nullptr, nullptr, 1, &commandBuffer ), nullptr );
queue.waitIdle();
}
template <typename Func>
void oneTimeSubmit( vk::UniqueDevice const & device,
vk::UniqueCommandPool const & commandPool,
vk::Queue const & queue,
Func const & func )
void oneTimeSubmit( vk::Device const & device,
vk::CommandPool const & commandPool,
vk::Queue const & queue,
Func const & func )
{
vk::UniqueCommandBuffer commandBuffer =
std::move( device
->allocateCommandBuffersUnique(
vk::CommandBufferAllocateInfo( *commandPool, vk::CommandBufferLevel::ePrimary, 1 ) )
.front() );
vk::CommandBuffer commandBuffer =
device
.allocateCommandBuffers( vk::CommandBufferAllocateInfo( commandPool, vk::CommandBufferLevel::ePrimary, 1 ) )
.front();
oneTimeSubmit( commandBuffer, queue, func );
}
template <class T>
void copyToDevice( vk::UniqueDevice const & device,
vk::UniqueDeviceMemory const & memory,
T const * pData,
size_t count,
vk::DeviceSize stride = sizeof( T ) )
void copyToDevice( vk::Device const & device,
vk::DeviceMemory const & deviceMemory,
T const * pData,
size_t count,
vk::DeviceSize stride = sizeof( T ) )
{
assert( sizeof( T ) <= stride );
uint8_t * deviceData = static_cast<uint8_t *>( device->mapMemory( memory.get(), 0, count * stride ) );
uint8_t * deviceData = static_cast<uint8_t *>( device.mapMemory( deviceMemory, 0, count * stride ) );
if ( stride == sizeof( T ) )
{
memcpy( deviceData, pData, count * sizeof( T ) );
@@ -73,13 +72,13 @@ namespace vk
deviceData += stride;
}
}
device->unmapMemory( memory.get() );
device.unmapMemory( deviceMemory );
}
template <class T>
void copyToDevice( vk::UniqueDevice const & device, vk::UniqueDeviceMemory const & memory, T const & data )
void copyToDevice( vk::Device const & device, vk::DeviceMemory const & deviceMemory, T const & data )
{
copyToDevice<T>( device, memory, &data, 1 );
copyToDevice<T>( device, deviceMemory, &data, 1 );
}
template <class T>
@@ -88,11 +87,11 @@ namespace vk
return v < lo ? lo : hi < v ? hi : v;
}
void setImageLayout( vk::UniqueCommandBuffer const & commandBuffer,
vk::Image image,
vk::Format format,
vk::ImageLayout oldImageLayout,
vk::ImageLayout newImageLayout );
void setImageLayout( vk::CommandBuffer const & commandBuffer,
vk::Image image,
vk::Format format,
vk::ImageLayout oldImageLayout,
vk::ImageLayout newImageLayout );
struct WindowData
{
@@ -111,26 +110,32 @@ namespace vk
struct BufferData
{
BufferData( vk::PhysicalDevice const & physicalDevice,
vk::UniqueDevice const & device,
vk::Device const & device,
vk::DeviceSize size,
vk::BufferUsageFlags usage,
vk::MemoryPropertyFlags propertyFlags = vk::MemoryPropertyFlagBits::eHostVisible |
vk::MemoryPropertyFlagBits::eHostCoherent );
void clear( vk::Device const & device )
{
device.freeMemory( deviceMemory );
device.destroyBuffer( buffer );
}
template <typename DataType>
void upload( vk::UniqueDevice const & device, DataType const & data ) const
void upload( vk::Device const & device, DataType const & data ) const
{
assert( ( m_propertyFlags & vk::MemoryPropertyFlagBits::eHostCoherent ) &&
( m_propertyFlags & vk::MemoryPropertyFlagBits::eHostVisible ) );
assert( sizeof( DataType ) <= m_size );
void * dataPtr = device->mapMemory( *this->deviceMemory, 0, sizeof( DataType ) );
void * dataPtr = device.mapMemory( deviceMemory, 0, sizeof( DataType ) );
memcpy( dataPtr, &data, sizeof( DataType ) );
device->unmapMemory( *this->deviceMemory );
device.unmapMemory( deviceMemory );
}
template <typename DataType>
void upload( vk::UniqueDevice const & device, std::vector<DataType> const & data, size_t stride = 0 ) const
void upload( vk::Device const & device, std::vector<DataType> const & data, size_t stride = 0 ) const
{
assert( m_propertyFlags & vk::MemoryPropertyFlagBits::eHostVisible );
@@ -142,8 +147,8 @@ namespace vk
template <typename DataType>
void upload( vk::PhysicalDevice const & physicalDevice,
vk::UniqueDevice const & device,
vk::UniqueCommandPool const & commandPool,
vk::Device const & device,
vk::CommandPool const & commandPool,
vk::Queue queue,
std::vector<DataType> const & data,
size_t stride ) const
@@ -160,13 +165,15 @@ namespace vk
vk::su::BufferData stagingBuffer( physicalDevice, device, dataSize, vk::BufferUsageFlagBits::eTransferSrc );
copyToDevice( device, stagingBuffer.deviceMemory, data.data(), data.size(), elementSize );
vk::su::oneTimeSubmit( device, commandPool, queue, [&]( vk::UniqueCommandBuffer const & commandBuffer ) {
commandBuffer->copyBuffer( *stagingBuffer.buffer, *this->buffer, vk::BufferCopy( 0, 0, dataSize ) );
vk::su::oneTimeSubmit( device, commandPool, queue, [&]( vk::CommandBuffer const & commandBuffer ) {
commandBuffer.copyBuffer( stagingBuffer.buffer, buffer, vk::BufferCopy( 0, 0, dataSize ) );
} );
stagingBuffer.clear( device );
}
vk::UniqueBuffer buffer;
vk::UniqueDeviceMemory deviceMemory;
vk::Buffer buffer;
vk::DeviceMemory deviceMemory;
#if !defined( NDEBUG )
private:
vk::DeviceSize m_size;
@@ -178,7 +185,7 @@ namespace vk
struct ImageData
{
ImageData( vk::PhysicalDevice const & physicalDevice,
vk::UniqueDevice const & device,
vk::Device const & device,
vk::Format format,
vk::Extent2D const & extent,
vk::ImageTiling tiling,
@@ -187,44 +194,62 @@ namespace vk
vk::MemoryPropertyFlags memoryProperties,
vk::ImageAspectFlags aspectMask );
vk::Format format;
vk::UniqueImage image;
vk::UniqueDeviceMemory deviceMemory;
vk::UniqueImageView imageView;
void clear( vk::Device const & device )
{
device.destroyImageView( imageView );
device.freeMemory( deviceMemory );
device.destroyImage( image );
}
vk::Format format;
vk::Image image;
vk::DeviceMemory deviceMemory;
vk::ImageView imageView;
};
struct DepthBufferData : public ImageData
{
DepthBufferData( vk::PhysicalDevice & physicalDevice,
vk::UniqueDevice & device,
vk::Format format,
vk::Extent2D const & extent );
DepthBufferData( vk::PhysicalDevice const & physicalDevice,
vk::Device const & device,
vk::Format format,
vk::Extent2D const & extent );
};
struct SurfaceData
{
SurfaceData( vk::UniqueInstance & instance, std::string const & windowName, vk::Extent2D const & extent );
SurfaceData( vk::Instance const & instance, std::string const & windowName, vk::Extent2D const & extent );
vk::Extent2D extent;
WindowData window;
vk::UniqueSurfaceKHR surface;
vk::Extent2D extent;
WindowData window;
vk::SurfaceKHR surface;
};
struct SwapChainData
{
SwapChainData( vk::PhysicalDevice const & physicalDevice,
vk::UniqueDevice const & device,
vk::SurfaceKHR const & surface,
vk::Extent2D const & extent,
vk::ImageUsageFlags usage,
vk::UniqueSwapchainKHR const & oldSwapChain,
uint32_t graphicsFamilyIndex,
uint32_t presentFamilyIndex );
SwapChainData( vk::PhysicalDevice const & physicalDevice,
vk::Device const & device,
vk::SurfaceKHR const & surface,
vk::Extent2D const & extent,
vk::ImageUsageFlags usage,
vk::SwapchainKHR const & oldSwapChain,
uint32_t graphicsFamilyIndex,
uint32_t presentFamilyIndex );
vk::Format colorFormat;
vk::UniqueSwapchainKHR swapChain;
std::vector<vk::Image> images;
std::vector<vk::UniqueImageView> imageViews;
void clear( vk::Device const & device )
{
for ( auto & imageView : imageViews )
{
device.destroyImageView( imageView );
}
imageViews.clear();
images.clear();
device.destroySwapchainKHR( swapChain );
}
vk::Format colorFormat;
vk::SwapchainKHR swapChain;
std::vector<vk::Image> images;
std::vector<vk::ImageView> imageViews;
};
class CheckerboardImageGenerator
@@ -267,33 +292,42 @@ namespace vk
struct TextureData
{
TextureData( vk::PhysicalDevice const & physicalDevice,
vk::UniqueDevice const & device,
vk::Device const & device,
vk::Extent2D const & extent_ = { 256, 256 },
vk::ImageUsageFlags usageFlags = {},
vk::FormatFeatureFlags formatFeatureFlags = {},
bool anisotropyEnable = false,
bool forceStaging = false );
template <typename ImageGenerator>
void setImage( vk::UniqueDevice const & device,
vk::UniqueCommandBuffer const & commandBuffer,
ImageGenerator const & imageGenerator )
void clear( vk::Device const & device )
{
void * data =
needsStaging
? device->mapMemory( stagingBufferData->deviceMemory.get(),
0,
device->getBufferMemoryRequirements( stagingBufferData->buffer.get() ).size )
: device->mapMemory(
imageData->deviceMemory.get(), 0, device->getImageMemoryRequirements( imageData->image.get() ).size );
if ( stagingBufferData )
{
stagingBufferData->clear( device );
}
imageData->clear( device );
device.destroySampler( sampler );
}
template <typename ImageGenerator>
void setImage( vk::Device const & device,
vk::CommandBuffer const & commandBuffer,
ImageGenerator const & imageGenerator )
{
void * data = needsStaging
? device.mapMemory( stagingBufferData->deviceMemory,
0,
device.getBufferMemoryRequirements( stagingBufferData->buffer ).size )
: device.mapMemory(
imageData->deviceMemory, 0, device.getImageMemoryRequirements( imageData->image ).size );
imageGenerator( data, extent );
device->unmapMemory( needsStaging ? stagingBufferData->deviceMemory.get() : imageData->deviceMemory.get() );
device.unmapMemory( needsStaging ? stagingBufferData->deviceMemory : imageData->deviceMemory );
if ( needsStaging )
{
// Since we're going to blit to the texture image, set its layout to eTransferDstOptimal
vk::su::setImageLayout( commandBuffer,
imageData->image.get(),
imageData->image,
imageData->format,
vk::ImageLayout::eUndefined,
vk::ImageLayout::eTransferDstOptimal );
@@ -303,11 +337,11 @@ namespace vk
vk::ImageSubresourceLayers( vk::ImageAspectFlagBits::eColor, 0, 0, 1 ),
vk::Offset3D( 0, 0, 0 ),
vk::Extent3D( extent, 1 ) );
commandBuffer->copyBufferToImage(
stagingBufferData->buffer.get(), imageData->image.get(), vk::ImageLayout::eTransferDstOptimal, copyRegion );
commandBuffer.copyBufferToImage(
stagingBufferData->buffer, imageData->image, vk::ImageLayout::eTransferDstOptimal, copyRegion );
// Set the layout for the texture image from eTransferDstOptimal to SHADER_READ_ONLY
vk::su::setImageLayout( commandBuffer,
imageData->image.get(),
imageData->image,
imageData->format,
vk::ImageLayout::eTransferDstOptimal,
vk::ImageLayout::eShaderReadOnlyOptimal );
@@ -316,7 +350,7 @@ namespace vk
{
// If we can use the linear tiled image as a texture, just do it
vk::su::setImageLayout( commandBuffer,
imageData->image.get(),
imageData->image,
imageData->format,
vk::ImageLayout::ePreinitialized,
vk::ImageLayout::eShaderReadOnlyOptimal );
@@ -328,7 +362,7 @@ namespace vk
bool needsStaging;
std::unique_ptr<BufferData> stagingBufferData;
std::unique_ptr<ImageData> imageData;
vk::UniqueSampler textureSampler;
vk::Sampler sampler;
};
struct UUID
@@ -351,51 +385,51 @@ namespace vk
return static_cast<TargetType>( value );
}
vk::UniqueDeviceMemory allocateMemory( vk::UniqueDevice const & device,
vk::PhysicalDeviceMemoryProperties const & memoryProperties,
vk::MemoryRequirements const & memoryRequirements,
vk::MemoryPropertyFlags memoryPropertyFlags );
bool contains( std::vector<vk::ExtensionProperties> const & extensionProperties,
std::string const & extensionName );
vk::UniqueCommandPool createCommandPool( vk::UniqueDevice & device, uint32_t queueFamilyIndex );
vk::UniqueDebugUtilsMessengerEXT createDebugUtilsMessenger( vk::UniqueInstance & instance );
vk::UniqueDescriptorPool createDescriptorPool( vk::UniqueDevice & device,
std::vector<vk::DescriptorPoolSize> const & poolSizes );
vk::UniqueDescriptorSetLayout createDescriptorSetLayout(
vk::UniqueDevice const & device,
vk::DeviceMemory allocateDeviceMemory( vk::Device const & device,
vk::PhysicalDeviceMemoryProperties const & memoryProperties,
vk::MemoryRequirements const & memoryRequirements,
vk::MemoryPropertyFlags memoryPropertyFlags );
bool contains( std::vector<vk::ExtensionProperties> const & extensionProperties,
std::string const & extensionName );
vk::CommandPool createCommandPool( vk::Device const & device, uint32_t queueFamilyIndex );
vk::DebugUtilsMessengerEXT createDebugUtilsMessengerEXT( vk::Instance const & instance );
vk::DescriptorPool createDescriptorPool( vk::Device const & device,
std::vector<vk::DescriptorPoolSize> const & poolSizes );
vk::DescriptorSetLayout createDescriptorSetLayout(
vk::Device const & device,
std::vector<std::tuple<vk::DescriptorType, uint32_t, vk::ShaderStageFlags>> const & bindingData,
vk::DescriptorSetLayoutCreateFlags flags = {} );
vk::UniqueDevice createDevice( vk::PhysicalDevice physicalDevice,
uint32_t queueFamilyIndex,
std::vector<std::string> const & extensions = {},
vk::PhysicalDeviceFeatures const * physicalDeviceFeatures = nullptr,
void const * pNext = nullptr );
std::vector<vk::UniqueFramebuffer> createFramebuffers( vk::UniqueDevice & device,
vk::UniqueRenderPass & renderPass,
std::vector<vk::UniqueImageView> const & imageViews,
vk::UniqueImageView const & depthImageView,
vk::Extent2D const & extent );
vk::UniquePipeline
createGraphicsPipeline( vk::UniqueDevice const & device,
vk::UniquePipelineCache 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::UniquePipelineLayout const & pipelineLayout,
vk::UniqueRenderPass const & renderPass );
vk::UniqueInstance createInstance( std::string const & appName,
std::string const & engineName,
std::vector<std::string> const & layers = {},
std::vector<std::string> const & extensions = {},
uint32_t apiVersion = VK_API_VERSION_1_0 );
vk::UniqueRenderPass createRenderPass( vk::UniqueDevice & device,
vk::Format colorFormat,
vk::Format depthFormat,
vk::AttachmentLoadOp loadOp = vk::AttachmentLoadOp::eClear,
vk::ImageLayout colorFinalLayout = vk::ImageLayout::ePresentSrcKHR );
vk::Device createDevice( vk::PhysicalDevice const & physicalDevice,
uint32_t queueFamilyIndex,
std::vector<std::string> const & extensions = {},
vk::PhysicalDeviceFeatures const * physicalDeviceFeatures = nullptr,
void const * pNext = nullptr );
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 );
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 );
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 = VK_API_VERSION_1_0 );
vk::RenderPass createRenderPass( vk::Device const & device,
vk::Format colorFormat,
vk::Format depthFormat,
vk::AttachmentLoadOp loadOp = vk::AttachmentLoadOp::eClear,
vk::ImageLayout colorFinalLayout = vk::ImageLayout::ePresentSrcKHR );
VKAPI_ATTR VkBool32 VKAPI_CALL
debugUtilsMessengerCallback( VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageTypes,
@@ -407,26 +441,45 @@ namespace vk
uint32_t findMemoryType( vk::PhysicalDeviceMemoryProperties const & memoryProperties,
uint32_t typeBits,
vk::MemoryPropertyFlags requirementsMask );
std::vector<std::string> getDeviceExtensions();
std::vector<std::string> getInstanceExtensions();
vk::Format pickDepthFormat( vk::PhysicalDevice const & physicalDevice );
vk::PresentModeKHR pickPresentMode( std::vector<vk::PresentModeKHR> const & presentModes );
vk::SurfaceFormatKHR pickSurfaceFormat( std::vector<vk::SurfaceFormatKHR> const & formats );
void submitAndWait( vk::UniqueDevice & device, vk::Queue queue, vk::UniqueCommandBuffer & commandBuffer );
std::vector<char const *> gatherExtensions( std::vector<std::string> const & extensions
#if !defined( NDEBUG )
,
std::vector<vk::ExtensionProperties> const & extensionProperties
#endif
);
std::vector<char const *> gatherLayers( std::vector<std::string> const & layers
#if !defined( NDEBUG )
,
std::vector<vk::LayerProperties> const & layerProperties
#endif
);
std::vector<std::string> getDeviceExtensions();
std::vector<std::string> getInstanceExtensions();
vk::DebugUtilsMessengerCreateInfoEXT makeDebugUtilsMessengerCreateInfoEXT();
#if defined( NDEBUG )
vk::StructureChain<vk::InstanceCreateInfo>
#else
vk::StructureChain<vk::InstanceCreateInfo, vk::DebugUtilsMessengerCreateInfoEXT>
#endif
makeInstanceCreateInfoChain( vk::ApplicationInfo const & applicationInfo,
std::vector<char const *> const & layers,
std::vector<char const *> const & extensions );
vk::Format pickDepthFormat( vk::PhysicalDevice const & physicalDevice );
vk::PresentModeKHR pickPresentMode( std::vector<vk::PresentModeKHR> const & presentModes );
vk::SurfaceFormatKHR pickSurfaceFormat( std::vector<vk::SurfaceFormatKHR> const & formats );
void submitAndWait( vk::Device const & device, vk::Queue const & queue, vk::CommandBuffer const & commandBuffer );
void updateDescriptorSets(
vk::UniqueDevice const & device,
vk::UniqueDescriptorSet const & descriptorSet,
std::vector<std::tuple<vk::DescriptorType, vk::UniqueBuffer const &, vk::UniqueBufferView const &>> const &
bufferData,
vk::su::TextureData const & textureData,
uint32_t bindingOffset = 0 );
vk::Device const & device,
vk::DescriptorSet const & descriptorSet,
std::vector<std::tuple<vk::DescriptorType, vk::Buffer const &, vk::BufferView const &>> const & bufferData,
vk::su::TextureData const & textureData,
uint32_t bindingOffset = 0 );
void updateDescriptorSets(
vk::UniqueDevice const & device,
vk::UniqueDescriptorSet const & descriptorSet,
std::vector<std::tuple<vk::DescriptorType, vk::UniqueBuffer const &, vk::UniqueBufferView const &>> const &
bufferData,
std::vector<vk::su::TextureData> const & textureData,
uint32_t bindingOffset = 0 );
vk::Device const & device,
vk::DescriptorSet const & descriptorSet,
std::vector<std::tuple<vk::DescriptorType, vk::Buffer const &, vk::BufferView const &>> const & bufferData,
std::vector<vk::su::TextureData> const & textureData,
uint32_t bindingOffset = 0 );
} // namespace su
} // namespace vk