Merge with upstream master

This commit is contained in:
Bill Hollings 2017-06-05 17:04:14 -04:00
commit 338d38ea9a
123 changed files with 4315 additions and 398592 deletions

View file

@ -23,9 +23,9 @@ namespace vks
*/
struct Buffer
{
VkBuffer buffer;
VkDevice device;
VkDeviceMemory memory;
VkBuffer buffer = VK_NULL_HANDLE;
VkDeviceMemory memory = VK_NULL_HANDLE;
VkDescriptorBufferInfo descriptor;
VkDeviceSize size = 0;
VkDeviceSize alignment = 0;

View file

@ -124,7 +124,7 @@ public:
#endif
)
{
VkResult err;
VkResult err = VK_SUCCESS;
// Create the os-specific surface
#ifdef _WIN32
@ -178,6 +178,10 @@ public:
#endif
#endif
if (err != VK_SUCCESS) {
vks::tools::exitFatal("Could not create surface!", "Fatal error");
}
// Get available queue family properties
uint32_t queueCount;
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueCount, NULL);
@ -246,13 +250,11 @@ public:
// Get list of supported surface formats
uint32_t formatCount;
err = fpGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &formatCount, NULL);
assert(!err);
VK_CHECK_RESULT(fpGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &formatCount, NULL));
assert(formatCount > 0);
std::vector<VkSurfaceFormatKHR> surfaceFormats(formatCount);
err = fpGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &formatCount, surfaceFormats.data());
assert(!err);
VK_CHECK_RESULT(fpGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &formatCount, surfaceFormats.data()));
// If the surface format list only includes one entry with VK_FORMAT_UNDEFINED,
// there is no preferered format, so we assume VK_FORMAT_B8G8R8A8_UNORM
@ -321,24 +323,19 @@ public:
*/
void create(uint32_t *width, uint32_t *height, bool vsync = false)
{
VkResult err;
VkSwapchainKHR oldSwapchain = swapChain;
// Get physical device surface properties and formats
VkSurfaceCapabilitiesKHR surfCaps;
err = fpGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, &surfCaps);
assert(!err);
VK_CHECK_RESULT(fpGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, &surfCaps));
// Get available present modes
uint32_t presentModeCount;
err = fpGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &presentModeCount, NULL);
assert(!err);
VK_CHECK_RESULT(fpGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &presentModeCount, NULL));
assert(presentModeCount > 0);
std::vector<VkPresentModeKHR> presentModes(presentModeCount);
err = fpGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &presentModeCount, presentModes.data());
assert(!err);
VK_CHECK_RESULT(fpGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &presentModeCount, presentModes.data()));
VkExtent2D swapchainExtent = {};
// If width (and height) equals the special value 0xFFFFFFFF, the size of the surface will be set by the swapchain
@ -444,8 +441,7 @@ public:
swapchainCI.imageUsage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
}
err = fpCreateSwapchainKHR(device, &swapchainCI, nullptr, &swapChain);
assert(!err);
VK_CHECK_RESULT(fpCreateSwapchainKHR(device, &swapchainCI, nullptr, &swapChain));
// If an existing swap chain is re-created, destroy the old swap chain
// This also cleans up all the presentable images
@ -457,14 +453,11 @@ public:
}
fpDestroySwapchainKHR(device, oldSwapchain, nullptr);
}
err = fpGetSwapchainImagesKHR(device, swapChain, &imageCount, NULL);
assert(!err);
VK_CHECK_RESULT(fpGetSwapchainImagesKHR(device, swapChain, &imageCount, NULL));
// Get the swap chain images
images.resize(imageCount);
err = fpGetSwapchainImagesKHR(device, swapChain, &imageCount, images.data());
assert(!err);
VK_CHECK_RESULT(fpGetSwapchainImagesKHR(device, swapChain, &imageCount, images.data()));
// Get the swap chain buffers containing the image and imageview
buffers.resize(imageCount);
@ -492,8 +485,7 @@ public:
colorAttachmentView.image = buffers[i].image;
err = vkCreateImageView(device, &colorAttachmentView, nullptr, &buffers[i].view);
assert(!err);
VK_CHECK_RESULT(vkCreateImageView(device, &colorAttachmentView, nullptr, &buffers[i].view));
}
}

View file

@ -312,6 +312,7 @@ public:
samplerInfo.minLod = 0.0f;
samplerInfo.maxLod = 1.0f;
samplerInfo.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
samplerInfo.maxAnisotropy = 1.0f;
VK_CHECK_RESULT(vkCreateSampler(vulkanDevice->logicalDevice, &samplerInfo, nullptr, &sampler));
// Descriptor
@ -665,7 +666,7 @@ public:
renderPassBeginInfo.clearValueCount = 0;
renderPassBeginInfo.pClearValues = nullptr;
for (int32_t i = 0; i < cmdBuffers.size(); ++i)
for (size_t i = 0; i < cmdBuffers.size(); ++i)
{
renderPassBeginInfo.framebuffer = *frameBuffers[i];

View file

@ -104,6 +104,9 @@ namespace vks
free(textureData);
#else
if (!vks::tools::fileExists(filename)) {
vks::tools::exitFatal("Could not load texture from " + filename, "File not found");
}
gli::texture2d tex2D(gli::load(filename.c_str()));
#endif
assert(!tex2D.empty());
@ -219,7 +222,6 @@ namespace vks
vks::tools::setImageLayout(
copyCmd,
image,
VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
subresourceRange);
@ -239,7 +241,6 @@ namespace vks
vks::tools::setImageLayout(
copyCmd,
image,
VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
imageLayout,
subresourceRange);
@ -480,7 +481,6 @@ namespace vks
vks::tools::setImageLayout(
copyCmd,
image,
VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
subresourceRange);
@ -500,7 +500,6 @@ namespace vks
vks::tools::setImageLayout(
copyCmd,
image,
VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
imageLayout,
subresourceRange);
@ -524,6 +523,7 @@ namespace vks
samplerCreateInfo.compareOp = VK_COMPARE_OP_NEVER;
samplerCreateInfo.minLod = 0.0f;
samplerCreateInfo.maxLod = 0.0f;
samplerCreateInfo.maxAnisotropy = 1.0f;
VK_CHECK_RESULT(vkCreateSampler(device->logicalDevice, &samplerCreateInfo, nullptr, &sampler));
// Create image view
@ -582,9 +582,11 @@ namespace vks
free(textureData);
#else
if (!vks::tools::fileExists(filename)) {
vks::tools::exitFatal("Could not load texture from " + filename, "File not found");
}
gli::texture2d_array tex2DArray(gli::load(filename));
#endif
assert(!tex2DArray.empty());
this->device = device;
@ -691,7 +693,6 @@ namespace vks
vks::tools::setImageLayout(
copyCmd,
image,
VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
subresourceRange);
@ -710,7 +711,6 @@ namespace vks
vks::tools::setImageLayout(
copyCmd,
image,
VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
imageLayout,
subresourceRange);
@ -791,6 +791,9 @@ namespace vks
free(textureData);
#else
if (!vks::tools::fileExists(filename)) {
vks::tools::exitFatal("Could not load texture from " + filename, "File not found");
}
gli::texture_cube texCube(gli::load(filename));
#endif
assert(!texCube.empty());
@ -902,7 +905,6 @@ namespace vks
vks::tools::setImageLayout(
copyCmd,
image,
VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
subresourceRange);
@ -921,7 +923,6 @@ namespace vks
vks::tools::setImageLayout(
copyCmd,
image,
VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
imageLayout,
subresourceRange);

View file

@ -94,7 +94,6 @@ namespace vks
void setImageLayout(
VkCommandBuffer cmdbuffer,
VkImage image,
VkImageAspectFlags aspectMask,
VkImageLayout oldImageLayout,
VkImageLayout newImageLayout,
VkImageSubresourceRange subresourceRange,
@ -156,6 +155,9 @@ namespace vks
// Make sure any shader reads from the image have been finished
imageMemoryBarrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
break;
default:
// Other source layouts aren't handled (yet)
break;
}
// Target layouts (new)
@ -170,15 +172,13 @@ namespace vks
case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
// Image will be used as a transfer source
// Make sure any reads from and writes to the image have been finished
imageMemoryBarrier.srcAccessMask = imageMemoryBarrier.srcAccessMask | VK_ACCESS_TRANSFER_READ_BIT;
// Make sure any reads from the image have been finished
imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
break;
case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
// Image will be used as a color attachment
// Make sure any writes to the color buffer have been finished
imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
break;
@ -197,6 +197,9 @@ namespace vks
}
imageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
break;
default:
// Other source layouts aren't handled (yet)
break;
}
// Put barrier inside setup command buffer
@ -225,7 +228,7 @@ namespace vks
subresourceRange.baseMipLevel = 0;
subresourceRange.levelCount = 1;
subresourceRange.layerCount = 1;
setImageLayout(cmdbuffer, image, aspectMask, oldImageLayout, newImageLayout, subresourceRange);
setImageLayout(cmdbuffer, image, oldImageLayout, newImageLayout, subresourceRange, srcStageMask, dstStageMask);
}
void insertImageMemoryBarrier(
@ -289,7 +292,7 @@ namespace vks
#if defined(__ANDROID__)
// Android shaders are stored as assets in the apk
// So they need to be loaded via the asset manager
VkShaderModule loadShader(AAssetManager* assetManager, const char *fileName, VkDevice device, VkShaderStageFlagBits stage)
VkShaderModule loadShader(AAssetManager* assetManager, const char *fileName, VkDevice device)
{
// Load shader from compressed asset
AAsset* asset = AAssetManager_open(assetManager, fileName, AASSET_MODE_STREAMING);
@ -316,7 +319,7 @@ namespace vks
return shaderModule;
}
#else
VkShaderModule loadShader(const char *fileName, VkDevice device, VkShaderStageFlagBits stage)
VkShaderModule loadShader(const char *fileName, VkDevice device)
{
std::ifstream is(fileName, std::ios::binary | std::ios::in | std::ios::ate);
@ -375,5 +378,11 @@ namespace vks
return shaderModule;
}
bool fileExists(const std::string &filename)
{
std::ifstream f(filename.c_str());
return !f.fail();
}
}
}

View file

@ -21,6 +21,7 @@
#include <vector>
#include <iostream>
#include <stdexcept>
#include <fstream>
#if defined(_WIN32)
#include <windows.h>
#include <fcntl.h>
@ -82,7 +83,6 @@ namespace vks
void setImageLayout(
VkCommandBuffer cmdbuffer,
VkImage image,
VkImageAspectFlags aspectMask,
VkImageLayout oldImageLayout,
VkImageLayout newImageLayout,
VkImageSubresourceRange subresourceRange,
@ -115,13 +115,16 @@ namespace vks
// Load a SPIR-V shader (binary)
#if defined(__ANDROID__)
VkShaderModule loadShader(AAssetManager* assetManager, const char *fileName, VkDevice device, VkShaderStageFlagBits stage);
VkShaderModule loadShader(AAssetManager* assetManager, const char *fileName, VkDevice device);
#else
VkShaderModule loadShader(const char *fileName, VkDevice device, VkShaderStageFlagBits stage);
VkShaderModule loadShader(const char *fileName, VkDevice device);
#endif
// Load a GLSL shader (text)
// Note: GLSL support requires vendor-specific extensions to be enabled and is not a core-feature of Vulkan
VkShaderModule loadShaderGLSL(const char *fileName, VkDevice device, VkShaderStageFlagBits stage);
/** @brief Checks if a file exists */
bool fileExists(const std::string &filename);
}
}

View file

@ -203,9 +203,9 @@ VkPipelineShaderStageCreateInfo VulkanExampleBase::loadShader(std::string fileNa
shaderStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
shaderStage.stage = stage;
#if defined(__ANDROID__)
shaderStage.module = vks::tools::loadShader(androidApp->activity->assetManager, fileName.c_str(), device, stage);
shaderStage.module = vks::tools::loadShader(androidApp->activity->assetManager, fileName.c_str(), device);
#else
shaderStage.module = vks::tools::loadShader(fileName.c_str(), device, stage);
shaderStage.module = vks::tools::loadShader(fileName.c_str(), device);
#endif
shaderStage.pName = "main"; // todo : make param
assert(shaderStage.module != VK_NULL_HANDLE);
@ -587,15 +587,19 @@ void VulkanExampleBase::updateTextOverlay()
textOverlay->endTextUpdate();
}
void VulkanExampleBase::getOverlayText(VulkanTextOverlay *textOverlay)
{
// Can be overriden in derived class
}
void VulkanExampleBase::getOverlayText(VulkanTextOverlay*) {}
void VulkanExampleBase::prepareFrame()
{
// Acquire the next image from the swap chaing
VK_CHECK_RESULT(swapChain.acquireNextImage(semaphores.presentComplete, &currentBuffer));
// Acquire the next image from the swap chain
VkResult err = swapChain.acquireNextImage(semaphores.presentComplete, &currentBuffer);
// Recreate the swapchain if it's no longer compatible with the surface (OUT_OF_DATE) or no longer optimal for presentation (SUBOPTIMAL)
if ((err == VK_ERROR_OUT_OF_DATE_KHR) || (err == VK_SUBOPTIMAL_KHR)) {
windowResize();
}
else {
VK_CHECK_RESULT(err);
}
}
void VulkanExampleBase::submitFrame()
@ -989,7 +993,7 @@ HWND VulkanExampleBase::setupWindow(HINSTANCE hinstance, WNDPROC wndproc)
dmScreenSettings.dmBitsPerPel = 32;
dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
if ((width != screenWidth) && (height != screenHeight))
if ((width != (uint32_t)screenWidth) && (height != (uint32_t)screenHeight))
{
if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
{
@ -999,7 +1003,7 @@ HWND VulkanExampleBase::setupWindow(HINSTANCE hinstance, WNDPROC wndproc)
}
else
{
return false;
return nullptr;
}
}
}
@ -1054,7 +1058,7 @@ HWND VulkanExampleBase::setupWindow(HINSTANCE hinstance, WNDPROC wndproc)
{
printf("Could not create window!\n");
fflush(stdout);
return 0;
return nullptr;
exit(1);
}
@ -1905,20 +1909,11 @@ void VulkanExampleBase::handleEvent(const xcb_generic_event_t *event)
}
#endif
void VulkanExampleBase::viewChanged()
{
// Can be overrdiden in derived class
}
void VulkanExampleBase::viewChanged() {}
void VulkanExampleBase::keyPressed(uint32_t keyCode)
{
// Can be overriden in derived class
}
void VulkanExampleBase::keyPressed(uint32_t) {}
void VulkanExampleBase::buildCommandBuffers()
{
// Can be overriden in derived class
}
void VulkanExampleBase::buildCommandBuffers() {}
void VulkanExampleBase::createCommandPool()
{

View file

@ -21,6 +21,8 @@
#include "VulkanAndroid.h"
#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
#include <wayland-client.h>
#elif defined(_DIRECT2DISPLAY)
//
#elif defined(__linux__)
#include <xcb/xcb.h>
#endif
@ -225,6 +227,8 @@ public:
bool right = false;
bool middle = false;
} mouseButtons;
#elif defined(_DIRECT2DISPLAY)
bool quit = false;
#elif defined(__linux__)
struct {
bool left = false;
@ -242,7 +246,7 @@ public:
VulkanExampleBase(bool enableValidation);
// dtor
~VulkanExampleBase();
virtual ~VulkanExampleBase();
// Setup the vulkan instance, enable required extensions and connect to the physical device (GPU)
void initVulkan();
@ -297,6 +301,9 @@ public:
static void keyboardModifiersCb(void *data, struct wl_keyboard *keyboard,
uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched,
uint32_t mods_locked, uint32_t group);
#elif defined(_DIRECT2DISPLAY)
//
#elif defined(__linux__)
xcb_window_t setupWindow();
void initxcbConnection();
@ -316,8 +323,8 @@ public:
// Containing view dependant matrices
virtual void viewChanged();
// Called if a key is pressed
// Can be overriden in derived class to do custom key handling
virtual void keyPressed(uint32_t keyCode);
/** @brief (Virtual) Called after a key was pressed, can be used to do custom key handling */
virtual void keyPressed(uint32_t);
// Called when the window has been resized
// Can be overriden in derived class to recreate or rebuild resources attached to the frame buffer / swapchain
virtual void windowResized();
@ -337,7 +344,7 @@ public:
// Can be overriden in derived class to setup a custom render pass (e.g. for MSAA)
virtual void setupRenderPass();
/** @brief (Virtual) called after the physical device features have been read, used to set features to enable on the device */
/** @brief (Virtual) Called after the physical device features have been read, can be used to set features to enable on the device */
virtual void getEnabledFeatures();
// Connect and prepare the swap chain
@ -377,9 +384,8 @@ public:
void updateTextOverlay();
// Called when the text overlay is updating
// Can be overriden in derived class to add custom text to the overlay
virtual void getOverlayText(VulkanTextOverlay * textOverlay);
/** @brief (Virtual) Called when the text overlay is updating, can be used to add custom text to the overlay */
virtual void getOverlayText(VulkanTextOverlay*);
// Prepare the frame for workload submission
// - Acquires the next image from the swap chain
@ -405,9 +411,9 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
} \
return (DefWindowProc(hWnd, uMsg, wParam, lParam)); \
} \
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, int nCmdShow) \
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int) \
{ \
for (size_t i = 0; i < __argc; i++) { VulkanExample::args.push_back(__argv[i]); }; \
for (int32_t i = 0; i < __argc; i++) { VulkanExample::args.push_back(__argv[i]); }; \
vulkanExample = new VulkanExample(); \
vulkanExample->initVulkan(); \
vulkanExample->setupWindow(hInstance, WndProc); \