Add samples DynamicUniform, EnableValidationWithCallback, EnumerateDevicesAdvanced, Events (#313)

+ slightly adjust some other samples.
This commit is contained in:
Andreas Süßenbach 2019-04-01 10:06:49 +02:00 committed by Markus Tavenrath
parent bcc02a1cb0
commit f7ec6041b3
13 changed files with 804 additions and 19 deletions

View File

@ -37,7 +37,6 @@ int main(int /*argc*/, char ** /*argv*/)
std::vector<vk::PhysicalDevice> physicalDevices = instance->enumeratePhysicalDevices();
assert(!physicalDevices.empty());
vk::PhysicalDeviceMemoryProperties memoryProperties = physicalDevices[0].getMemoryProperties();
vk::su::SurfaceData surfaceData(instance, AppName, AppName, vk::Extent2D(500, 500));

View File

@ -37,7 +37,6 @@ int main(int /*argc*/, char ** /*argv*/)
std::vector<vk::PhysicalDevice> physicalDevices = instance->enumeratePhysicalDevices();
assert(!physicalDevices.empty());
vk::PhysicalDeviceMemoryProperties memoryProperties = physicalDevices[0].getMemoryProperties();
vk::su::SurfaceData surfaceData(instance, AppName, AppName, vk::Extent2D(500, 500));
@ -77,7 +76,7 @@ int main(int /*argc*/, char ** /*argv*/)
std::vector<vk::UniqueDescriptorSet> descriptorSets = device->allocateDescriptorSetsUnique(vk::DescriptorSetAllocateInfo(descriptorPool.get(), 1, &descriptorSetLayout.get()));
vk::DescriptorBufferInfo descriptorBufferInfo(uniformBufferData.buffer.get(), 0, sizeof(glm::mat4x4));
vk::su::updateDescriptorSets(device, descriptorSets[0], &descriptorBufferInfo);
vk::su::updateDescriptorSets(device, descriptorSets[0], vk::DescriptorType::eUniformBuffer, &descriptorBufferInfo);
vk::UniquePipelineCache pipelineCache = device->createPipelineCacheUnique(vk::PipelineCacheCreateInfo());
vk::UniquePipeline graphicsPipeline = vk::su::createGraphicsPipeline(device, pipelineCache, vertexShaderModule, fragmentShaderModule, sizeof(coloredCubeData[0]), pipelineLayout, renderPass);

View File

@ -134,7 +134,6 @@ int main(int /*argc*/, char ** /*argv*/)
std::vector<vk::PhysicalDevice> physicalDevices = instance->enumeratePhysicalDevices();
assert(!physicalDevices.empty());
vk::PhysicalDeviceMemoryProperties memoryProperties = physicalDevices[0].getMemoryProperties();
vk::su::SurfaceData surfaceData(instance, AppName, AppName, vk::Extent2D(500, 500));
@ -160,7 +159,7 @@ int main(int /*argc*/, char ** /*argv*/)
vk::su::BufferData uniformBufferData(physicalDevices[0], device, sizeof(glm::mat4x4), vk::BufferUsageFlagBits::eUniformBuffer);
vk::su::copyToDevice(device, uniformBufferData.deviceMemory, vk::su::createModelViewProjectionClipMatrix());
vk::UniqueDescriptorSetLayout descriptorSetLayout = vk::su::createDescriptorSetLayout(device, textured);
vk::UniqueDescriptorSetLayout descriptorSetLayout = vk::su::createDescriptorSetLayout(device, vk::DescriptorType::eUniformBuffer, textured);
vk::UniquePipelineLayout pipelineLayout = device->createPipelineLayoutUnique(vk::PipelineLayoutCreateInfo(vk::PipelineLayoutCreateFlags(), 1, &descriptorSetLayout.get()));
vk::UniqueRenderPass renderPass = vk::su::createRenderPass(device, vk::su::pickColorFormat(physicalDevices[0].getSurfaceFormatsKHR(surfaceData.surface.get())), depthBufferData.format);
@ -175,12 +174,12 @@ int main(int /*argc*/, char ** /*argv*/)
vk::su::BufferData vertexBufferData(physicalDevices[0], device, sizeof(texturedCubeData), vk::BufferUsageFlagBits::eVertexBuffer);
vk::su::copyToDevice(device, vertexBufferData.deviceMemory, texturedCubeData, sizeof(texturedCubeData) / sizeof(texturedCubeData[0]));
vk::UniqueDescriptorPool descriptorPool = vk::su::createDescriptorPool(device, textured);
vk::UniqueDescriptorPool descriptorPool = vk::su::createDescriptorPool(device, vk::DescriptorType::eUniformBuffer, textured);
std::vector<vk::UniqueDescriptorSet> descriptorSets = device->allocateDescriptorSetsUnique(vk::DescriptorSetAllocateInfo(descriptorPool.get(), 1, &descriptorSetLayout.get()));
vk::DescriptorBufferInfo bufferInfo(uniformBufferData.buffer.get(), 0, sizeof(glm::mat4x4));
vk::DescriptorImageInfo imageInfo(textureData.textureSampler.get(), textureData.imageData->imageView.get(), vk::ImageLayout::eShaderReadOnlyOptimal);
vk::su::updateDescriptorSets(device, descriptorSets[0], &bufferInfo, &imageInfo);
vk::su::updateDescriptorSets(device, descriptorSets[0], vk::DescriptorType::eUniformBuffer, &bufferInfo, &imageInfo);
vk::UniquePipelineCache pipelineCache = device->createPipelineCacheUnique(vk::PipelineCacheCreateInfo());
vk::UniquePipeline graphicsPipeline = vk::su::createGraphicsPipeline(device, pipelineCache, vertexShaderModule, fragmentShaderModule, sizeof(texturedCubeData[0]), pipelineLayout, renderPass);

View File

@ -0,0 +1,44 @@
# Copyright(c) 2019, NVIDIA CORPORATION. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
cmake_minimum_required(VERSION 3.2)
project(DynamicUniform)
set(HEADERS
../utils/geometries.hpp
../utils/math.hpp
../utils/shaders.hpp
../utils/utils.hpp
)
set(SOURCES
DynamicUniform.cpp
../utils/math.cpp
../utils/shaders.cpp
../utils/utils.cpp
)
source_group(headers FILES ${HEADERS})
source_group(sources FILES ${SOURCES})
add_executable(DynamicUniform
${HEADERS}
${SOURCES}
)
set_target_properties(DynamicUniform PROPERTIES FOLDER "Samples")
target_include_directories(DynamicUniform PUBLIC ${CMAKE_SOURCE_DIR}/glslang)
target_link_libraries(DynamicUniform PUBLIC glslang SPIRV "$ENV{VULKAN_SDK}/Lib/vulkan-1.lib"
)

View File

@ -0,0 +1,186 @@
// Copyright(c) 2019, NVIDIA CORPORATION. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// VulkanHpp Samples : DynamicUniform
// Draw 2 Cubes using dynamic uniform buffer
#include "../utils/geometries.hpp"
#include "../utils/math.hpp"
#include "../utils/shaders.hpp"
#include "../utils/utils.hpp"
#include "vulkan/vulkan.hpp"
#include "SPIRV/GlslangToSpv.h"
#include <iostream>
static char const* AppName = "DynamicUniform";
static char const* EngineName = "Vulkan.hpp";
int main(int /*argc*/, char ** /*argv*/)
{
try
{
vk::UniqueInstance instance = vk::su::createInstance(AppName, EngineName, vk::su::getInstanceExtensions());
#if !defined(NDEBUG)
vk::UniqueDebugReportCallbackEXT debugReportCallback = vk::su::createDebugReportCallback(instance);
#endif
std::vector<vk::PhysicalDevice> physicalDevices = instance->enumeratePhysicalDevices();
assert(!physicalDevices.empty());
vk::su::SurfaceData surfaceData(instance, AppName, AppName, vk::Extent2D(500, 500));
std::pair<uint32_t, uint32_t> graphicsAndPresentQueueFamilyIndex = vk::su::findGraphicsAndPresentQueueFamilyIndex(physicalDevices[0], surfaceData.surface);
vk::UniqueDevice device = vk::su::createDevice(physicalDevices[0], graphicsAndPresentQueueFamilyIndex.first, vk::su::getDeviceExtensions());
vk::UniqueCommandPool commandPool = vk::su::createCommandPool(device, graphicsAndPresentQueueFamilyIndex.first);
std::vector<vk::UniqueCommandBuffer> commandBuffers = device->allocateCommandBuffersUnique(vk::CommandBufferAllocateInfo(commandPool.get(), vk::CommandBufferLevel::ePrimary, 1));
vk::Queue graphicsQueue = device->getQueue(graphicsAndPresentQueueFamilyIndex.first, 0);
vk::Queue presentQueue = device->getQueue(graphicsAndPresentQueueFamilyIndex.second, 0);
vk::su::SwapChainData swapChainData(physicalDevices[0], device, surfaceData.surface, surfaceData.extent, vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eTransferSrc
, graphicsAndPresentQueueFamilyIndex.first, graphicsAndPresentQueueFamilyIndex.second);
vk::su::DepthBufferData depthBufferData(physicalDevices[0], device, vk::Format::eD16Unorm, surfaceData.extent);
vk::UniqueRenderPass renderPass = vk::su::createRenderPass(device, vk::su::pickColorFormat(physicalDevices[0].getSurfaceFormatsKHR(surfaceData.surface.get())), depthBufferData.format);
glslang::InitializeProcess();
vk::UniqueShaderModule vertexShaderModule = vk::su::createShaderModule(device, vk::ShaderStageFlagBits::eVertex, vertexShaderText_PC_C);
vk::UniqueShaderModule 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, depthBufferData.imageView, surfaceData.extent);
vk::su::BufferData vertexBufferData(physicalDevices[0], device, sizeof(coloredCubeData), vk::BufferUsageFlagBits::eVertexBuffer);
vk::su::copyToDevice(device, vertexBufferData.deviceMemory, coloredCubeData, sizeof(coloredCubeData) / sizeof(coloredCubeData[0]));
/* VULKAN_KEY_START */
vk::PhysicalDeviceLimits limits = physicalDevices[0].getProperties().limits;
if (limits.maxDescriptorSetUniformBuffersDynamic < 1)
{
std::cout << "No dynamic uniform buffers supported\n";
exit(-1);
}
/* Set up uniform buffer with 2 transform matrices in it */
glm::mat4x4 mvpcs[2];
glm::mat4x4 model = glm::mat4x4(1.0f);
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;
model = glm::translate(model, glm::vec3(-1.5f, -1.5f, -1.5f));
mvpcs[1] = clip * projection * view * model;
VkDeviceSize bufferSize = sizeof(glm::mat4x4);
if (limits.minUniformBufferOffsetAlignment)
{
bufferSize = (bufferSize + limits.minUniformBufferOffsetAlignment - 1) & ~(limits.minUniformBufferOffsetAlignment - 1);
}
vk::su::BufferData uniformBufferData(physicalDevices[0], device, 2 * bufferSize, vk::BufferUsageFlagBits::eUniformBuffer);
vk::su::copyToDevice(device, uniformBufferData.deviceMemory, mvpcs, 2, bufferSize);
// create a DescriptorSetLayout with vk::DescriptorType::eUniformBufferDynamic
vk::UniqueDescriptorSetLayout descriptorSetLayout = vk::su::createDescriptorSetLayout(device, vk::DescriptorType::eUniformBufferDynamic);
vk::UniquePipelineLayout pipelineLayout = device->createPipelineLayoutUnique(vk::PipelineLayoutCreateInfo(vk::PipelineLayoutCreateFlags(), 1, &descriptorSetLayout.get()));
// create a DescriptorPool with vk::DescriptorType::eUniformBufferDynamic
vk::UniqueDescriptorPool descriptorPool = vk::su::createDescriptorPool(device, vk::DescriptorType::eUniformBufferDynamic);
std::vector<vk::UniqueDescriptorSet> descriptorSets = device->allocateDescriptorSetsUnique(vk::DescriptorSetAllocateInfo(descriptorPool.get(), 1, &descriptorSetLayout.get()));
vk::DescriptorBufferInfo descriptorBufferInfo(uniformBufferData.buffer.get(), 0, sizeof(glm::mat4x4));
vk::su::updateDescriptorSets(device, descriptorSets[0], vk::DescriptorType::eUniformBufferDynamic, &descriptorBufferInfo);
vk::UniquePipelineCache pipelineCache = device->createPipelineCacheUnique(vk::PipelineCacheCreateInfo());
vk::UniquePipeline graphicsPipeline = vk::su::createGraphicsPipeline(device, pipelineCache, vertexShaderModule, fragmentShaderModule, sizeof(coloredCubeData[0]), 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);
assert(currentBuffer.result == vk::Result::eSuccess);
assert(currentBuffer.value < framebuffers.size());
commandBuffers[0]->begin(vk::CommandBufferBeginInfo(vk::CommandBufferUsageFlags()));
vk::ClearValue clearValues[2];
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::Rect2D(vk::Offset2D(0, 0), surfaceData.extent), 2, clearValues);
commandBuffers[0]->beginRenderPass(renderPassBeginInfo, vk::SubpassContents::eInline);
commandBuffers[0]->bindPipeline(vk::PipelineBindPoint::eGraphics, graphicsPipeline.get());
vk::Viewport viewport(0.0f, 0.0f, static_cast<float>(surfaceData.extent.width), static_cast<float>(surfaceData.extent.height), 0.0f, 1.0f);
commandBuffers[0]->setViewport(0, viewport);
vk::Rect2D scissor(vk::Offset2D(0, 0), surfaceData.extent);
commandBuffers[0]->setScissor(0, scissor);
/* The first draw should use the first matrix in the buffer */
uint32_t dynamicOffset = 0;
commandBuffers[0]->bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipelineLayout.get(), 0, descriptorSets[0].get(), dynamicOffset);
vk::DeviceSize vertexOffset = 0;
commandBuffers[0]->bindVertexBuffers(0, vertexBufferData.buffer.get(), vertexOffset);
commandBuffers[0]->draw(12 * 3, 1, 0, 0);
// the second draw should use the second matrix in the buffer;
dynamicOffset = (uint32_t)bufferSize;
commandBuffers[0]->bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipelineLayout.get(), 0, descriptorSets[0].get(), dynamicOffset);
commandBuffers[0]->draw(12 * 3, 1, 0, 0);
commandBuffers[0]->endRenderPass();
commandBuffers[0]->end();
vk::UniqueFence drawFence = device->createFenceUnique(vk::FenceCreateInfo());
vk::PipelineStageFlags waitDestinationStageMask(vk::PipelineStageFlagBits::eColorAttachmentOutput);
vk::SubmitInfo submitInfo(1, &imageAcquiredSemaphore.get(), &waitDestinationStageMask, 1, &commandBuffers[0].get());
graphicsQueue.submit(submitInfo, drawFence.get());
while (vk::Result::eTimeout == device->waitForFences(drawFence.get(), VK_TRUE, vk::su::FenceTimeout))
;
presentQueue.presentKHR(vk::PresentInfoKHR(0, nullptr, 1, &swapChainData.swapChain.get(), &currentBuffer.value));
Sleep(1000);
/* VULKAN_KEY_END */
device->waitIdle();
#if defined(VK_USE_PLATFORM_WIN32_KHR)
DestroyWindow(surfaceData.window);
#else
#pragma error "unhandled platform"
#endif
}
catch (vk::SystemError err)
{
std::cout << "vk::SystemError: " << err.what() << std::endl;
exit(-1);
}
catch (std::runtime_error err)
{
std::cout << "std::runtime_error: " << err.what() << std::endl;
exit(-1);
}
catch (...)
{
std::cout << "unknown error\n";
exit(-1);
}
return 0;
}

View File

@ -0,0 +1,37 @@
# Copyright(c) 2019, NVIDIA CORPORATION. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
cmake_minimum_required(VERSION 3.2)
project(EnableValidationWithCallback)
set(HEADERS
)
set(SOURCES
EnableValidationWithCallback.cpp
)
source_group(headers FILES ${HEADERS})
source_group(sources FILES ${SOURCES})
add_executable(EnableValidationWithCallback
${HEADERS}
${SOURCES}
)
set_target_properties(EnableValidationWithCallback PROPERTIES FOLDER "Samples")
target_include_directories(EnableValidationWithCallback PUBLIC ${CMAKE_SOURCE_DIR}/glslang)
target_link_libraries(EnableValidationWithCallback PUBLIC glslang SPIRV "$ENV{VULKAN_SDK}/Lib/vulkan-1.lib"
)

View File

@ -0,0 +1,178 @@
// Copyright(c) 2019, NVIDIA CORPORATION. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// VulkanHpp Samples : EnableValidationWithCallback
// Show how to enable validation layers and provide callback
#include "../utils/utils.hpp"
#include "vulkan/vulkan.hpp"
#include <algorithm>
#include <iostream>
#include <sstream>
static char const* AppName = "EnableValidationWithCallback";
static char const* EngineName = "Vulkan.hpp";
PFN_vkCreateDebugReportCallbackEXT pfnVkCreateDebugReportCallbackEXT;
PFN_vkDestroyDebugReportCallbackEXT pfnVkDestroyDebugReportCallbackEXT;
VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback)
{
return pfnVkCreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pCallback);
}
VKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT callback, const VkAllocationCallbacks* pAllocator)
{
pfnVkDestroyDebugReportCallbackEXT(instance, callback, pAllocator);
}
VKAPI_ATTR VkBool32 VKAPI_CALL dbgFunc(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT /*objType*/, uint64_t /*srcObject*/, size_t /*location*/, int32_t msgCode, const char *pLayerPrefix, const char *pMsg, void * /*pUserData*/)
{
std::ostringstream message;
switch (flags)
{
case VK_DEBUG_REPORT_INFORMATION_BIT_EXT:
message << "INFORMATION: ";
break;
case VK_DEBUG_REPORT_WARNING_BIT_EXT:
message << "WARNING: ";
break;
case VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT:
message << "PERFORMANCE WARNING: ";
break;
case VK_DEBUG_REPORT_ERROR_BIT_EXT:
message << "ERROR: ";
break;
case VK_DEBUG_REPORT_DEBUG_BIT_EXT:
message << "DEBUG: ";
break;
default:
message << "unknown flag (" << flags << "): ";
break;
}
message << "[" << pLayerPrefix << "] Code " << msgCode << " : " << pMsg;
#ifdef _WIN32
MessageBox(NULL, message.str().c_str(), "Alert", MB_OK);
#else
std::cout << message.str() << std::endl;
#endif
return false;
}
bool checkLayers(std::vector<char const*> const& layers, std::vector<vk::LayerProperties> const& properties)
{
// return true if all layers are listed in the properties
return std::all_of(layers.begin(), layers.end(), [&properties](char const* name)
{
return std::find_if(properties.begin(), properties.end(), [&name](vk::LayerProperties const& property) { return strcmp(property.layerName, name) == 0; }) != properties.end();
});
}
int main(int /*argc*/, char ** /*argv*/)
{
try
{
std::vector<vk::LayerProperties> instanceLayerProperties = vk::enumerateInstanceLayerProperties();
/* VULKAN_KEY_START */
// Use standard_validation meta layer that enables all recommended validation layers
std::vector<char const*> instanceLayerNames;
instanceLayerNames.push_back("VK_LAYER_LUNARG_standard_validation");
if (!checkLayers(instanceLayerNames, instanceLayerProperties))
{
// If standard validation is not present, search instead for the individual layers that make it up, in the correct order.
instanceLayerNames.clear();
instanceLayerNames.push_back("VK_LAYER_GOOGLE_threading");
instanceLayerNames.push_back("VK_LAYER_LUNARG_parameter_validation");
instanceLayerNames.push_back("VK_LAYER_LUNARG_object_tracker");
instanceLayerNames.push_back("VK_LAYER_LUNARG_core_validation");
instanceLayerNames.push_back("VK_LAYER_GOOGLE_unique_objects");
if (!checkLayers(instanceLayerNames, instanceLayerProperties))
{
std::cout << "Set the environment variable VK_LAYER_PATH to point to the location of your layers" << std::endl;
exit(1);
}
}
/* Enable debug callback extension */
std::vector<char const*> instanceExtensionNames;
instanceExtensionNames.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
vk::ApplicationInfo applicationInfo(AppName, 1, EngineName, 1, VK_API_VERSION_1_0);
vk::InstanceCreateInfo instanceCreateInfo( vk::InstanceCreateFlags(), &applicationInfo, vk::su::checked_cast<uint32_t>(instanceLayerNames.size()), instanceLayerNames.data(),
vk::su::checked_cast<uint32_t>(instanceExtensionNames.size()) , instanceExtensionNames.data() );
vk::UniqueInstance instance = vk::createInstanceUnique(instanceCreateInfo);
std::vector<vk::PhysicalDevice> physicalDevices = instance->enumeratePhysicalDevices();
assert(!physicalDevices.empty());
std::vector<vk::QueueFamilyProperties> queueFamilyProperties = physicalDevices[0].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));
float queuePriority = 0.0f;
vk::DeviceQueueCreateInfo deviceQueueCreateInfo(vk::DeviceQueueCreateFlags(), queueFamilyIndex, 1, &queuePriority);
vk::UniqueDevice device = physicalDevices[0].createDeviceUnique(vk::DeviceCreateInfo(vk::DeviceCreateFlags(), 1, &deviceQueueCreateInfo));
pfnVkCreateDebugReportCallbackEXT = reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>(instance->getProcAddr("vkCreateDebugReportCallbackEXT"));
if (!pfnVkCreateDebugReportCallbackEXT)
{
std::cout << "GetInstanceProcAddr: Unable to find vkCreateDebugReportCallbackEXT function." << std::endl;
exit(1);
}
pfnVkDestroyDebugReportCallbackEXT = reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>(instance->getProcAddr("vkDestroyDebugReportCallbackEXT"));
if (!pfnVkDestroyDebugReportCallbackEXT)
{
std::cout << "GetInstanceProcAddr: Unable to find vkDestroyDebugReportCallbackEXT function." << std::endl;
exit(1);
}
vk::UniqueDebugReportCallbackEXT debugReportCallback = instance->createDebugReportCallbackEXTUnique(vk::DebugReportCallbackCreateInfoEXT(vk::DebugReportFlagBitsEXT::eError | vk::DebugReportFlagBitsEXT::eWarning, dbgFunc));
// Create a command pool (not a UniqueCommandPool, for testing purposes!
vk::CommandPool commandPool = device->createCommandPool(vk::CommandPoolCreateInfo(vk::CommandPoolCreateFlags(), queueFamilyIndex));
// The commandPool is not destroyed automatically (as it's not a UniqueCommandPool.
// 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 << "*** The following error message is EXPECTED ***\n";
/* VULKAN_KEY_END */
}
catch (vk::SystemError err)
{
std::cout << "vk::SystemError: " << err.what() << std::endl;
exit(-1);
}
catch (std::runtime_error err)
{
std::cout << "std::runtime_error: " << err.what() << std::endl;
exit(-1);
}
catch (...)
{
std::cout << "unknown error\n";
exit(-1);
}
return 0;
}

View File

@ -0,0 +1,37 @@
# Copyright(c) 2018-2019, NVIDIA CORPORATION. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
cmake_minimum_required(VERSION 3.2)
project(EnumerateDevicesAdvanced)
set(HEADERS
../utils/utils.hpp
)
set(SOURCES
EnumerateDevicesAdvanced.cpp
../utils/utils.cpp
)
source_group(headers FILES ${HEADERS})
source_group(sources FILES ${SOURCES})
add_executable(EnumerateDevicesAdvanced
${HEADERS}
${SOURCES}
)
set_target_properties(EnumerateDevicesAdvanced PROPERTIES FOLDER "Samples")
target_link_libraries(EnumerateDevicesAdvanced "$ENV{VULKAN_SDK}/Lib/vulkan-1.lib")

View File

@ -0,0 +1,94 @@
// Copyright(c) 2018-2019, NVIDIA CORPORATION. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// VulkanHpp Samples : EnumerateDevicesAdvanced
// Enumerate physical devices
#include "../utils/utils.hpp"
#include "vulkan/vulkan.hpp"
#include <iomanip>
#include <iostream>
static char const* AppName = "EnumerateDevicesAdvanced";
static char const* EngineName = "Vulkan.hpp";
void print_UUID(uint8_t *pipelineCacheUUID)
{
for (int j = 0; j < VK_UUID_SIZE; ++j)
{
std::cout << std::setw(2) << (uint32_t)pipelineCacheUUID[j];
if (j == 3 || j == 5 || j == 7 || j == 9)
{
std::cout << '-';
}
}
}
int main(int /*argc*/, char ** /*argv*/)
{
try
{
vk::UniqueInstance instance = vk::su::createInstance(AppName, EngineName);
#if !defined(NDEBUG)
vk::UniqueDebugReportCallbackEXT debugReportCallback = vk::su::createDebugReportCallback(instance);
#endif
/* VULKAN_HPP_KEY_START */
// enumerate the physicalDevices
std::vector<vk::PhysicalDevice> physicalDevices = instance->enumeratePhysicalDevices();
for (auto const& physicalDevice : physicalDevices)
{
vk::PhysicalDeviceProperties properties = physicalDevice.getProperties();
std::cout << "apiVersion: ";
std::cout << ((properties.apiVersion >> 22) & 0xfff) << '.'; // Major.
std::cout << ((properties.apiVersion >> 12) & 0x3ff) << '.'; // Minor.
std::cout << (properties.apiVersion & 0xfff); // Patch.
std::cout << '\n';
std::cout << "driverVersion: " << properties.driverVersion << '\n';
std::cout << std::showbase << std::internal << std::setfill('0') << std::hex;
std::cout << "vendorId: " << std::setw(6) << properties.vendorID << '\n';
std::cout << "deviceId: " << std::setw(6) << properties.deviceID << '\n';
std::cout << std::noshowbase << std::right << std::setfill(' ') << std::dec;
std::cout << "deviceType: " << vk::to_string(properties.deviceType) << "\n";
std::cout << "deviceName: " << properties.deviceName << '\n';
std::cout << "pipelineCacheUUID: ";
std::cout << std::setfill('0') << std::hex;
print_UUID(properties.pipelineCacheUUID);
std::cout << std::setfill(' ') << std::dec;
std::cout << '\n';
std::cout << '\n';
}
/* VULKAN_HPP_KEY_END */
}
catch (vk::SystemError err)
{
std::cout << "vk::SystemError: " << err.what() << std::endl;
exit(-1);
}
catch (...)
{
std::cout << "unknown error\n";
exit(-1);
}
return 0;
}

View File

@ -0,0 +1,44 @@
# Copyright(c) 2019, NVIDIA CORPORATION. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
cmake_minimum_required(VERSION 3.2)
project(Events)
set(HEADERS
../utils/geometries.hpp
../utils/math.hpp
../utils/shaders.hpp
../utils/utils.hpp
)
set(SOURCES
Events.cpp
../utils/math.cpp
../utils/shaders.cpp
../utils/utils.cpp
)
source_group(headers FILES ${HEADERS})
source_group(sources FILES ${SOURCES})
add_executable(Events
${HEADERS}
${SOURCES}
)
set_target_properties(Events PROPERTIES FOLDER "Samples")
target_include_directories(Events PUBLIC ${CMAKE_SOURCE_DIR}/glslang)
target_link_libraries(Events PUBLIC glslang SPIRV "$ENV{VULKAN_SDK}/Lib/vulkan-1.lib"
)

156
samples/Events/Events.cpp Normal file
View File

@ -0,0 +1,156 @@
// Copyright(c) 2019, NVIDIA CORPORATION. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// VulkanHpp Samples : Events
// Use basic events
#include "../utils/geometries.hpp"
#include "../utils/math.hpp"
#include "../utils/shaders.hpp"
#include "../utils/utils.hpp"
#include "vulkan/vulkan.hpp"
#include "SPIRV/GlslangToSpv.h"
#include <iostream>
static char const* AppName = "Events";
static char const* EngineName = "Vulkan.hpp";
int main(int /*argc*/, char ** /*argv*/)
{
try
{
vk::UniqueInstance instance = vk::su::createInstance(AppName, EngineName, vk::su::getInstanceExtensions());
#if !defined(NDEBUG)
vk::UniqueDebugReportCallbackEXT debugReportCallback = vk::su::createDebugReportCallback(instance);
#endif
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::UniqueCommandPool commandPool = vk::su::createCommandPool(device, graphicsQueueFamilyIndex);
std::vector<vk::UniqueCommandBuffer> commandBuffers = device->allocateCommandBuffersUnique(vk::CommandBufferAllocateInfo(commandPool.get(), vk::CommandBufferLevel::ePrimary, 1));
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
commandBuffers[0]->begin(vk::CommandBufferBeginInfo(vk::CommandBufferUsageFlags()));
commandBuffers[0]->setViewport(0, vk::Viewport(0.0f, 0.0f, 10.0f, 10.0f, 0.0f, 1.0f));
commandBuffers[0]->end();
vk::UniqueFence fence = device->createFenceUnique(vk::FenceCreateInfo());
vk::PipelineStageFlags waitDestinationStageMask(vk::PipelineStageFlagBits::eColorAttachmentOutput);
vk::SubmitInfo submitInfo(0, nullptr, &waitDestinationStageMask, 1, &commandBuffers[0].get());
graphicsQueue.submit(submitInfo, fence.get());
// 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);
timeouts++;
} while (result == vk::Result::eTimeout);
assert(result == vk::Result::eSuccess);
if (timeouts != 0)
{
std::cout << "Unsuitable timeout value, exiting\n";
exit(-1);
}
// Now create an event and wait for it on the GPU
vk::UniqueEvent event = device->createEventUnique(vk::EventCreateInfo(vk::EventCreateFlags()));
commandBuffers[0]->reset(vk::CommandBufferResetFlags());
commandBuffers[0]->begin(vk::CommandBufferBeginInfo());
commandBuffers[0]->waitEvents(event.get(), vk::PipelineStageFlagBits::eHost, vk::PipelineStageFlagBits::eBottomOfPipe, nullptr, nullptr, nullptr);
commandBuffers[0]->end();
device->resetFences(fence.get());
// 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 vkQueueSubmit through vkSetEvent without breakpoints
waitDestinationStageMask = vk::PipelineStageFlagBits::eBottomOfPipe;
graphicsQueue.submit(submitInfo, fence.get());
// 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);
if (result != vk::Result::eTimeout)
{
std::cout << "Didn't get expected timeout in vkWaitForFences, exiting\n";
exit(-1);
}
// Set the event from the CPU and wait for the fence.
// This should succeed since we set the event
device->setEvent(event.get());
do
{
result = device->waitForFences(fence.get(), true, vk::su::FenceTimeout);
} while (result == vk::Result::eTimeout);
assert(result == vk::Result::eSuccess);
commandBuffers[0]->reset({});
device->resetFences(fence.get());
device->resetEvent(event.get());
// Now set the event from the GPU and wait on the CPU
commandBuffers[0]->begin(vk::CommandBufferBeginInfo());
commandBuffers[0]->setEvent(event.get(), vk::PipelineStageFlagBits::eBottomOfPipe);
commandBuffers[0]->end();
// Look for the event on the CPU. It should be RESET since we haven't sent the command buffer yet.
result = device->getEventStatus(event.get());
assert(result == vk::Result::eEventReset);
// Send the command buffer and loop waiting for the event
graphicsQueue.submit(submitInfo, fence.get());
int polls = 0;
do
{
result = device->getEventStatus(event.get());
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);
} while (result == vk::Result::eTimeout);
assert(result == vk::Result::eSuccess);
/* VULKAN_KEY_END */
}
catch (vk::SystemError err)
{
std::cout << "vk::SystemError: " << err.what() << std::endl;
exit(-1);
}
catch (std::runtime_error err)
{
std::cout << "std::runtime_error: " << err.what() << std::endl;
exit(-1);
}
catch (...)
{
std::cout << "unknown error\n";
exit(-1);
}
return 0;
}

View File

@ -66,10 +66,10 @@ namespace vk
return instance->createDebugReportCallbackEXTUnique(vk::DebugReportCallbackCreateInfoEXT(flags, &vk::su::debugReportCallback));
}
vk::UniqueDescriptorPool createDescriptorPool(vk::UniqueDevice &device, bool textured)
vk::UniqueDescriptorPool createDescriptorPool(vk::UniqueDevice &device, vk::DescriptorType descriptorType, bool textured)
{
std::vector<vk::DescriptorPoolSize> poolSizes;
poolSizes.push_back(vk::DescriptorPoolSize(vk::DescriptorType::eUniformBuffer, 1));
poolSizes.push_back(vk::DescriptorPoolSize(descriptorType, 1));
if (textured)
{
poolSizes.push_back(vk::DescriptorPoolSize(vk::DescriptorType::eCombinedImageSampler, 1));
@ -78,10 +78,10 @@ namespace vk
return device->createDescriptorPoolUnique(descriptorPoolCreateInfo);
}
vk::UniqueDescriptorSetLayout createDescriptorSetLayout(vk::UniqueDevice &device, bool textured)
vk::UniqueDescriptorSetLayout createDescriptorSetLayout(vk::UniqueDevice &device, vk::DescriptorType descriptorType, bool textured)
{
std::vector<vk::DescriptorSetLayoutBinding> bindings;
bindings.push_back(vk::DescriptorSetLayoutBinding(0, vk::DescriptorType::eUniformBuffer, 1, vk::ShaderStageFlagBits::eVertex));
bindings.push_back(vk::DescriptorSetLayoutBinding(0, descriptorType, 1, vk::ShaderStageFlagBits::eVertex));
if (textured)
{
bindings.push_back(vk::DescriptorSetLayoutBinding(1, vk::DescriptorType::eCombinedImageSampler, 1, vk::ShaderStageFlagBits::eFragment));
@ -392,10 +392,10 @@ namespace vk
;
}
void updateDescriptorSets(vk::UniqueDevice &device, vk::UniqueDescriptorSet &descriptorSet, vk::DescriptorBufferInfo const* descriptorBufferInfo, vk::DescriptorImageInfo const* descriptorImageInfo)
void updateDescriptorSets(vk::UniqueDevice &device, vk::UniqueDescriptorSet &descriptorSet, vk::DescriptorType descriptorType, vk::DescriptorBufferInfo const* descriptorBufferInfo, vk::DescriptorImageInfo const* descriptorImageInfo)
{
std::vector<vk::WriteDescriptorSet> writeDescriptorSets;
writeDescriptorSets.push_back(vk::WriteDescriptorSet(descriptorSet.get(), 0, 0, 1, vk::DescriptorType::eUniformBuffer, nullptr, descriptorBufferInfo, nullptr));
writeDescriptorSets.push_back(vk::WriteDescriptorSet(descriptorSet.get(), 0, 0, 1, descriptorType, nullptr, descriptorBufferInfo, nullptr));
if (descriptorImageInfo)
{
writeDescriptorSets.push_back(vk::WriteDescriptorSet(descriptorSet.get(), 1, 0, 1, vk::DescriptorType::eCombinedImageSampler, descriptorImageInfo, nullptr, nullptr));

View File

@ -91,10 +91,22 @@ namespace vk
}
template <class T>
void copyToDevice(vk::UniqueDevice &device, vk::UniqueDeviceMemory &memory, T const* pData, size_t count)
void copyToDevice(vk::UniqueDevice &device, vk::UniqueDeviceMemory &memory, T const* pData, size_t count, size_t stride = sizeof(T))
{
uint8_t* deviceData = static_cast<uint8_t*>(device->mapMemory(memory.get(), 0, count * sizeof(T)));
memcpy(deviceData, pData, count * sizeof(T));
assert(sizeof(T) <= stride);
uint8_t* deviceData = static_cast<uint8_t*>(device->mapMemory(memory.get(), 0, count * stride));
if (stride == sizeof(T))
{
memcpy(deviceData, pData, count * sizeof(T));
}
else
{
for (size_t i = 0; i < count; i++)
{
memcpy(deviceData, &pData[i], sizeof(T));
deviceData += stride;
}
}
device->unmapMemory(memory.get());
}
@ -113,8 +125,8 @@ namespace vk
vk::UniqueDeviceMemory allocateMemory(vk::UniqueDevice &device, vk::PhysicalDeviceMemoryProperties const& memoryProperties, vk::MemoryRequirements const& memoryRequirements, vk::MemoryPropertyFlags memoryPropertyFlags);
vk::UniqueCommandPool createCommandPool(vk::UniqueDevice &device, uint32_t queueFamilyIndex);
vk::UniqueDebugReportCallbackEXT createDebugReportCallback(vk::UniqueInstance &instance);
vk::UniqueDescriptorPool createDescriptorPool(vk::UniqueDevice &device, bool textured = false);
vk::UniqueDescriptorSetLayout createDescriptorSetLayout(vk::UniqueDevice &device, bool textured = false);
vk::UniqueDescriptorPool createDescriptorPool(vk::UniqueDevice &device, vk::DescriptorType descriptorType = vk::DescriptorType::eUniformBuffer, bool textured = false);
vk::UniqueDescriptorSetLayout createDescriptorSetLayout(vk::UniqueDevice &device, vk::DescriptorType = vk::DescriptorType::eUniformBuffer, bool textured = false);
vk::UniqueDevice createDevice(vk::PhysicalDevice physicalDevice, uint32_t queueFamilyIndex, std::vector<std::string> const& extensions = {});
std::vector<vk::UniqueFramebuffer> createFramebuffers(vk::UniqueDevice &device, vk::UniqueRenderPass &renderPass, std::vector<vk::UniqueImageView> const& imageViews, vk::UniqueImageView &depthImageView, vk::Extent2D const& extent);
vk::UniquePipeline createGraphicsPipeline(vk::UniqueDevice &device, vk::UniquePipelineCache &pipelineCache, vk::UniqueShaderModule &vertexShaderModule, vk::UniqueShaderModule &fragmentShaderModule, uint32_t vertexStride, vk::UniquePipelineLayout &pipelineLayout, vk::UniqueRenderPass &renderPass);
@ -129,7 +141,7 @@ namespace vk
vk::Format pickColorFormat(std::vector<vk::SurfaceFormatKHR> const& formats);
void setImageLayout(vk::UniqueCommandBuffer &commandBuffer, vk::Image image, vk::ImageAspectFlags aspectFlags, vk::ImageLayout oldImageLayout, vk::ImageLayout newImageLayout, vk::PipelineStageFlags sourceStageMask, vk::PipelineStageFlags destinationStageMask);
void submitAndWait(vk::UniqueDevice &device, vk::Queue queue, vk::UniqueCommandBuffer &commandBuffer);
void updateDescriptorSets(vk::UniqueDevice &device, vk::UniqueDescriptorSet &descriptorSet, vk::DescriptorBufferInfo const* descriptorBufferInfo, vk::DescriptorImageInfo const* descriptorImageInfo = nullptr);
void updateDescriptorSets(vk::UniqueDevice &device, vk::UniqueDescriptorSet &descriptorSet, vk::DescriptorType descriptorType, vk::DescriptorBufferInfo const* descriptorBufferInfo, vk::DescriptorImageInfo const* descriptorImageInfo = nullptr);
#if defined(VK_USE_PLATFORM_WIN32_KHR)
HWND initializeWindow(std::string const& className, std::string const& windowName, LONG width, LONG height);