Introduce raii-compliant handle wrapper classes.
This commit is contained in:
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 */
|
||||
}
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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 */
|
||||
}
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user