Start of compute example

This commit is contained in:
Darren VanBuren 2019-10-16 14:02:00 -07:00
parent 0bf1dd95e9
commit 9afaf34349
3 changed files with 187 additions and 3 deletions

View file

@ -1,15 +1,18 @@
CFLAGS = -std=c++11
LDFLAGS = -L/usr/local/lib -lglfw -lrt -lm -ldl -lXrandr -lXinerama -lXxf86vm -lXext -lXcursor -lXrender -lXfixes -lX11 -lpthread -lxcb -lXau -lvulkan
all: VulkanTest
all: VulkanTest VulkanComputeTest
VulkanTest: main.cpp
g++ $(CFLAGS) -g -o VulkanTest main.cpp $(LDFLAGS)
VulkanComputeTest: compute.cpp
clang++ $(CFLAGS) -g -o VulkanComputeTest compute.cpp -lvulkan
.PHONY: test clean
test: VulkanTest
LD_LIBRARY_PATH=$(VULKAN_SDK_PATH)/lib VK_LAYER_PATH=$(VULKAN_SDK_PATH)/etc/explicit_layer.d ./VulkanTest
clean:
rm -f VulkanTest
rm -f VulkanTest VulkanComputeTest

181
compute.cpp Normal file
View file

@ -0,0 +1,181 @@
#include <iostream>
#include <vector>
#include <vulkan/vulkan.hpp>
const std::vector<const char*> validationLayers = {
"VK_LAYER_LUNARG_standard_validation"
};
#ifdef NDEBUG
const bool enableValidationLayers = false;
#else
const bool enableValidationLayers = true;
#endif
// Wrappers for extension functions that must be located using vkGetInstanceProcAddr
VkResult CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo,
const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback) {
auto func = (PFN_vkCreateDebugReportCallbackEXT) vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT");
if(func != nullptr) {
return func(instance, pCreateInfo, pAllocator, pCallback);
} else {
return VK_ERROR_EXTENSION_NOT_PRESENT;
}
}
void DestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT callback, const VkAllocationCallbacks* pAllocator) {
auto func = (PFN_vkDestroyDebugReportCallbackEXT) vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT");
if(func != nullptr) {
func(instance, callback, pAllocator);
}
}
class HelloVkCompute
{
private:
/* data */
VkInstance instance;
VkDebugReportCallbackEXT callback;
VkPhysicalDevice physicalDevice;
// Check if the validation layers are supported.
bool checkValidationLayerSupport() {
uint32_t layerCount;
vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
std::vector<VkLayerProperties> availableLayers(layerCount);
vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data());
for(const char* layerName : validationLayers) {
bool layerFound = false;
for(const auto& layerProperties : availableLayers) {
if(strcmp(layerName, layerProperties.layerName) == 0) {
layerFound = true;
break;
}
}
if(!layerFound) {
return false;
}
}
return true;
}
// Set up our debug report callback to get information back from the validation layers.
void setupDebugCallback() {
if (!enableValidationLayers) return;
VkDebugReportCallbackCreateInfoEXT createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
createInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT;
createInfo.pfnCallback = debugCallback;
if(CreateDebugReportCallbackEXT(instance, &createInfo, nullptr, &callback) != VK_SUCCESS) {
throw std::runtime_error("failed to setup debug callback!");
}
}
void cleanupDebugCallback() {
if (!enableValidationLayers) return;
DestroyDebugReportCallbackEXT(instance, callback, nullptr);
}
void initVulkan() {
if(enableValidationLayers && !checkValidationLayerSupport()) {
throw std::runtime_error("validation layers requested, but not supported");
}
// Create VkApplicationInfo
VkApplicationInfo appInfo = {};
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
appInfo.pApplicationName = "Hello Vk Compute";
appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
appInfo.pEngineName = "No Engine";
appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
appInfo.apiVersion = VK_API_VERSION_1_0;
// Create VkInstanceCreateInfo and have it point to VkApplicationInfo
VkInstanceCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
createInfo.pApplicationInfo = &appInfo;
// Enable the validation layers if they are requested
if(enableValidationLayers) {
createInfo.enabledLayerCount = validationLayers.size();
createInfo.ppEnabledLayerNames = validationLayers.data();
} else {
createInfo.enabledLayerCount = 0;
}
if(vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS) {
throw std::runtime_error("failed to create Vulkan instance!");
}
uint32_t extensionCount = 0;
vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);
std::vector<VkExtensionProperties> extensions(extensionCount);
vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensions.data());
std::cout << "available extensions:" << std::endl;
for(const auto& extension : extensions) {
std::cout << "\t" << extension.extensionName << std::endl;
}
}
void pickDevice() {
uint32_t deviceCount = 0;
vkEnumeratePhysicalDevices(instance, &deviceCount, nullptr);
if(deviceCount == 0) {
throw std::runtime_error("Failed to find a device with Vulkan support!");
}
std::vector<VkPhysicalDevice> devices(deviceCount);
vkEnumeratePhysicalDevices(instance, &deviceCount, devices.data());
for(const auto& device : devices) {
if(isDeviceSuitable(device)) {
physicalDevice = device;
break;
}
}
if(physicalDevice == VK_NULL_HANDLE) {
throw std::runtime_error("Failed to find a suitable device!");
}
}
public:
// our debug callback function, just prints the message from the Validation layer to stderr
static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback( VkDebugReportFlagsEXT flags,
VkDebugReportObjectTypeEXT objType, uint64_t obj, size_t location, int32_t code,
const char* layerPrefix, const char* msg, void* userData) {
std::cerr << "[Validation Layer]: " << msg << std::endl;
return VK_FALSE;
}
void run() {
initVulkan();
pickDevice();
}
};
int main() {
HelloVkCompute app;
try {
app.run();
} catch (const std::runtime_error& e) {
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}

View file

@ -198,7 +198,7 @@ private:
vkDestroyInstance(instance, nullptr);
}
// Check if the validation layers are supported.s
// Check if the validation layers are supported.
bool checkValidationLayerSupport() {
uint32_t layerCount;
vkEnumerateInstanceLayerProperties(&layerCount, nullptr);