Hello,
I´m from Germany, so I can´t speak (and write) English very well. But my triangle code is crashing. It compiles but when I minimize the app-window every frame this error is coming:
UNASSIGNED-CoreValidation-DrawState-QueueForwardProgress(ERROR / SPEC): msgNum: 0 - VkQueue 0x64b37c8[] is waiting on VkNonDispatchableHandle 0xc84d0a000000000f[] that has no way to be signaled.
Objects: 1
[0] 0xf, type: 5, name: NULL
Here is my code:
#define GLFW_INCLUDE_VULKAN
#include "stdafx.h"
#include <GLFW\glfw3.h>
#include <vector>
#include <fstream>
//______________________________Folge7_______________________________________________
#define ASSERT_VULKAN(val)\
if (val != VK_SUCCESS)\
{\
__debugbreak();\
}
std::vector<char> readFile(const std::string & fileName);
void createShaderModule(const std::vector<char> & shaderCode, VkShaderModule * shaderModule);
void drawFrame();
void recreateSwapchain();
void windowOnResized(GLFWwindow * window, int width, int height);
void startGlfw();
void startVulkan();
void createInstance(VkApplicationInfo appInfo);
void printInstanceLayers();
void printInstanceExtensions();
void createGlfwWindowSurface();
void printPhysicalDeviceStats();
void createLogicalDevcie();
void createQueue();
void checkSurfaceSupport();
void createSwapchain();
void createImageViews();
void createRenderPass();
void createGraphicsPipeline();
void createFramebuffers();
void createCommandPool();
void createCommandBuffers();
void recordCommandBuffers();
void createSemaphores();
void gameLoop();
void shutdownVulkan();
void shutdownGlfw();
void printStats(VkPhysicalDevice& device);
VkInstance instance;
std::vector<VkPhysicalDevice> physicalDevices;
VkDevice device;
VkQueue queue;
VkSurfaceKHR surface;
VkPhysicalDeviceFeatures features = {};
VkResult result;
VkSwapchainKHR swapchain = VK_NULL_HANDLE;
VkImageView* imageViews;
VkFramebuffer* framebuffers;
uint32_t ammountOfSwapchainImages = 0;
VkPipelineLayout pipelineLayout;
VkRenderPass renderPass;
VkPipeline pipeline;
VkCommandPool commandPool;
VkCommandBuffer* commandBuffers;
VkSemaphore semaphoreImageAvilable;
VkSemaphore semaphoreRenderingDone;
VkShaderModule shaderModuleVert;
VkShaderModule shaderModuleFrag;
GLFWwindow* window;
uint32_t windowWidth = 400;
uint32_t windowHeight = 300;
const VkFormat FORMAT = VK_FORMAT_B8G8R8A8_UNORM;
int main()
{
//______________________________Folge22______________________________________________
startGlfw();
startVulkan();
gameLoop();
shutdownVulkan();
shutdownGlfw();
return 0;
}
//______________________________Folge36__________________________________________________
std::vector<char> readFile(const std::string& filename)
{
std::ifstream file(filename, std::ios::binary | std::ios::ate);
if (file)
{
size_t fileSize = static_cast<size_t>( file.tellg() );
std::vector<char> fileBuffer(fileSize);
file.seekg(0);
file.read(fileBuffer.data(), fileSize);
file.close();
return fileBuffer;
}
else
{
throw std::runtime_error("File opening failed!");
}
}
//______________________________Folge38__________________________________________________
void createShaderModule(const std::vector<char>& shaderCode, VkShaderModule* shaderModule)
{
//______________________________Folge37______________________________________________
VkShaderModuleCreateInfo shaderModuleCreateInfo;
shaderModuleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
shaderModuleCreateInfo.pNext = nullptr;
shaderModuleCreateInfo.flags = 0;
shaderModuleCreateInfo.codeSize = shaderCode.size();
shaderModuleCreateInfo.pCode = (uint32_t*)shaderCode.data();
//______________________________Folge38________________________________________________
result = vkCreateShaderModule(device, &shaderModuleCreateInfo, nullptr, shaderModule);
ASSERT_VULKAN(result);
}
//______________________________Folge70____________________________________________________
void drawFrame()
{
//______________________________Folge72________________________________________________
uint32_t imageIndex = 0;
vkAcquireNextImageKHR(device, swapchain, std::numeric_limits<uint32_t>::max(), semaphoreImageAvilable, VK_NULL_HANDLE, &imageIndex);
//______________________________Folge73________________________________________________
VkSubmitInfo submitInfo;
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo.pNext = nullptr;
submitInfo.waitSemaphoreCount = 1;
submitInfo.pWaitSemaphores = &semaphoreImageAvilable;
VkPipelineStageFlags waitStageMask[] =
{
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
};
submitInfo.pWaitDstStageMask = waitStageMask;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &(commandBuffers[imageIndex]);
submitInfo.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = &semaphoreRenderingDone;
//______________________________Folge74________________________________________________
result = vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE);
ASSERT_VULKAN(result);
//______________________________Folge76________________________________________________
VkPresentInfoKHR presentInfo;
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
presentInfo.pNext = nullptr;
presentInfo.waitSemaphoreCount = 1;
presentInfo.pWaitSemaphores = &semaphoreRenderingDone;
presentInfo.swapchainCount = 1;
presentInfo.pSwapchains = &swapchain;
presentInfo.pImageIndices = &imageIndex;
presentInfo.pResults = nullptr;
//______________________________Folge77________________________________________________
result = vkQueuePresentKHR(queue, &presentInfo);
//ASSERT_VULKAN(result);
}
void recreateSwapchain()
{
//______________________________Folge82________________________________________________
vkDeviceWaitIdle(device);
//______________________________Folge63______________________________________________
vkFreeCommandBuffers(device, commandPool, ammountOfSwapchainImages, commandBuffers);
delete[] commandBuffers;
//______________________________Folge61______________________________________________
vkDestroyCommandPool(device, commandPool, nullptr);
//______________________________Folge59______________________________________________
for (size_t i = 0; i < ammountOfSwapchainImages; i++)
{
vkDestroyFramebuffer(device, framebuffers[i], nullptr);
}
delete[] framebuffers;
//______________________________Folge57______________________________________________
vkDestroyPipeline(device, pipeline, nullptr);
//______________________________Folge55______________________________________________
vkDestroyRenderPass(device, renderPass, nullptr);
//______________________________Folge31______________________________________________
for (int i = 0; i < ammountOfSwapchainImages; i++)
{
vkDestroyImageView(device, imageViews[i], nullptr);
}
delete[] imageViews;
//______________________________Folge50______________________________________________
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
//______________________________Folge38______________________________________________
vkDestroyShaderModule(device, shaderModuleVert, nullptr);
vkDestroyShaderModule(device, shaderModuleFrag, nullptr);
//______________________________Folge82______________________________________________
VkSwapchainKHR oldSwapchain = swapchain;
createSwapchain();
createImageViews();
createRenderPass();
createGraphicsPipeline();
createFramebuffers();
createCommandPool();
createCommandBuffers();
recordCommandBuffers();
//______________________________Folge28______________________________________________
vkDestroySwapchainKHR(device, oldSwapchain, nullptr);
}
//______________________________Folge82_________________________________________________
void windowOnResized(GLFWwindow* window, int width, int height)
{
if (width == 0 || height == 0) return;
windowWidth = width;
windowHeight = height;
VkSurfaceCapabilitiesKHR surfaceCapabilities;
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevices[0], surface, &surfaceCapabilities);
recreateSwapchain();
}
void startGlfw()
{
//______________________________Folg22________________________________________________
glfwInit();
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
//glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
window = glfwCreateWindow(windowWidth, windowHeight, "Vulkan tutorial", nullptr, nullptr);
//______________________________Folg82________________________________________________
glfwSetWindowSizeCallback(window, windowOnResized);
}
//______________________________Folg81_____________________________________________________
std::vector<VkPhysicalDevice> getAllPhysicalDevices()
{
//______________________________Folge8_______________________________________________
uint32_t ammountOfPhysicalDevices = 0;
result = vkEnumeratePhysicalDevices(instance, &ammountOfPhysicalDevices, nullptr);
ASSERT_VULKAN(result);
std::vector<VkPhysicalDevice> physicalDevices = {};
physicalDevices.resize(ammountOfPhysicalDevices);
result = vkEnumeratePhysicalDevices(instance, &ammountOfPhysicalDevices, physicalDevices.data());
ASSERT_VULKAN(result);
//______________________________Folg81_______________________________________________
return physicalDevices;
}
void startVulkan()
{
//______________________________Folge4_______________________________________________
VkApplicationInfo appInfo;
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
appInfo.pNext = nullptr;
appInfo.pApplicationName = "Vulkan test";
appInfo.applicationVersion = VK_MAKE_VERSION(0, 0, 0);
appInfo.pEngineName = "Purple Engine test";
appInfo.engineVersion = VK_MAKE_VERSION(0, 0, 0);
appInfo.apiVersion = VK_API_VERSION_1_0;
//______________________________Folge81______________________________________________
createInstance(appInfo);
physicalDevices = getAllPhysicalDevices();
printInstanceLayers();
printInstanceExtensions();
createGlfwWindowSurface();
printPhysicalDeviceStats();
createLogicalDevcie();
createQueue();
checkSurfaceSupport();
createSwapchain();
createImageViews();
createRenderPass();
createGraphicsPipeline();
createFramebuffers();
createCommandPool();
createCommandBuffers();
recordCommandBuffers();
createSemaphores();
}
//______________________________Folge81___________________________________________________
void createInstance(VkApplicationInfo appInfo)
{
//______________________________Folge16______________________________________________
const std::vector<const char*> validationLayers =
{
"VK_LAYER_LUNARG_standard_validation"
};
//______________________________Folge23______________________________________________
uint32_t ammountOfGlfwExtensions = 0;
auto glfwExtensions = glfwGetRequiredInstanceExtensions(&ammountOfGlfwExtensions);
//______________________________Folge5_______________________________________________
VkInstanceCreateInfo instanceInfo;
instanceInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
instanceInfo.pNext = nullptr;
instanceInfo.flags = 0;
instanceInfo.pApplicationInfo = &appInfo;
instanceInfo.enabledLayerCount = validationLayers.size();
instanceInfo.ppEnabledLayerNames = validationLayers.data();
instanceInfo.enabledExtensionCount = ammountOfGlfwExtensions;
instanceInfo.ppEnabledExtensionNames = glfwExtensions;
//______________________________Folge6_______________________________________________
result = vkCreateInstance(&instanceInfo, nullptr, &instance);
ASSERT_VULKAN(result);
}
//______________________________Folge81__________________________________________________
void printInstanceLayers()
{
//______________________________Folge16______________________________________________
uint32_t ammountOfLayers = 0;
result = vkEnumerateInstanceLayerProperties(&ammountOfLayers, nullptr);
ASSERT_VULKAN(result);
VkLayerProperties* layers = new VkLayerProperties[ammountOfLayers];
result = vkEnumerateInstanceLayerProperties(&ammountOfLayers, layers);
ASSERT_VULKAN(result);
std::cout << "Ammount of Layers: " << ammountOfLayers << std::endl;
for (int i = 0; i < ammountOfLayers; i++)
{
std::cout << "Name: " << layers[i].layerName << std::endl;
std::cout << "Spec Version: " << layers[i].specVersion << std::endl;
std::cout << "Implement Version: " << layers[i].implementationVersion << std::endl;
std::cout << "Description: " << layers[i].description << std::endl;
std::cout << std::endl;
}
//______________________________Folge19______________________________________________
delete[] layers;
}
//______________________________Folge81__________________________________________________
void printInstanceExtensions()
{
//______________________________Folge17______________________________________________
uint32_t ammountOfExtensions = 0;
result = vkEnumerateInstanceExtensionProperties(nullptr, &ammountOfExtensions, nullptr);
ASSERT_VULKAN(result);
VkExtensionProperties* extensions = new VkExtensionProperties[ammountOfExtensions];
result = vkEnumerateInstanceExtensionProperties(nullptr, &ammountOfExtensions, extensions);
ASSERT_VULKAN(result);
std::cout << std::endl;
std::cout << "Ammount of Extensions: " << ammountOfExtensions << std::endl;
for (int i = 0; i < ammountOfExtensions; i++)
{
std::cout << std::endl;
std::cout << "Name: " << extensions[i].extensionName << std::endl;
std::cout << "Spec Version: " << extensions[i].specVersion << std::endl;
}
std::cout << std::endl;
//______________________________Folge19______________________________________________
delete[] extensions;
}
//______________________________Folge81__________________________________________________
void createGlfwWindowSurface()
{
//______________________________Folge23_____________________________________________
result = glfwCreateWindowSurface(instance, window, nullptr, &surface);
ASSERT_VULKAN(result);
}
//______________________________Folge81__________________________________________________
void printPhysicalDeviceStats()
{
//______________________________Folge9_______________________________________________
for (int i = 0; i < physicalDevices.size(); i++)
{
printStats(physicalDevices[i]);
}
}
//______________________________Folg81___________________________________________________
void createLogicalDevcie()
{
//______________________________Folge16______________________________________________
float queuePrios[] =
{
1.0F, 1.0F, 1.0F, 1.0F
};
//______________________________Folge13______________________________________________
VkDeviceQueueCreateInfo deviceQueueCreateInfo;
deviceQueueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
deviceQueueCreateInfo.pNext = nullptr;
deviceQueueCreateInfo.flags = 0;
deviceQueueCreateInfo.queueFamilyIndex = 0; //TODO chose correct family index
deviceQueueCreateInfo.queueCount = 1; //TODO check if this ammount is valid
deviceQueueCreateInfo.pQueuePriorities = queuePrios;
//______________________________Folge28______________________________________________
const std::vector<const char*> deviceExtensions =
{
VK_KHR_SWAPCHAIN_EXTENSION_NAME
};
//______________________________Folge14______________________________________________
VkDeviceCreateInfo deviceCreateInfo;
deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
deviceCreateInfo.pNext = nullptr;
deviceCreateInfo.flags = 0;
deviceCreateInfo.queueCreateInfoCount = 1;
deviceCreateInfo.pQueueCreateInfos = &deviceQueueCreateInfo;
deviceCreateInfo.enabledLayerCount = 0;
deviceCreateInfo.ppEnabledLayerNames = nullptr;
deviceCreateInfo.enabledExtensionCount = deviceExtensions.size();
deviceCreateInfo.ppEnabledExtensionNames = deviceExtensions.data();
deviceCreateInfo.pEnabledFeatures = &features;
//______________________________Folge15______________________________________________
result = vkCreateDevice(physicalDevices[0], &deviceCreateInfo, nullptr, &device); //TODO pick "best device" instead of first device
ASSERT_VULKAN(result);
}
//______________________________Folg81___________________________________________________
void createQueue()
{
//______________________________Folge19______________________________________________
vkGetDeviceQueue(device, 0, 0, &queue);
}
//______________________________Folg81___________________________________________________
void checkSurfaceSupport()
{
//______________________________Folge28______________________________________________
VkBool32 surfaceSupport = false;
result = vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevices[0], 0, surface, &surfaceSupport);
ASSERT_VULKAN(result);
if (!surfaceSupport)
{
std::cerr << "Surface not supported!" << std::endl;
__debugbreak();
}
}
//______________________________Folg81___________________________________________________
void createSwapchain()
{
//______________________________Folge27______________________________________________
VkSwapchainCreateInfoKHR swapchainCreateInfo;
swapchainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
swapchainCreateInfo.pNext = nullptr;
swapchainCreateInfo.flags = 0;
swapchainCreateInfo.surface = surface;
swapchainCreateInfo.minImageCount = 2; //TODO check if valid
swapchainCreateInfo.imageFormat = FORMAT; //TODO check if valid
swapchainCreateInfo.imageColorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; //TODO check if valid
swapchainCreateInfo.imageExtent = VkExtent2D{ windowWidth, windowHeight };
swapchainCreateInfo.imageArrayLayers = 1;
swapchainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
swapchainCreateInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
swapchainCreateInfo.queueFamilyIndexCount = 0;
swapchainCreateInfo.pQueueFamilyIndices = nullptr;
swapchainCreateInfo.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
swapchainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
swapchainCreateInfo.presentMode = VK_PRESENT_MODE_FIFO_KHR;
swapchainCreateInfo.clipped = VK_TRUE;
swapchainCreateInfo.oldSwapchain = swapchain;
//______________________________Folge28______________________________________________
result = vkCreateSwapchainKHR(device, &swapchainCreateInfo, nullptr, &swapchain);
ASSERT_VULKAN(result);
}
//______________________________Folg81___________________________________________________
void createImageViews()
{
//______________________________Folge29______________________________________________
result = vkGetSwapchainImagesKHR(device, swapchain, &ammountOfSwapchainImages, nullptr);
ASSERT_VULKAN(result);
VkImage* swapchainImages = new VkImage[ammountOfSwapchainImages];
result = vkGetSwapchainImagesKHR(device, swapchain, &ammountOfSwapchainImages, swapchainImages);
ASSERT_VULKAN(result);
//______________________________Folge31______________________________________________
imageViews = new VkImageView[ammountOfSwapchainImages];
for (int i = 0; i < ammountOfSwapchainImages; i++)
{
//______________________________Folge30__________________________________________
VkImageViewCreateInfo imageViewCreateInfo;
imageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
imageViewCreateInfo.pNext = nullptr;
imageViewCreateInfo.flags = 0;
imageViewCreateInfo.image = swapchainImages[i];
imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
imageViewCreateInfo.format = FORMAT; //TODO check if valid
imageViewCreateInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
imageViewCreateInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
imageViewCreateInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
imageViewCreateInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
imageViewCreateInfo.subresourceRange.baseMipLevel = 0;
imageViewCreateInfo.subresourceRange.levelCount = 1;
imageViewCreateInfo.subresourceRange.baseArrayLayer = 0;
imageViewCreateInfo.subresourceRange.layerCount = 1;
//______________________________Folge31__________________________________________
result = vkCreateImageView(device, &imageViewCreateInfo, nullptr, &imageViews[i]);
ASSERT_VULKAN(result);
}
//______________________________Folge29______________________________________________
delete[] swapchainImages;
}
//______________________________Folg81___________________________________________________
void createRenderPass()
{
//______________________________Folge51______________________________________________
VkAttachmentDescription attachmentDescription;
attachmentDescription.flags = 0;
attachmentDescription.format = FORMAT; //TODO check if valid
attachmentDescription.samples = VK_SAMPLE_COUNT_1_BIT;
attachmentDescription.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
attachmentDescription.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
attachmentDescription.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachmentDescription.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachmentDescription.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
attachmentDescription.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
//______________________________Folge52______________________________________________
VkAttachmentReference attachmentReference;
attachmentReference.attachment = 0;
attachmentReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
//______________________________Folge53______________________________________________
VkSubpassDescription subpassDescription;
subpassDescription.flags = 0;
subpassDescription.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
subpassDescription.inputAttachmentCount = 0;
subpassDescription.pInputAttachments = nullptr;
subpassDescription.colorAttachmentCount = 1;
subpassDescription.pColorAttachments = &attachmentReference;
subpassDescription.pResolveAttachments = nullptr;
subpassDescription.pDepthStencilAttachment = nullptr;
subpassDescription.preserveAttachmentCount = 0;
subpassDescription.pPreserveAttachments = nullptr;
//______________________________Folge75______________________________________________
VkSubpassDependency subpassDependency;
subpassDependency.srcSubpass = VK_SUBPASS_EXTERNAL;
subpassDependency.dstSubpass = 0;
subpassDependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
subpassDependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
subpassDependency.srcAccessMask = 0;
subpassDependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
subpassDependency.dependencyFlags = 0;
//______________________________Folge54______________________________________________
VkRenderPassCreateInfo renderPassCreateInfo;
renderPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
renderPassCreateInfo.pNext = nullptr;
renderPassCreateInfo.flags = 0;
renderPassCreateInfo.attachmentCount = 1;
renderPassCreateInfo.pAttachments = &attachmentDescription;
renderPassCreateInfo.subpassCount = 1;
renderPassCreateInfo.pSubpasses = &subpassDescription;
renderPassCreateInfo.dependencyCount = 0;
renderPassCreateInfo.pDependencies = nullptr;
//______________________________Folge55______________________________________________
result = vkCreateRenderPass(device, &renderPassCreateInfo, nullptr, &renderPass);
ASSERT_VULKAN(result);
}
//______________________________Folg81___________________________________________________
void createGraphicsPipeline()
{
//______________________________Folge36______________________________________________
auto shaderCodeVert = readFile("vert.spv");
auto shaderCodeFrag = readFile("frag.spv");
//______________________________Folge38______________________________________________
createShaderModule(shaderCodeVert, &shaderModuleVert);
createShaderModule(shaderCodeFrag, &shaderModuleFrag);
//______________________________Folge39______________________________________________
VkPipelineShaderStageCreateInfo shaderStageCreateInfoVert;
shaderStageCreateInfoVert.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
shaderStageCreateInfoVert.pNext = nullptr;
shaderStageCreateInfoVert.flags = 0;
shaderStageCreateInfoVert.stage = VK_SHADER_STAGE_VERTEX_BIT;
shaderStageCreateInfoVert.module = shaderModuleVert;
shaderStageCreateInfoVert.pName = "main";
shaderStageCreateInfoVert.pSpecializationInfo = nullptr;
VkPipelineShaderStageCreateInfo shaderStageCreateInfoFrag;
shaderStageCreateInfoFrag.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
shaderStageCreateInfoFrag.pNext = nullptr;
shaderStageCreateInfoFrag.flags = 0;
shaderStageCreateInfoFrag.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
shaderStageCreateInfoFrag.module = shaderModuleFrag;
shaderStageCreateInfoFrag.pName = "main";
shaderStageCreateInfoFrag.pSpecializationInfo = nullptr;
VkPipelineShaderStageCreateInfo shaderStageCreateInfos[] =
{
shaderStageCreateInfoVert, shaderStageCreateInfoFrag
};
//______________________________Folge40______________________________________________
VkPipelineVertexInputStateCreateInfo vertexInputCreateInfo;
vertexInputCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
vertexInputCreateInfo.pNext = nullptr;
vertexInputCreateInfo.flags = 0;
vertexInputCreateInfo.vertexBindingDescriptionCount = 0;
vertexInputCreateInfo.pVertexBindingDescriptions = nullptr;
vertexInputCreateInfo.vertexAttributeDescriptionCount = 0;
vertexInputCreateInfo.pVertexAttributeDescriptions = nullptr;
//______________________________Folge41______________________________________________
VkPipelineInputAssemblyStateCreateInfo inputAssemblyCreateInfo;
inputAssemblyCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
inputAssemblyCreateInfo.pNext = nullptr;
inputAssemblyCreateInfo.flags = 0;
inputAssemblyCreateInfo.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
inputAssemblyCreateInfo.primitiveRestartEnable = VK_FALSE;
//______________________________Folge42______________________________________________
VkViewport viewport;
viewport.x = 0.0f;
viewport.y = 0.0f;
viewport.width = windowWidth;
viewport.height = windowHeight;
viewport.minDepth = 0.0f;
viewport.maxDepth = 1.0f;
//______________________________Folge43______________________________________________
VkRect2D scissor;
scissor.offset = { 0, 0 };
scissor.extent = { windowWidth, windowHeight };