//============================================================================== void PipelineImpl::initGraphics(const PipelineInitInfo& init) { FilledGraphicsPipelineCreateInfo ci = FILLED; ci.pStages = &ci.m_stages[0]; initShaders(init, ci); // Init sub-states ci.pVertexInputState = initVertexStage(init.m_vertex, ci.m_vertex); ci.pInputAssemblyState = initInputAssemblyState(init.m_inputAssembler, ci.m_ia); ci.pTessellationState = initTessellationState(init.m_tessellation, ci.m_tess); ci.pViewportState = initViewportState(ci.m_vp); ci.pRasterizationState = initRasterizerState(init.m_rasterizer, ci.m_rast); ci.pMultisampleState = initMsState(ci.m_ms); ci.pDepthStencilState = initDsState(init.m_depthStencil, ci.m_ds); ci.pColorBlendState = initColorState(init.m_color, ci.m_color); ci.pDynamicState = nullptr; // No dynamic state as static at the moment // Finalize ci.layout = getGrManagerImpl().m_globalPipelineLayout; ci.renderPass = getGrManagerImpl().getOrCreateCompatibleRenderPass(init); ci.basePipelineHandle = VK_NULL_HANDLE; ANKI_VK_CHECK(vkCreateGraphicsPipelines( getDevice(), nullptr, 1, &ci, nullptr, &m_handle)); }
void preparePipelines() { if (pipeline != VK_NULL_HANDLE) { vkDestroyPipeline(device, pipeline, nullptr); } const std::vector<VkDynamicState> dynamicStateEnables = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCI = vks::initializers::pipelineInputAssemblyStateCreateInfo(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0, VK_FALSE); VkPipelineColorBlendAttachmentState blendAttachmentState = vks::initializers::pipelineColorBlendAttachmentState(0xf, VK_FALSE); VkPipelineColorBlendStateCreateInfo colorBlendStateCI = vks::initializers::pipelineColorBlendStateCreateInfo(1, &blendAttachmentState); VkPipelineDepthStencilStateCreateInfo depthStencilStateCI = vks::initializers::pipelineDepthStencilStateCreateInfo(VK_TRUE, VK_FALSE, VK_COMPARE_OP_LESS_OR_EQUAL); VkPipelineViewportStateCreateInfo viewportStateCI = vks::initializers::pipelineViewportStateCreateInfo(1, 1, 0); VkPipelineMultisampleStateCreateInfo multisampleStateCI = vks::initializers::pipelineMultisampleStateCreateInfo(VK_SAMPLE_COUNT_1_BIT, 0); VkPipelineDynamicStateCreateInfo dynamicStateCI = vks::initializers::pipelineDynamicStateCreateInfo(dynamicStateEnables.data(), static_cast<uint32_t>(dynamicStateEnables.size()), 0); VkPipelineRasterizationStateCreateInfo rasterizationStateCI{}; rasterizationStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; rasterizationStateCI.polygonMode = VK_POLYGON_MODE_FILL; rasterizationStateCI.lineWidth = 1.0f; rasterizationStateCI.cullMode = VK_CULL_MODE_NONE + cullMode; rasterizationStateCI.frontFace = windingOrder == 0 ? VK_FRONT_FACE_CLOCKWISE : VK_FRONT_FACE_COUNTER_CLOCKWISE; // Vertex bindings and attributes std::vector<VkVertexInputBindingDescription> vertexInputBindings = { vks::initializers::vertexInputBindingDescription(0, sizeof(float) * 5, VK_VERTEX_INPUT_RATE_VERTEX), }; std::vector<VkVertexInputAttributeDescription> vertexInputAttributes = { vks::initializers::vertexInputAttributeDescription(0, 0, VK_FORMAT_R32G32B32_SFLOAT, 0), // Position vks::initializers::vertexInputAttributeDescription(0, 1, VK_FORMAT_R32G32_SFLOAT, sizeof(float) * 3), // uv }; VkPipelineVertexInputStateCreateInfo vertexInputState = vks::initializers::pipelineVertexInputStateCreateInfo(); vertexInputState.vertexBindingDescriptionCount = static_cast<uint32_t>(vertexInputBindings.size()); vertexInputState.pVertexBindingDescriptions = vertexInputBindings.data(); vertexInputState.vertexAttributeDescriptionCount = static_cast<uint32_t>(vertexInputAttributes.size()); vertexInputState.pVertexAttributeDescriptions = vertexInputAttributes.data(); VkGraphicsPipelineCreateInfo pipelineCreateInfoCI = vks::initializers::pipelineCreateInfo(pipelineLayout, renderPass, 0); //pipelineCreateInfoCI.pVertexInputState = &emptyInputState; pipelineCreateInfoCI.pVertexInputState = &vertexInputState; pipelineCreateInfoCI.pInputAssemblyState = &inputAssemblyStateCI; pipelineCreateInfoCI.pRasterizationState = &rasterizationStateCI; pipelineCreateInfoCI.pColorBlendState = &colorBlendStateCI; pipelineCreateInfoCI.pMultisampleState = &multisampleStateCI; pipelineCreateInfoCI.pViewportState = &viewportStateCI; pipelineCreateInfoCI.pDepthStencilState = &depthStencilStateCI; pipelineCreateInfoCI.pDynamicState = &dynamicStateCI; const std::array<VkPipelineShaderStageCreateInfo, 2> shaderStages = { loadShader(getAssetPath() + "shaders/negativeviewportheight/quad.vert.spv", VK_SHADER_STAGE_VERTEX_BIT), loadShader(getAssetPath() + "shaders/negativeviewportheight/quad.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT) }; pipelineCreateInfoCI.stageCount = static_cast<uint32_t>(shaderStages.size()); pipelineCreateInfoCI.pStages = shaderStages.data(); VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfoCI, nullptr, &pipeline)); }
void preparePipelines() { const std::vector<VkDynamicState> dynamicStateEnables = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCI = vks::initializers::pipelineInputAssemblyStateCreateInfo(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0, VK_FALSE); VkPipelineRasterizationStateCreateInfo rasterizationStateCI = vks::initializers::pipelineRasterizationStateCreateInfo(VK_POLYGON_MODE_FILL, VK_CULL_MODE_BACK_BIT, VK_FRONT_FACE_COUNTER_CLOCKWISE, 0); VkPipelineColorBlendAttachmentState blendAttachmentState = vks::initializers::pipelineColorBlendAttachmentState(0xf, VK_FALSE); VkPipelineColorBlendStateCreateInfo colorBlendStateCI = vks::initializers::pipelineColorBlendStateCreateInfo(1, &blendAttachmentState); VkPipelineDepthStencilStateCreateInfo depthStencilStateCI = vks::initializers::pipelineDepthStencilStateCreateInfo(VK_TRUE, VK_TRUE, VK_COMPARE_OP_LESS_OR_EQUAL); VkPipelineViewportStateCreateInfo viewportStateCI = vks::initializers::pipelineViewportStateCreateInfo(1, 1, 0); VkPipelineMultisampleStateCreateInfo multisampleStateCI = vks::initializers::pipelineMultisampleStateCreateInfo(VK_SAMPLE_COUNT_1_BIT, 0); VkPipelineDynamicStateCreateInfo dynamicStateCI = vks::initializers::pipelineDynamicStateCreateInfo(dynamicStateEnables.data(), static_cast<uint32_t>(dynamicStateEnables.size()), 0); // Vertex bindings and attributes const std::vector<VkVertexInputBindingDescription> vertexInputBindings = { vks::initializers::vertexInputBindingDescription(0, sizeof(vkglTF::Model::Vertex), VK_VERTEX_INPUT_RATE_VERTEX), }; const std::vector<VkVertexInputAttributeDescription> vertexInputAttributes = { vks::initializers::vertexInputAttributeDescription(0, 0, VK_FORMAT_R32G32B32_SFLOAT, 0), // Location 0: Position vks::initializers::vertexInputAttributeDescription(0, 1, VK_FORMAT_R32G32B32_SFLOAT, sizeof(float) * 3), // Location 1: Normal vks::initializers::vertexInputAttributeDescription(0, 2, VK_FORMAT_R32G32_SFLOAT, sizeof(float) * 6), // Location 2: UV }; VkPipelineVertexInputStateCreateInfo vertexInputState = vks::initializers::pipelineVertexInputStateCreateInfo(); vertexInputState.vertexBindingDescriptionCount = static_cast<uint32_t>(vertexInputBindings.size()); vertexInputState.pVertexBindingDescriptions = vertexInputBindings.data(); vertexInputState.vertexAttributeDescriptionCount = static_cast<uint32_t>(vertexInputAttributes.size()); vertexInputState.pVertexAttributeDescriptions = vertexInputAttributes.data(); VkGraphicsPipelineCreateInfo pipelineCreateInfoCI = vks::initializers::pipelineCreateInfo(pipelineLayout, renderPass, 0); pipelineCreateInfoCI.pVertexInputState = &vertexInputState; pipelineCreateInfoCI.pInputAssemblyState = &inputAssemblyStateCI; pipelineCreateInfoCI.pRasterizationState = &rasterizationStateCI; pipelineCreateInfoCI.pColorBlendState = &colorBlendStateCI; pipelineCreateInfoCI.pMultisampleState = &multisampleStateCI; pipelineCreateInfoCI.pViewportState = &viewportStateCI; pipelineCreateInfoCI.pDepthStencilState = &depthStencilStateCI; pipelineCreateInfoCI.pDynamicState = &dynamicStateCI; const std::array<VkPipelineShaderStageCreateInfo, 2> shaderStages = { loadShader(getAssetPath() + "shaders/conditionalrender/model.vert.spv", VK_SHADER_STAGE_VERTEX_BIT), loadShader(getAssetPath() + "shaders/conditionalrender/model.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT) }; pipelineCreateInfoCI.stageCount = static_cast<uint32_t>(shaderStages.size()); pipelineCreateInfoCI.pStages = shaderStages.data(); VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfoCI, nullptr, &pipeline)); }
GraphicsPipeline::GraphicsPipeline(const FunctionCallbackInfo<Value>& args) { Isolate* isolate = args.GetIsolate(); HandleScope handle_scope(isolate); Wrap(args.This()); parent_device.Reset(isolate, getELitObjectFromArgN(0, parent_device)); vkCreateGraphicsPipelines = reinterpret_cast<PFN_vkCreateGraphicsPipelines>(vkGetDeviceProcAddr(ObjectWrap::Unwrap<Device>(parent_device.Get(isolate))->vulkan_handle,"vkCreateGraphicsPipelines")); vkDestroyPipeline = reinterpret_cast<PFN_vkDestroyPipeline>(vkGetDeviceProcAddr(ObjectWrap::Unwrap<Device>(parent_device.Get(isolate))->vulkan_handle,"vkDestroyPipeline")); VkGraphicsPipelineCreateInfo pCreateInfos; memset(&pCreateInfos, 0, sizeof(VkGraphicsPipelineCreateInfo)); pCreateInfos.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; vkCreateGraphicsPipelines(ObjectWrap::Unwrap<Device>(parent_device.Get(isolate))->vulkan_handle, nullptr, 1, &pCreateInfos, nullptr, &vulkan_handle); setELitPtr(args.This(), vulkan_handle, vulkan_handle); }
VkResult Pipeline::init_try(const Device &dev, const VkGraphicsPipelineCreateInfo &info) { VkPipeline pipe; VkPipelineCache cache; VkPipelineCacheCreateInfo ci; memset((void *)&ci, 0, sizeof(VkPipelineCacheCreateInfo)); ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; VkResult err = vkCreatePipelineCache(dev.handle(), &ci, NULL, &cache); EXPECT(err == VK_SUCCESS); if (err == VK_SUCCESS) { err = vkCreateGraphicsPipelines(dev.handle(), cache, 1, &info, NULL, &pipe); if (err == VK_SUCCESS) { NonDispHandle::init(dev.handle(), pipe); } vkDestroyPipelineCache(dev.handle(), cache, NULL); } return err; }
void Shadow::SetupGraphicsPipeline() { auto pipelineCreateInfo = vkstruct<VkGraphicsPipelineCreateInfo>(); pipelineCreateInfo.flags = 0; pipelineCreateInfo.stageCount = 1u; pipelineCreateInfo.pStages = &shaderStageCreateInfo; pipelineCreateInfo.pVertexInputState = &vertexInputStateCreateInfo; pipelineCreateInfo.pInputAssemblyState = &inputAssemblyStateCreateInfo; pipelineCreateInfo.pTessellationState = nullptr; pipelineCreateInfo.pViewportState = &viewportStateCreateInfo; pipelineCreateInfo.pRasterizationState = &rasterizationStateCreateInfo; pipelineCreateInfo.pMultisampleState = &multisampleStateCreateInfo; pipelineCreateInfo.pDepthStencilState = &depthstencilStateCreateInfo; pipelineCreateInfo.pColorBlendState = nullptr; // No color attachment pipelineCreateInfo.pDynamicState = nullptr; pipelineCreateInfo.layout = mPipelineLayout; pipelineCreateInfo.renderPass = mRenderPass; pipelineCreateInfo.subpass = 0u; gVkLastRes = vkCreateGraphicsPipelines(gDevice.VkHandle(), VK_NULL_HANDLE, 1u, &pipelineCreateInfo, nullptr, &mPipeline); VKFN_LAST_RES_SUCCESS_OR_QUIT(vkCreateGraphicsPipelines); }
void preparePipelines() { VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = vks::initializers::pipelineInputAssemblyStateCreateInfo( VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0, VK_FALSE); VkPipelineRasterizationStateCreateInfo rasterizationState = vks::initializers::pipelineRasterizationStateCreateInfo( VK_POLYGON_MODE_FILL, VK_CULL_MODE_BACK_BIT, VK_FRONT_FACE_COUNTER_CLOCKWISE, 0); VkPipelineColorBlendAttachmentState blendAttachmentState = vks::initializers::pipelineColorBlendAttachmentState( 0xf, VK_FALSE); VkPipelineColorBlendStateCreateInfo colorBlendState = vks::initializers::pipelineColorBlendStateCreateInfo( 1, &blendAttachmentState); VkPipelineDepthStencilStateCreateInfo depthStencilState = vks::initializers::pipelineDepthStencilStateCreateInfo( VK_FALSE, VK_FALSE, VK_COMPARE_OP_LESS_OR_EQUAL); VkPipelineViewportStateCreateInfo viewportState = vks::initializers::pipelineViewportStateCreateInfo(1, 1, 0); VkPipelineMultisampleStateCreateInfo multisampleState = vks::initializers::pipelineMultisampleStateCreateInfo( VK_SAMPLE_COUNT_1_BIT, 0); std::vector<VkDynamicState> dynamicStateEnables = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; VkPipelineDynamicStateCreateInfo dynamicState = vks::initializers::pipelineDynamicStateCreateInfo( dynamicStateEnables.data(), dynamicStateEnables.size(), 0); // Skybox pipeline (background cube) std::array<VkPipelineShaderStageCreateInfo,2> shaderStages; shaderStages[0] = loadShader(getAssetPath() + "shaders/cubemap/skybox.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); shaderStages[1] = loadShader(getAssetPath() + "shaders/cubemap/skybox.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); VkGraphicsPipelineCreateInfo pipelineCreateInfo = vks::initializers::pipelineCreateInfo( pipelineLayout, renderPass, 0); pipelineCreateInfo.pVertexInputState = &vertices.inputState; pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState; pipelineCreateInfo.pRasterizationState = &rasterizationState; pipelineCreateInfo.pColorBlendState = &colorBlendState; pipelineCreateInfo.pMultisampleState = &multisampleState; pipelineCreateInfo.pViewportState = &viewportState; pipelineCreateInfo.pDepthStencilState = &depthStencilState; pipelineCreateInfo.pDynamicState = &dynamicState; pipelineCreateInfo.stageCount = shaderStages.size(); pipelineCreateInfo.pStages = shaderStages.data(); VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.skybox)); // Cube map reflect pipeline shaderStages[0] = loadShader(getAssetPath() + "shaders/cubemap/reflect.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); shaderStages[1] = loadShader(getAssetPath() + "shaders/cubemap/reflect.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); // Enable depth test and write depthStencilState.depthWriteEnable = VK_TRUE; depthStencilState.depthTestEnable = VK_TRUE; // Flip cull mode rasterizationState.cullMode = VK_CULL_MODE_FRONT_BIT; VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.reflect)); }
/** * Create the graphics pipeline. */ VkcPipeline::VkcPipeline(const VkcSwapchain *swapchain, const VkcDevice *device) { // Fill descriptor set binding info. QVector<VkDescriptorSetLayoutBinding> setBindings = { { 0, // uint32_t binding; VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, // VkDescriptorType descriptorType; 1, // uint32_t descriptorCount; VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlags stageFlags; nullptr // const VkSampler* pImmutableSamplers; }, { 10, // uint32_t binding; VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, // VkDescriptorType descriptorType; 1, // uint32_t descriptorCount; VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags; nullptr // const VkSampler* pImmutableSamplers; } }; // Fill desctriptor set size info. QVector<VkDescriptorPoolSize> poolSizes = { { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, // VkDescriptorType type; 1 // uint32_t descriptorCount; }, { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, // VkDescriptorType type; 1 // uint32_t descriptorCount; } }; // Fill descriptor set layout info. VkDescriptorSetLayoutCreateInfo setLayoutInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType; nullptr, // const void* pNext; 0, // VkDescriptorSetLayoutCreateFlags flags; (uint32_t)setBindings.size(), // uint32_t bindingCount; setBindings.data() // const VkDescriptorSetLayoutBinding* pBindings; }; // Create descriptor set layout. vkCreateDescriptorSetLayout(device->logical, &setLayoutInfo, nullptr, &setLayout); // Fill descriptor pool info. VkDescriptorPoolCreateInfo descriptorPoolInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, // VkStructureType sType; nullptr, // const void* pNext; VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, // VkDescriptorPoolCreateFlags flags; 1, // uint32_t maxSets; (uint32_t)poolSizes.size(), // uint32_t poolSizeCount; poolSizes.data() // const VkDescriptorPoolSize* pPoolSizes; }; // Create descriptor pool. vkCreateDescriptorPool(device->logical, &descriptorPoolInfo, nullptr, &descriptorPool); // Fill descriptor set allocate info. VkDescriptorSetAllocateInfo descriptorSetAllocateInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType; nullptr, // const void* pNext; descriptorPool, // VkDescriptorPool descriptorPool; 1, // uint32_t descriptorSetCount; &setLayout // const VkDescriptorSetLayout* pSetLayouts; }; // Allocate space for descriptor set. vkAllocateDescriptorSets(device->logical, &descriptorSetAllocateInfo, &descriptorSet); // Fill pipeline layout info. VkPipelineLayoutCreateInfo pipelineLayoutInfo = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; nullptr, // const void* pNext; 0, // VkPipelineLayoutCreateFlags flags; 1, // uint32_t setLayoutCount; &setLayout, // const VkDescriptorSetLayout* pSetLayouts; 0, // uint32_t pushConstantRangeCount; nullptr // const VkPushConstantRange* pPushConstantRanges; }; // Create pipeline layout. vkCreatePipelineLayout(device->logical, &pipelineLayoutInfo, nullptr, &layout); // Create shaders. createShader(vertShader, "shader.vert.spv", device); createShader(fragShader, "shader.frag.spv", device); // Fill shader stage info. QVector<VkPipelineShaderStageCreateInfo> shaderStages = { { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; nullptr, // const void* pNext; 0, // VkPipelineShaderStageCreateFlags flags; VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage; vertShader, // VkShaderModule module; "main", // const char* pName; nullptr // const VkSpecializationInfo* pSpecializationInfo; }, { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; nullptr, // const void* pNext; 0, // VkPipelineShaderStageCreateFlags flags; VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage; fragShader, // VkShaderModule module; "main", // const char* pName; nullptr // const VkSpecializationInfo* pSpecializationInfo; } }; // Fill vertex input binding description. VkVertexInputBindingDescription vertexBinding = { 0, // uint32_t binding; sizeof(VkVertex), // uint32_t stride; VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate; }; // Fill vertex input attribute description. QVector<VkVertexInputAttributeDescription> vertexAttributes = { { 0, // uint32_t location; 0, // uint32_t binding; VK_FORMAT_R32G32B32_SFLOAT, // VkFormat format; offsetof(VkVertex, x) // uint32_t offset; }, { 1, // uint32_t location; 0, // uint32_t binding; VK_FORMAT_R32G32_SFLOAT, // VkFormat format; offsetof(VkVertex, u) // uint32_t offset; }, { 2, // uint32_t location; 0, // uint32_t binding; VK_FORMAT_R32G32B32_SFLOAT, // VkFormat format; offsetof(VkVertex, nx) // uint32_t offset; } }; // Fill vertex input state info. VkPipelineVertexInputStateCreateInfo vertexInfo = { VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; nullptr, // const void* pNext; 0, // VkPipelineVertexInputStateCreateFlags flags; 1, // uint32_t vertexBindingDescriptionCount; &vertexBinding, // const VkVertexInputBindingDescription* pVertexBindingDescriptions; (uint32_t)vertexAttributes.size(), // uint32_t vertexAttributeDescriptionCount; vertexAttributes.data() // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; }; VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo = { VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType; nullptr, // const void* pNext; 0, // VkPipelineInputAssemblyStateCreateFlags flags; VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology topology; VK_FALSE, // VkBool32 primitiveRestartEnable; }; /* * Space reserved for VkPipelineTessellationStateCreateInfo. */ // Fill viewport info. VkViewport viewport = { 0.0f, // float x; 0.0f, // float y; (float)swapchain->extent.width, // float width; (float)swapchain->extent.height, // float height; 0.0f, // float minDepth; 1.0f, // float maxDepth; }; // Fill scissors info. VkRect2D scissors = { {0, 0}, // VkOffset2D offset; swapchain->extent // VkExtent2D extent; }; // Fill viewport state info. VkPipelineViewportStateCreateInfo viewportInfo = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType; nullptr, // const void* pNext; 0, // VkPipelineViewportStateCreateFlags flags; 1, // uint32_t viewportCount; &viewport, // const VkViewport* pViewports; 1, // uint32_t scissorCount; &scissors // const VkRect2D* pScissors; }; // Fill rasterization state info. VkPipelineRasterizationStateCreateInfo rasterisationInfo = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; nullptr, // const void* pNext; 0, // VkPipelineRasterizationStateCreateFlags flags; VK_FALSE, // VkBool32 depthClampEnable; VK_FALSE, // VkBool32 rasterizerDiscardEnable; VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode; VK_CULL_MODE_BACK_BIT, // VkCullModeFlags cullMode; VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace; VK_FALSE, // VkBool32 depthBiasEnable; 0, // float depthBiasConstantFactor; 0, // float depthBiasClamp; 0, // float depthBiasSlopeFactor; 1, // float lineWidth; }; // Fill multisample state info. VkPipelineMultisampleStateCreateInfo multisampleInfo = { VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; nullptr, // const void* pNext; 0, // VkPipelineMultisampleStateCreateFlags flags; VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples; VK_FALSE, // VkBool32 sampleShadingEnable; 0, // float minSampleShading; nullptr, // const VkSampleMask* pSampleMask; VK_FALSE, // VkBool32 alphaToCoverageEnable; VK_FALSE, // VkBool32 alphaToOneEnable; }; // Fill stencil operation state info. VkStencilOpState stencilInfo = { VK_STENCIL_OP_KEEP, // VkStencilOp failOp; VK_STENCIL_OP_INCREMENT_AND_CLAMP, // VkStencilOp passOp; VK_STENCIL_OP_INCREMENT_AND_CLAMP, // VkStencilOp depthFailOp; VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp; 0, // uint32_t compareMask; 0, // uint32_t writeMask; 0 // uint32_t reference; }; // Fill depth state info. VkPipelineDepthStencilStateCreateInfo depthStencilInfo = { VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType; nullptr, // const void* pNext; 0, // VkPipelineDepthStencilStateCreateFlags flags; VK_TRUE, // VkBool32 depthTestEnable; VK_TRUE, // VkBool32 depthWriteEnable; VK_COMPARE_OP_GREATER_OR_EQUAL, // VkCompareOp depthCompareOp; VK_FALSE, // VkBool32 depthBoundsTestEnable; VK_TRUE, // VkBool32 stencilTestEnable; stencilInfo, // VkStencilOpState front; stencilInfo, // VkStencilOpState back; 0.0f, // float minDepthBounds; 0.0f // float maxDepthBounds; }; // Fill color blend attachment state info. VkPipelineColorBlendAttachmentState colorBlendState = { VK_TRUE, // VkBool32 blendEnable; VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcColorBlendFactor; VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // VkBlendFactor dstColorBlendFactor; VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp; VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcAlphaBlendFactor; VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // VkBlendFactor dstAlphaBlendFactor; VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp; VK_COLOR_COMPONENT_R_BIT | // VkColorComponentFlags colorWriteMask; VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT }; // Fill color blend state info. VkPipelineColorBlendStateCreateInfo colorBlendInfo = { VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; nullptr, // const void* pNext; 0, // VkPipelineColorBlendStateCreateFlags flags; VK_FALSE, // VkBool32 logicOpEnable; VK_LOGIC_OP_NO_OP, // VkLogicOp logicOp; 1, // uint32_t attachmentCount; &colorBlendState, // const VkPipelineColorBlendAttachmentState* pAttachments; {1.0f, 1.0f, 1.0f, 1.0f} // float blendConstants[4]; }; // Select dynamic states. QVector<VkDynamicState> dynamicStates = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, //VK_DYNAMIC_STATE_STENCIL_REFERENCE }; // Fill dynamic state info. VkPipelineDynamicStateCreateInfo dynamicStateInfo = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType; nullptr, // const void* pNext; 0, // VkPipelineDynamicStateCreateFlags flags; (uint32_t)dynamicStates.count(), // uint32_t dynamicStateCount; dynamicStates.data() // const VkDynamicState* pDynamicStates; }; // Fill graphics pipeline info. VkGraphicsPipelineCreateInfo pipelineInfo = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType; nullptr, // const void* pNext; 0, // VkPipelineCreateFlags flags; (uint32_t)shaderStages.size(), // uint32_t stageCount; shaderStages.data(), // const VkPipelineShaderStageCreateInfo* pStages; &vertexInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState; &inputAssemblyInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; nullptr, // const VkPipelineTessellationStateCreateInfo* pTessellationState; &viewportInfo, // const VkPipelineViewportStateCreateInfo* pViewportState; &rasterisationInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState; &multisampleInfo, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState; &depthStencilInfo, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; &colorBlendInfo, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState; &dynamicStateInfo, // const VkPipelineDynamicStateCreateInfo* pDynamicState; layout, // VkPipelineLayout layout; swapchain->renderPass, // VkRenderPass renderPass; 0, // uint32_t subpass; VK_NULL_HANDLE, // VkPipeline basePipelineHandle; 0 // int32_t basePipelineIndex; }; // Create graphics pipeline. vkCreateGraphicsPipelines(device->logical, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &handle); this->logicalDevice = device->logical; }
bool Tutorial03::CreatePipeline() { Tools::AutoDeleter<VkShaderModule, PFN_vkDestroyShaderModule> vertex_shader_module = CreateShaderModule( "Data03/vert.spv" ); Tools::AutoDeleter<VkShaderModule, PFN_vkDestroyShaderModule> fragment_shader_module = CreateShaderModule( "Data03/frag.spv" ); if( !vertex_shader_module || !fragment_shader_module ) { return false; } std::vector<VkPipelineShaderStageCreateInfo> shader_stage_create_infos = { // Vertex shader { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType nullptr, // const void *pNext 0, // VkPipelineShaderStageCreateFlags flags VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage vertex_shader_module.Get(), // VkShaderModule module "main", // const char *pName nullptr // const VkSpecializationInfo *pSpecializationInfo }, // Fragment shader { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType nullptr, // const void *pNext 0, // VkPipelineShaderStageCreateFlags flags VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage fragment_shader_module.Get(), // VkShaderModule module "main", // const char *pName nullptr // const VkSpecializationInfo *pSpecializationInfo } }; VkPipelineVertexInputStateCreateInfo vertex_input_state_create_info = { VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType nullptr, // const void *pNext 0, // VkPipelineVertexInputStateCreateFlags flags; 0, // uint32_t vertexBindingDescriptionCount nullptr, // const VkVertexInputBindingDescription *pVertexBindingDescriptions 0, // uint32_t vertexAttributeDescriptionCount nullptr // const VkVertexInputAttributeDescription *pVertexAttributeDescriptions }; VkPipelineInputAssemblyStateCreateInfo input_assembly_state_create_info = { VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType nullptr, // const void *pNext 0, // VkPipelineInputAssemblyStateCreateFlags flags VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology topology VK_FALSE // VkBool32 primitiveRestartEnable }; VkViewport viewport = { 0.0f, // float x 0.0f, // float y 300.0f, // float width 300.0f, // float height 0.0f, // float minDepth 1.0f // float maxDepth }; VkRect2D scissor = { { // VkOffset2D offset 0, // int32_t x 0 // int32_t y }, { // VkExtent2D extent 300, // int32_t width 300 // int32_t height } }; VkPipelineViewportStateCreateInfo viewport_state_create_info = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType nullptr, // const void *pNext 0, // VkPipelineViewportStateCreateFlags flags 1, // uint32_t viewportCount &viewport, // const VkViewport *pViewports 1, // uint32_t scissorCount &scissor // const VkRect2D *pScissors }; VkPipelineRasterizationStateCreateInfo rasterization_state_create_info = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType nullptr, // const void *pNext 0, // VkPipelineRasterizationStateCreateFlags flags VK_FALSE, // VkBool32 depthClampEnable VK_FALSE, // VkBool32 rasterizerDiscardEnable VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode VK_CULL_MODE_BACK_BIT, // VkCullModeFlags cullMode VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace VK_FALSE, // VkBool32 depthBiasEnable 0.0f, // float depthBiasConstantFactor 0.0f, // float depthBiasClamp 0.0f, // float depthBiasSlopeFactor 1.0f // float lineWidth }; VkPipelineMultisampleStateCreateInfo multisample_state_create_info = { VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType nullptr, // const void *pNext 0, // VkPipelineMultisampleStateCreateFlags flags VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples VK_FALSE, // VkBool32 sampleShadingEnable 1.0f, // float minSampleShading nullptr, // const VkSampleMask *pSampleMask VK_FALSE, // VkBool32 alphaToCoverageEnable VK_FALSE // VkBool32 alphaToOneEnable }; VkPipelineColorBlendAttachmentState color_blend_attachment_state = { VK_FALSE, // VkBool32 blendEnable VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | // VkColorComponentFlags colorWriteMask VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT }; VkPipelineColorBlendStateCreateInfo color_blend_state_create_info = { VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType nullptr, // const void *pNext 0, // VkPipelineColorBlendStateCreateFlags flags VK_FALSE, // VkBool32 logicOpEnable VK_LOGIC_OP_COPY, // VkLogicOp logicOp 1, // uint32_t attachmentCount &color_blend_attachment_state, // const VkPipelineColorBlendAttachmentState *pAttachments { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4] }; Tools::AutoDeleter<VkPipelineLayout, PFN_vkDestroyPipelineLayout> pipeline_layout = CreatePipelineLayout(); if( !pipeline_layout ) { return false; } VkGraphicsPipelineCreateInfo pipeline_create_info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType nullptr, // const void *pNext 0, // VkPipelineCreateFlags flags static_cast<uint32_t>(shader_stage_create_infos.size()), // uint32_t stageCount &shader_stage_create_infos[0], // const VkPipelineShaderStageCreateInfo *pStages &vertex_input_state_create_info, // const VkPipelineVertexInputStateCreateInfo *pVertexInputState; &input_assembly_state_create_info, // const VkPipelineInputAssemblyStateCreateInfo *pInputAssemblyState nullptr, // const VkPipelineTessellationStateCreateInfo *pTessellationState &viewport_state_create_info, // const VkPipelineViewportStateCreateInfo *pViewportState &rasterization_state_create_info, // const VkPipelineRasterizationStateCreateInfo *pRasterizationState &multisample_state_create_info, // const VkPipelineMultisampleStateCreateInfo *pMultisampleState nullptr, // const VkPipelineDepthStencilStateCreateInfo *pDepthStencilState &color_blend_state_create_info, // const VkPipelineColorBlendStateCreateInfo *pColorBlendState nullptr, // const VkPipelineDynamicStateCreateInfo *pDynamicState pipeline_layout.Get(), // VkPipelineLayout layout Vulkan.RenderPass, // VkRenderPass renderPass 0, // uint32_t subpass VK_NULL_HANDLE, // VkPipeline basePipelineHandle -1 // int32_t basePipelineIndex }; if( vkCreateGraphicsPipelines( GetDevice(), VK_NULL_HANDLE, 1, &pipeline_create_info, nullptr, &Vulkan.GraphicsPipeline ) != VK_SUCCESS ) { std::cout << "Could not create graphics pipeline!" << std::endl; return false; } return true; }
void preparePipelines() { VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = vkTools::initializers::pipelineInputAssemblyStateCreateInfo( VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0, VK_FALSE); VkPipelineRasterizationStateCreateInfo rasterizationState = vkTools::initializers::pipelineRasterizationStateCreateInfo( VK_POLYGON_MODE_FILL, VK_CULL_MODE_BACK_BIT, VK_FRONT_FACE_CLOCKWISE, 0); VkPipelineColorBlendAttachmentState blendAttachmentState = vkTools::initializers::pipelineColorBlendAttachmentState( 0xf, VK_FALSE); VkPipelineColorBlendStateCreateInfo colorBlendState = vkTools::initializers::pipelineColorBlendStateCreateInfo( 1, &blendAttachmentState); VkPipelineDepthStencilStateCreateInfo depthStencilState = vkTools::initializers::pipelineDepthStencilStateCreateInfo( VK_TRUE, VK_TRUE, VK_COMPARE_OP_LESS_OR_EQUAL); VkPipelineViewportStateCreateInfo viewportState = vkTools::initializers::pipelineViewportStateCreateInfo(1, 1, 0); VkPipelineMultisampleStateCreateInfo multisampleState = vkTools::initializers::pipelineMultisampleStateCreateInfo( VK_SAMPLE_COUNT_1_BIT, 0); std::vector<VkDynamicState> dynamicStateEnables = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; VkPipelineDynamicStateCreateInfo dynamicState = vkTools::initializers::pipelineDynamicStateCreateInfo( dynamicStateEnables.data(), dynamicStateEnables.size(), 0); // Pipeline for the meshes (armadillo, bunny, etc.) // Load shaders std::array<VkPipelineShaderStageCreateInfo, 2> shaderStages; shaderStages[0] = loadShader(getAssetPath() + "shaders/vulkanscene/mesh.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); shaderStages[1] = loadShader(getAssetPath() + "shaders/vulkanscene/mesh.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); VkGraphicsPipelineCreateInfo pipelineCreateInfo = vkTools::initializers::pipelineCreateInfo( pipelineLayout, renderPass, 0); pipelineCreateInfo.pVertexInputState = &demoMeshes.inputState; pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState; pipelineCreateInfo.pRasterizationState = &rasterizationState; pipelineCreateInfo.pColorBlendState = &colorBlendState; pipelineCreateInfo.pMultisampleState = &multisampleState; pipelineCreateInfo.pViewportState = &viewportState; pipelineCreateInfo.pDepthStencilState = &depthStencilState; pipelineCreateInfo.pDynamicState = &dynamicState; pipelineCreateInfo.stageCount = shaderStages.size(); pipelineCreateInfo.pStages = shaderStages.data(); VkResult err = vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.models); assert(!err); // Pipeline for the logos shaderStages[0] = loadShader(getAssetPath() + "shaders/vulkanscene/logo.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); shaderStages[1] = loadShader(getAssetPath() + "shaders/vulkanscene/logo.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); err = vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.logos); assert(!err); // Pipeline for the sky sphere (todo) rasterizationState.cullMode = VK_CULL_MODE_FRONT_BIT; // Inverted culling depthStencilState.depthWriteEnable = VK_FALSE; // No depth writes shaderStages[0] = loadShader(getAssetPath() + "shaders/vulkanscene/skybox.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); shaderStages[1] = loadShader(getAssetPath() + "shaders/vulkanscene/skybox.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); err = vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.skybox); assert(!err); // Assign pipelines demoMeshes.logos->pipeline = pipelines.logos; demoMeshes.models->pipeline = pipelines.models; demoMeshes.background->pipeline = pipelines.models; demoMeshes.skybox->pipeline = pipelines.skybox; }
void preparePipelines() { VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = vkTools::initializers::pipelineInputAssemblyStateCreateInfo( VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0, VK_FALSE); VkPipelineRasterizationStateCreateInfo rasterizationState = vkTools::initializers::pipelineRasterizationStateCreateInfo( VK_POLYGON_MODE_FILL, VK_CULL_MODE_NONE, VK_FRONT_FACE_COUNTER_CLOCKWISE, 0); VkPipelineColorBlendAttachmentState blendAttachmentState = vkTools::initializers::pipelineColorBlendAttachmentState( 0xf, VK_FALSE); VkPipelineColorBlendStateCreateInfo colorBlendState = vkTools::initializers::pipelineColorBlendStateCreateInfo( 1, &blendAttachmentState); VkPipelineDepthStencilStateCreateInfo depthStencilState = vkTools::initializers::pipelineDepthStencilStateCreateInfo( VK_TRUE, VK_TRUE, VK_COMPARE_OP_LESS_OR_EQUAL); VkPipelineViewportStateCreateInfo viewportState = vkTools::initializers::pipelineViewportStateCreateInfo(1, 1, 0); VkPipelineMultisampleStateCreateInfo multisampleState = vkTools::initializers::pipelineMultisampleStateCreateInfo( VK_SAMPLE_COUNT_1_BIT, 0); std::vector<VkDynamicState> dynamicStateEnables = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; VkPipelineDynamicStateCreateInfo dynamicState = vkTools::initializers::pipelineDynamicStateCreateInfo( dynamicStateEnables.data(), dynamicStateEnables.size(), 0); // Parallax mapping pipeline // Load shaders std::array<VkPipelineShaderStageCreateInfo, 2> shaderStages; shaderStages[0] = loadShader("./../data/shaders/parallax/parallax.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); shaderStages[1] = loadShader("./../data/shaders/parallax/parallax.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); VkGraphicsPipelineCreateInfo pipelineCreateInfo = vkTools::initializers::pipelineCreateInfo( pipelineLayout, renderPass, 0); pipelineCreateInfo.pVertexInputState = &vertices.inputState; pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState; pipelineCreateInfo.pRasterizationState = &rasterizationState; pipelineCreateInfo.pColorBlendState = &colorBlendState; pipelineCreateInfo.pMultisampleState = &multisampleState; pipelineCreateInfo.pViewportState = &viewportState; pipelineCreateInfo.pDepthStencilState = &depthStencilState; pipelineCreateInfo.pDynamicState = &dynamicState; pipelineCreateInfo.stageCount = shaderStages.size(); pipelineCreateInfo.pStages = shaderStages.data(); VkResult err = vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.parallaxMapping); assert(!err); // Normal mapping (no parallax effect) shaderStages[0] = loadShader("./../data/shaders/parallax/normalmap.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); shaderStages[1] = loadShader("./../data/shaders/parallax/normalmap.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); err = vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.normalMapping); assert(!err); }
void Renderer::_InitGraphicsPipeline() { { // Create Vertex Shader Module std::vector<char> vert_shader_code = readFile(VERT_PATH); VkShaderModuleCreateInfo shader_module_create_info{}; shader_module_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; shader_module_create_info.codeSize = vert_shader_code.size(); shader_module_create_info.pCode = (uint32_t *)vert_shader_code.data(); ErrorCheck(vkCreateShaderModule(_device, &shader_module_create_info, nullptr, &_vert_module)); } { // Create Fragment Shader Module std::vector<char> frag_shader_code = readFile(FRAG_PATH); VkShaderModuleCreateInfo shader_module_create_info{}; shader_module_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; shader_module_create_info.codeSize = frag_shader_code.size(); shader_module_create_info.pCode = (uint32_t *)frag_shader_code.data(); ErrorCheck(vkCreateShaderModule(_device, &shader_module_create_info, nullptr, &_frag_module)); } VkPipelineShaderStageCreateInfo vert_shader_stage_create_info{}; vert_shader_stage_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; vert_shader_stage_create_info.stage = VK_SHADER_STAGE_VERTEX_BIT; vert_shader_stage_create_info.module = _vert_module; vert_shader_stage_create_info.pName = "main"; VkPipelineShaderStageCreateInfo frag_shader_stage_create_info{}; frag_shader_stage_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; frag_shader_stage_create_info.stage = VK_SHADER_STAGE_FRAGMENT_BIT; frag_shader_stage_create_info.module = _frag_module; frag_shader_stage_create_info.pName = "main"; VkPipelineShaderStageCreateInfo shader_stages[] = { vert_shader_stage_create_info, frag_shader_stage_create_info }; VkVertexInputBindingDescription binding_description = Vertex::getBindingDescription(); std::array<VkVertexInputAttributeDescription, 3> attribute_descriptions = Vertex::getAttributeDescriptions(); VkPipelineVertexInputStateCreateInfo vertex_input_info_create_info{}; vertex_input_info_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; vertex_input_info_create_info.vertexBindingDescriptionCount = 1; vertex_input_info_create_info.pVertexBindingDescriptions = &binding_description; vertex_input_info_create_info.vertexAttributeDescriptionCount = (uint32_t)attribute_descriptions.size(); vertex_input_info_create_info.pVertexAttributeDescriptions = attribute_descriptions.data(); VkPipelineInputAssemblyStateCreateInfo pipeline_input_assembly_state_create_info{}; pipeline_input_assembly_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; pipeline_input_assembly_state_create_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; pipeline_input_assembly_state_create_info.primitiveRestartEnable = VK_FALSE; VkViewport viewport{}; viewport.x = 0.0f; viewport.y = 0.0f; viewport.width = (float)(_window->getWidth()); viewport.height = (float)(_window->getHeight()); viewport.minDepth = 0.0f; viewport.maxDepth = 1.0f; VkRect2D scissor{}; scissor.offset = { 0, 0 }; scissor.extent.width = _window->getWidth(); scissor.extent.height = _window->getHeight(); VkPipelineViewportStateCreateInfo pipeline_viewport_state_create_info{}; pipeline_viewport_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; pipeline_viewport_state_create_info.viewportCount = 1; pipeline_viewport_state_create_info.pViewports = &viewport; pipeline_viewport_state_create_info.scissorCount = 1; pipeline_viewport_state_create_info.pScissors = &scissor; VkPipelineRasterizationStateCreateInfo rasterization_state_create_info{}; rasterization_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; rasterization_state_create_info.depthClampEnable = VK_FALSE; rasterization_state_create_info.rasterizerDiscardEnable = VK_FALSE; rasterization_state_create_info.polygonMode = VK_POLYGON_MODE_FILL; rasterization_state_create_info.lineWidth = 1.0f; rasterization_state_create_info.cullMode = VK_CULL_MODE_BACK_BIT; rasterization_state_create_info.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; rasterization_state_create_info.depthBiasEnable = VK_FALSE; rasterization_state_create_info.depthBiasConstantFactor = 0.0f; rasterization_state_create_info.depthBiasClamp = 0.0f; rasterization_state_create_info.depthBiasSlopeFactor = 0.0f; VkPipelineMultisampleStateCreateInfo pipeline_multisample_state_create_info{}; // Anti-Aliasing pipeline_multisample_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; pipeline_multisample_state_create_info.sampleShadingEnable = VK_FALSE; pipeline_multisample_state_create_info.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; pipeline_multisample_state_create_info.minSampleShading = 1.0f; pipeline_multisample_state_create_info.pSampleMask = nullptr; pipeline_multisample_state_create_info.alphaToCoverageEnable = VK_FALSE; pipeline_multisample_state_create_info.alphaToOneEnable = VK_FALSE; VkPipelineColorBlendAttachmentState pipeline_color_blend_attachment_state{}; pipeline_color_blend_attachment_state.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; pipeline_color_blend_attachment_state.blendEnable = VK_FALSE; pipeline_color_blend_attachment_state.srcColorBlendFactor = VK_BLEND_FACTOR_ONE; pipeline_color_blend_attachment_state.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO; pipeline_color_blend_attachment_state.colorBlendOp = VK_BLEND_OP_ADD; pipeline_color_blend_attachment_state.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; pipeline_color_blend_attachment_state.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; pipeline_color_blend_attachment_state.alphaBlendOp = VK_BLEND_OP_ADD; VkPipelineColorBlendStateCreateInfo pipeline_color_blend_state_create_info{}; pipeline_color_blend_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; pipeline_color_blend_state_create_info.logicOpEnable = VK_FALSE; pipeline_color_blend_state_create_info.logicOp = VK_LOGIC_OP_COPY; pipeline_color_blend_state_create_info.attachmentCount = 1; pipeline_color_blend_state_create_info.pAttachments = &pipeline_color_blend_attachment_state; pipeline_color_blend_state_create_info.blendConstants[0] = 0.0f; pipeline_color_blend_state_create_info.blendConstants[1] = 0.0f; pipeline_color_blend_state_create_info.blendConstants[2] = 0.0f; pipeline_color_blend_state_create_info.blendConstants[3] = 0.0f; VkPipelineDepthStencilStateCreateInfo depth_stencil{}; depth_stencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; depth_stencil.depthTestEnable = VK_TRUE; depth_stencil.depthWriteEnable = VK_TRUE; depth_stencil.depthCompareOp = VK_COMPARE_OP_LESS; depth_stencil.depthBoundsTestEnable = VK_FALSE; depth_stencil.minDepthBounds = 0.0f; depth_stencil.maxDepthBounds = 1.0f; depth_stencil.stencilTestEnable = VK_FALSE; depth_stencil.front = {}; depth_stencil.back = {}; VkDescriptorSetLayout descriptor_set_layouts[] = { _descriptor_set_layout }; VkPipelineLayoutCreateInfo pipeline_layout_create_info {}; pipeline_layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; pipeline_layout_create_info.setLayoutCount = 1; pipeline_layout_create_info.pSetLayouts = descriptor_set_layouts; pipeline_layout_create_info.pushConstantRangeCount = 0; pipeline_layout_create_info.pPushConstantRanges = 0; ErrorCheck(vkCreatePipelineLayout(_device, &pipeline_layout_create_info, nullptr, &_pipeline_layout)); VkGraphicsPipelineCreateInfo graphics_pipeline_create_info {}; graphics_pipeline_create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; graphics_pipeline_create_info.stageCount = 2; // Shader stages graphics_pipeline_create_info.pStages = shader_stages; graphics_pipeline_create_info.pVertexInputState = &vertex_input_info_create_info; graphics_pipeline_create_info.pInputAssemblyState = &pipeline_input_assembly_state_create_info; graphics_pipeline_create_info.pViewportState = &pipeline_viewport_state_create_info; graphics_pipeline_create_info.pRasterizationState = &rasterization_state_create_info; graphics_pipeline_create_info.pMultisampleState = &pipeline_multisample_state_create_info; graphics_pipeline_create_info.pDepthStencilState = &depth_stencil; graphics_pipeline_create_info.pColorBlendState = &pipeline_color_blend_state_create_info; graphics_pipeline_create_info.pDynamicState = nullptr; graphics_pipeline_create_info.layout = _pipeline_layout; graphics_pipeline_create_info.renderPass = _render_pass; graphics_pipeline_create_info.subpass = 0; graphics_pipeline_create_info.basePipelineHandle = VK_NULL_HANDLE; graphics_pipeline_create_info.basePipelineIndex = -1; ErrorCheck(vkCreateGraphicsPipelines(_device, VK_NULL_HANDLE, 1, &graphics_pipeline_create_info, nullptr, &_graphics_pipeline)); }
int sample_main(int argc, char *argv[]) { VkResult U_ASSERT_ONLY res; struct sample_info info = {}; char sample_title[] = "Graphics Pipeline Sample"; const bool depthPresent = true; init_global_layer_properties(info); init_instance_extension_names(info); init_device_extension_names(info); init_instance(info, sample_title); init_enumerate_device(info); init_window_size(info, 500, 500); init_connection(info); init_window(info); init_swapchain_extension(info); init_device(info); init_command_pool(info); init_command_buffer(info); execute_begin_command_buffer(info); init_device_queue(info); init_swap_chain(info); init_depth_buffer(info); init_uniform_buffer(info); init_renderpass(info, depthPresent); init_framebuffers(info, depthPresent); init_vertex_buffer(info, g_vb_solid_face_colors_Data, sizeof(g_vb_solid_face_colors_Data), sizeof(g_vb_solid_face_colors_Data[0]), false); init_descriptor_and_pipeline_layouts(info, false); init_descriptor_pool(info, false); init_descriptor_set(info, false); init_shaders(info, vertShaderText, fragShaderText); /* VULKAN_KEY_START */ VkDynamicState dynamicStateEnables[VK_DYNAMIC_STATE_RANGE_SIZE]; VkPipelineDynamicStateCreateInfo dynamicState = {}; memset(dynamicStateEnables, 0, sizeof dynamicStateEnables); dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; dynamicState.pNext = NULL; dynamicState.pDynamicStates = dynamicStateEnables; dynamicState.dynamicStateCount = 0; VkPipelineVertexInputStateCreateInfo vi; vi.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; vi.pNext = NULL; vi.flags = 0; vi.vertexBindingDescriptionCount = 1; vi.pVertexBindingDescriptions = &info.vi_binding; vi.vertexAttributeDescriptionCount = 2; vi.pVertexAttributeDescriptions = info.vi_attribs; VkPipelineInputAssemblyStateCreateInfo ia; ia.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; ia.pNext = NULL; ia.flags = 0; ia.primitiveRestartEnable = VK_FALSE; ia.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; VkPipelineRasterizationStateCreateInfo rs; rs.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; rs.pNext = NULL; rs.flags = 0; rs.polygonMode = VK_POLYGON_MODE_FILL; rs.cullMode = VK_CULL_MODE_BACK_BIT; rs.frontFace = VK_FRONT_FACE_CLOCKWISE; rs.depthClampEnable = VK_FALSE; rs.rasterizerDiscardEnable = VK_FALSE; rs.depthBiasEnable = VK_FALSE; rs.depthBiasConstantFactor = 0; rs.depthBiasClamp = 0; rs.depthBiasSlopeFactor = 0; rs.lineWidth = 1.0f; VkPipelineColorBlendStateCreateInfo cb; cb.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; cb.pNext = NULL; cb.flags = 0; VkPipelineColorBlendAttachmentState att_state[1]; att_state[0].colorWriteMask = 0xf; att_state[0].blendEnable = VK_FALSE; att_state[0].alphaBlendOp = VK_BLEND_OP_ADD; att_state[0].colorBlendOp = VK_BLEND_OP_ADD; att_state[0].srcColorBlendFactor = VK_BLEND_FACTOR_ZERO; att_state[0].dstColorBlendFactor = VK_BLEND_FACTOR_ZERO; att_state[0].srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; att_state[0].dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; cb.attachmentCount = 1; cb.pAttachments = att_state; cb.logicOpEnable = VK_FALSE; cb.logicOp = VK_LOGIC_OP_NO_OP; cb.blendConstants[0] = 1.0f; cb.blendConstants[1] = 1.0f; cb.blendConstants[2] = 1.0f; cb.blendConstants[3] = 1.0f; VkPipelineViewportStateCreateInfo vp = {}; vp.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; vp.pNext = NULL; vp.flags = 0; vp.viewportCount = NUM_VIEWPORTS; dynamicStateEnables[dynamicState.dynamicStateCount++] = VK_DYNAMIC_STATE_VIEWPORT; vp.scissorCount = NUM_SCISSORS; dynamicStateEnables[dynamicState.dynamicStateCount++] = VK_DYNAMIC_STATE_SCISSOR; vp.pScissors = NULL; vp.pViewports = NULL; VkPipelineDepthStencilStateCreateInfo ds; ds.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; ds.pNext = NULL; ds.flags = 0; ds.depthTestEnable = VK_TRUE; ds.depthWriteEnable = VK_TRUE; ds.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL; ds.depthBoundsTestEnable = VK_FALSE; ds.minDepthBounds = 0; ds.maxDepthBounds = 0; ds.stencilTestEnable = VK_FALSE; ds.back.failOp = VK_STENCIL_OP_KEEP; ds.back.passOp = VK_STENCIL_OP_KEEP; ds.back.compareOp = VK_COMPARE_OP_ALWAYS; ds.back.compareMask = 0; ds.back.reference = 0; ds.back.depthFailOp = VK_STENCIL_OP_KEEP; ds.back.writeMask = 0; ds.front = ds.back; VkPipelineMultisampleStateCreateInfo ms; ms.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; ms.pNext = NULL; ms.flags = 0; ms.pSampleMask = NULL; ms.rasterizationSamples = NUM_SAMPLES; ms.sampleShadingEnable = VK_FALSE; ms.alphaToCoverageEnable = VK_FALSE; ms.alphaToOneEnable = VK_FALSE; ms.minSampleShading = 0.0; VkGraphicsPipelineCreateInfo pipeline; pipeline.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; pipeline.pNext = NULL; pipeline.layout = info.pipeline_layout; pipeline.basePipelineHandle = VK_NULL_HANDLE; pipeline.basePipelineIndex = 0; pipeline.flags = 0; pipeline.pVertexInputState = &vi; pipeline.pInputAssemblyState = &ia; pipeline.pRasterizationState = &rs; pipeline.pColorBlendState = &cb; pipeline.pTessellationState = NULL; pipeline.pMultisampleState = &ms; pipeline.pDynamicState = &dynamicState; pipeline.pViewportState = &vp; pipeline.pDepthStencilState = &ds; pipeline.pStages = info.shaderStages; pipeline.stageCount = 2; pipeline.renderPass = info.render_pass; pipeline.subpass = 0; res = vkCreateGraphicsPipelines(info.device, VK_NULL_HANDLE, 1, &pipeline, NULL, &info.pipeline); assert(res == VK_SUCCESS); execute_end_command_buffer(info); execute_queue_command_buffer(info); /* VULKAN_KEY_END */ vkDestroyPipeline(info.device, info.pipeline, NULL); destroy_descriptor_pool(info); destroy_vertex_buffer(info); destroy_framebuffers(info); destroy_shaders(info); destroy_renderpass(info); destroy_descriptor_and_pipeline_layouts(info); destroy_uniform_buffer(info); destroy_depth_buffer(info); destroy_swap_chain(info); destroy_command_buffer(info); destroy_command_pool(info); destroy_device(info); destroy_window(info); destroy_instance(info); return 0; }
VkPipeline Vulkan2D::GetPipeline(VkPipelineCache cache, VkRenderPass rp, VkShaderModule vs, VkShaderModule fs) { PipelineKey key; key.vs = vs; key.fs = fs; auto iter = pipelines_.find(key); if (iter != pipelines_.end()) { return iter->second; } VkPipelineColorBlendAttachmentState blend0 = {}; blend0.blendEnable = false; blend0.colorWriteMask = 0xF; VkPipelineColorBlendStateCreateInfo cbs = { VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO }; cbs.pAttachments = &blend0; cbs.attachmentCount = 1; cbs.logicOpEnable = false; VkPipelineDepthStencilStateCreateInfo dss = { VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO }; dss.depthBoundsTestEnable = false; dss.stencilTestEnable = false; dss.depthTestEnable = false; VkDynamicState dynamicStates[2]; int numDyn = 0; dynamicStates[numDyn++] = VK_DYNAMIC_STATE_SCISSOR; dynamicStates[numDyn++] = VK_DYNAMIC_STATE_VIEWPORT; VkPipelineDynamicStateCreateInfo ds = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; ds.pDynamicStates = dynamicStates; ds.dynamicStateCount = numDyn; VkPipelineRasterizationStateCreateInfo rs = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO }; rs.lineWidth = 1.0f; VkPipelineMultisampleStateCreateInfo ms = { VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO }; ms.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; VkPipelineShaderStageCreateInfo ss[2] = {}; ss[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; ss[0].stage = VK_SHADER_STAGE_VERTEX_BIT; ss[0].module = vs; ss[0].pName = "main"; ss[0].flags = 0; ss[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; ss[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT; ss[1].module = fs; ss[1].pName = "main"; ss[1].flags = 0; VkPipelineInputAssemblyStateCreateInfo inputAssembly = { VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO }; inputAssembly.flags = 0; inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; inputAssembly.primitiveRestartEnable = true; VkVertexInputAttributeDescription attrs[2]; int attributeCount = 2; attrs[0].binding = 0; attrs[0].format = VK_FORMAT_R32G32B32_SFLOAT; attrs[0].location = 0; attrs[0].offset = 0; attrs[1].binding = 0; attrs[1].format = VK_FORMAT_R32G32_SFLOAT; attrs[1].location = 1; attrs[1].offset = 12; int vertexStride = 12 + 8; VkVertexInputBindingDescription ibd = {}; ibd.binding = 0; ibd.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; ibd.stride = vertexStride; VkPipelineVertexInputStateCreateInfo vis = { VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO }; vis.vertexBindingDescriptionCount = 1; vis.pVertexBindingDescriptions = &ibd; vis.vertexAttributeDescriptionCount = attributeCount; vis.pVertexAttributeDescriptions = attrs; VkPipelineViewportStateCreateInfo views = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO }; views.viewportCount = 1; views.scissorCount = 1; views.pViewports = nullptr; // dynamic views.pScissors = nullptr; // dynamic VkGraphicsPipelineCreateInfo pipe = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO }; pipe.flags = 0; pipe.stageCount = 2; pipe.pStages = ss; pipe.basePipelineIndex = 0; pipe.pColorBlendState = &cbs; pipe.pDepthStencilState = &dss; pipe.pRasterizationState = &rs; // We will use dynamic viewport state. pipe.pVertexInputState = &vis; pipe.pViewportState = &views; pipe.pTessellationState = nullptr; pipe.pDynamicState = &ds; pipe.pInputAssemblyState = &inputAssembly; pipe.pMultisampleState = &ms; pipe.layout = pipelineLayout_; pipe.basePipelineHandle = VK_NULL_HANDLE; pipe.basePipelineIndex = 0; pipe.renderPass = rp; pipe.subpass = 0; VkPipeline pipeline; VkResult result = vkCreateGraphicsPipelines(vulkan_->GetDevice(), cache, 1, &pipe, nullptr, &pipeline); if (result == VK_SUCCESS) { pipelines_[key] = pipeline; return pipeline; } else { return VK_NULL_HANDLE; } }
/** * Sample using multiple render passes per framebuffer (different x,y extents) * and multiple subpasses per renderpass. */ int sample_main(int argc, char *argv[]) { VkResult U_ASSERT_ONLY res; struct sample_info info = {}; char sample_title[] = "Multi-pass render passes"; const bool depthPresent = true; process_command_line_args(info, argc, argv); init_global_layer_properties(info); init_instance_extension_names(info); init_device_extension_names(info); init_instance(info, sample_title); init_enumerate_device(info); init_window_size(info, 500, 500); init_connection(info); init_window(info); init_swapchain_extension(info); init_device(info); init_command_pool(info); init_command_buffer(info); execute_begin_command_buffer(info); init_device_queue(info); init_swap_chain(info); info.depth.format = VK_FORMAT_D32_SFLOAT_S8_UINT; init_depth_buffer(info); init_uniform_buffer(info); init_descriptor_and_pipeline_layouts(info, false); init_vertex_buffer(info, g_vb_solid_face_colors_Data, sizeof(g_vb_solid_face_colors_Data), sizeof(g_vb_solid_face_colors_Data[0]), false); init_descriptor_pool(info, false); init_descriptor_set(info, false); init_pipeline_cache(info); /* VULKAN_KEY_START */ /** * First renderpass in this sample. * Stenciled rendering: subpass 1 draw to stencil buffer, subpass 2 draw to * color buffer with stencil test */ VkAttachmentDescription attachments[2]; attachments[0].format = info.format; attachments[0].samples = VK_SAMPLE_COUNT_1_BIT; attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE; attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; attachments[0].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; attachments[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; attachments[0].flags = 0; attachments[1].format = info.depth.format; attachments[1].samples = VK_SAMPLE_COUNT_1_BIT; attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE; attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; attachments[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; attachments[1].initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; attachments[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; attachments[1].flags = 0; VkAttachmentReference color_reference = {}; color_reference.attachment = 0; color_reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; VkAttachmentReference depth_reference = {}; depth_reference.attachment = 1; depth_reference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; VkSubpassDescription subpass = {}; subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; subpass.flags = 0; subpass.inputAttachmentCount = 0; subpass.pInputAttachments = NULL; subpass.colorAttachmentCount = 0; subpass.pColorAttachments = NULL; subpass.pResolveAttachments = NULL; subpass.pDepthStencilAttachment = &depth_reference; subpass.preserveAttachmentCount = 0; subpass.pPreserveAttachments = NULL; std::vector<VkSubpassDescription> subpasses; /* first a depthstencil-only subpass */ subpasses.push_back(subpass); subpass.colorAttachmentCount = 1; subpass.pColorAttachments = &color_reference; /* then depthstencil and color */ subpasses.push_back(subpass); /* Set up a dependency between the source and destination subpasses */ VkSubpassDependency dependency = {}; dependency.srcSubpass = 0; dependency.dstSubpass = 1; dependency.dependencyFlags = 0; dependency.srcStageMask = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT; dependency.dstStageMask = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT; dependency.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; dependency.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; VkRenderPassCreateInfo rp_info = {}; rp_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; rp_info.pNext = NULL; rp_info.attachmentCount = 2; rp_info.pAttachments = attachments; rp_info.subpassCount = subpasses.size(); rp_info.pSubpasses = subpasses.data(); rp_info.dependencyCount = 1; rp_info.pDependencies = &dependency; VkRenderPass stencil_render_pass; res = vkCreateRenderPass(info.device, &rp_info, NULL, &stencil_render_pass); assert(!res); /* now that we have the render pass, create framebuffer and pipelines */ info.render_pass = stencil_render_pass; init_framebuffers(info, depthPresent); VkDynamicState dynamicStateEnables[VK_DYNAMIC_STATE_RANGE_SIZE]; VkPipelineDynamicStateCreateInfo dynamicState = {}; memset(dynamicStateEnables, 0, sizeof dynamicStateEnables); dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; dynamicState.pNext = NULL; dynamicState.pDynamicStates = dynamicStateEnables; dynamicState.dynamicStateCount = 0; VkPipelineVertexInputStateCreateInfo vi; vi.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; vi.pNext = NULL; vi.vertexBindingDescriptionCount = 1; vi.pVertexBindingDescriptions = &info.vi_binding; vi.vertexAttributeDescriptionCount = 2; vi.pVertexAttributeDescriptions = info.vi_attribs; VkPipelineInputAssemblyStateCreateInfo ia; ia.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; ia.pNext = NULL; ia.primitiveRestartEnable = VK_FALSE; ia.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; VkPipelineRasterizationStateCreateInfo rs; rs.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; rs.pNext = NULL; rs.polygonMode = VK_POLYGON_MODE_FILL; rs.cullMode = VK_CULL_MODE_BACK_BIT; rs.frontFace = VK_FRONT_FACE_CLOCKWISE; rs.depthClampEnable = VK_FALSE; rs.rasterizerDiscardEnable = VK_FALSE; rs.depthBiasEnable = VK_FALSE; rs.depthBiasConstantFactor = 0; rs.depthBiasClamp = 0; rs.depthBiasSlopeFactor = 0; rs.lineWidth = 0; VkPipelineColorBlendStateCreateInfo cb; cb.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; cb.pNext = NULL; VkPipelineColorBlendAttachmentState att_state[1]; att_state[0].colorWriteMask = 0xf; att_state[0].blendEnable = VK_FALSE; att_state[0].alphaBlendOp = VK_BLEND_OP_ADD; att_state[0].colorBlendOp = VK_BLEND_OP_ADD; att_state[0].srcColorBlendFactor = VK_BLEND_FACTOR_ZERO; att_state[0].dstColorBlendFactor = VK_BLEND_FACTOR_ZERO; att_state[0].srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; att_state[0].dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; cb.attachmentCount = 1; cb.pAttachments = att_state; cb.logicOpEnable = VK_FALSE; cb.logicOp = VK_LOGIC_OP_NO_OP; cb.blendConstants[0] = 1.0f; cb.blendConstants[1] = 1.0f; cb.blendConstants[2] = 1.0f; cb.blendConstants[3] = 1.0f; VkPipelineViewportStateCreateInfo vp = {}; vp.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; vp.pNext = NULL; vp.viewportCount = NUM_VIEWPORTS; dynamicStateEnables[dynamicState.dynamicStateCount++] = VK_DYNAMIC_STATE_VIEWPORT; vp.scissorCount = NUM_SCISSORS; dynamicStateEnables[dynamicState.dynamicStateCount++] = VK_DYNAMIC_STATE_SCISSOR; VkPipelineDepthStencilStateCreateInfo ds; ds.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; ds.pNext = NULL; ds.depthTestEnable = VK_TRUE; ds.depthWriteEnable = VK_TRUE; ds.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL; ds.depthBoundsTestEnable = VK_FALSE; ds.minDepthBounds = 0; ds.maxDepthBounds = 0; ds.stencilTestEnable = VK_TRUE; ds.back.failOp = VK_STENCIL_OP_REPLACE; ds.back.depthFailOp = VK_STENCIL_OP_REPLACE; ds.back.passOp = VK_STENCIL_OP_REPLACE; ds.back.compareOp = VK_COMPARE_OP_ALWAYS; ds.back.compareMask = 0xff; ds.back.writeMask = 0xff; ds.back.reference = 0x44; ds.front = ds.back; VkPipelineMultisampleStateCreateInfo ms; ms.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; ms.pNext = NULL; ms.pSampleMask = NULL; ms.rasterizationSamples = NUM_SAMPLES; ms.sampleShadingEnable = VK_FALSE; ms.minSampleShading = 0.0; ms.alphaToCoverageEnable = VK_FALSE; ms.alphaToOneEnable = VK_FALSE; VkGraphicsPipelineCreateInfo pipeline; pipeline.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; pipeline.pNext = NULL; pipeline.layout = info.pipeline_layout; pipeline.basePipelineHandle = VK_NULL_HANDLE; pipeline.basePipelineIndex = 0; pipeline.flags = 0; pipeline.pVertexInputState = &vi; pipeline.pInputAssemblyState = &ia; pipeline.pRasterizationState = &rs; pipeline.pColorBlendState = NULL; pipeline.pTessellationState = NULL; pipeline.pMultisampleState = &ms; pipeline.pDynamicState = &dynamicState; pipeline.pViewportState = &vp; pipeline.pDepthStencilState = &ds; pipeline.pStages = info.shaderStages; pipeline.stageCount = 2; pipeline.renderPass = stencil_render_pass; pipeline.subpass = 0; init_shaders(info, normalVertShaderText, fragShaderText); /* The first pipeline will render in subpass 0 to fill the stencil */ pipeline.subpass = 0; VkPipeline stencil_cube_pipe = VK_NULL_HANDLE; res = vkCreateGraphicsPipelines(info.device, info.pipelineCache, 1, &pipeline, NULL, &stencil_cube_pipe); assert(res == VK_SUCCESS); /* destroy the shaders used for the above pipelin eand replace them with those for the fullscreen fill pass */ destroy_shaders(info); init_shaders(info, fullscreenVertShaderText, fragShaderText); /* the second pipeline will stencil test but not write, using the same * reference */ ds.back.failOp = VK_STENCIL_OP_KEEP; ds.back.depthFailOp = VK_STENCIL_OP_KEEP; ds.back.passOp = VK_STENCIL_OP_KEEP; ds.back.compareOp = VK_COMPARE_OP_EQUAL; ds.front = ds.back; /* don't test depth, only use stencil test */ ds.depthTestEnable = VK_FALSE; /* the second pipeline will be a fullscreen triangle strip, with vertices generated purely from the vertex shader - no inputs needed */ ia.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; vi.vertexAttributeDescriptionCount = 0; vi.vertexBindingDescriptionCount = 0; /* this pipeline will run in the second subpass */ pipeline.subpass = 1; pipeline.pColorBlendState = &cb; VkPipeline stencil_fullscreen_pipe = VK_NULL_HANDLE; res = vkCreateGraphicsPipelines(info.device, info.pipelineCache, 1, &pipeline, NULL, &stencil_fullscreen_pipe); assert(res == VK_SUCCESS); destroy_shaders(info); info.pipeline = VK_NULL_HANDLE; VkClearValue clear_values[2]; clear_values[0].color.float32[0] = 0.2f; clear_values[0].color.float32[1] = 0.2f; clear_values[0].color.float32[2] = 0.2f; clear_values[0].color.float32[3] = 0.2f; clear_values[1].depthStencil.depth = 1.0f; clear_values[1].depthStencil.stencil = 0; VkSemaphore presentCompleteSemaphore; VkSemaphoreCreateInfo presentCompleteSemaphoreCreateInfo; presentCompleteSemaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; presentCompleteSemaphoreCreateInfo.pNext = NULL; presentCompleteSemaphoreCreateInfo.flags = 0; res = vkCreateSemaphore(info.device, &presentCompleteSemaphoreCreateInfo, NULL, &presentCompleteSemaphore); assert(res == VK_SUCCESS); // Get the index of the next available swapchain image: res = vkAcquireNextImageKHR(info.device, info.swap_chain, UINT64_MAX, presentCompleteSemaphore, NULL, &info.current_buffer); // TODO: Deal with the VK_SUBOPTIMAL_KHR and VK_ERROR_OUT_OF_DATE_KHR // return codes assert(res == VK_SUCCESS); VkRenderPassBeginInfo rp_begin; rp_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; rp_begin.pNext = NULL; rp_begin.renderPass = stencil_render_pass; rp_begin.framebuffer = info.framebuffers[info.current_buffer]; rp_begin.renderArea.offset.x = 0; rp_begin.renderArea.offset.y = 0; rp_begin.renderArea.extent.width = info.width / 2; rp_begin.renderArea.extent.height = info.height; rp_begin.clearValueCount = 2; rp_begin.pClearValues = clear_values; /* Begin the first render pass. This will render in the left half of the screen. Subpass 0 will render a cube, stencil writing but outputting no color. Subpass 1 will render a fullscreen pass, stencil testing and outputting color only where the cube filled in stencil */ vkCmdBeginRenderPass(info.cmd, &rp_begin, VK_SUBPASS_CONTENTS_INLINE); vkCmdBindPipeline(info.cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, stencil_cube_pipe); vkCmdBindDescriptorSets(info.cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, info.pipeline_layout, 0, NUM_DESCRIPTOR_SETS, info.desc_set.data(), 0, NULL); const VkDeviceSize offsets[1] = {0}; vkCmdBindVertexBuffers(info.cmd, 0, 1, &info.vertex_buffer.buf, offsets); VkViewport viewport; viewport.height = (float)info.height; viewport.width = (float)info.width / 2; viewport.minDepth = (float)0.0f; viewport.maxDepth = (float)1.0f; viewport.x = 0; viewport.y = 0; vkCmdSetViewport(info.cmd, 0, NUM_VIEWPORTS, &viewport); VkRect2D scissor; scissor.extent.width = info.width / 2; scissor.extent.height = info.height; scissor.offset.x = 0; scissor.offset.y = 0; vkCmdSetScissor(info.cmd, 0, NUM_SCISSORS, &scissor); /* Draw the cube into stencil */ vkCmdDraw(info.cmd, 12 * 3, 1, 0, 0); /* Advance to the next subpass */ vkCmdNextSubpass(info.cmd, VK_SUBPASS_CONTENTS_INLINE); /* Bind the fullscreen pass pipeline */ vkCmdBindPipeline(info.cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, stencil_fullscreen_pipe); vkCmdSetViewport(info.cmd, 0, NUM_VIEWPORTS, &viewport); vkCmdSetScissor(info.cmd, 0, NUM_SCISSORS, &scissor); /* Draw the fullscreen pass */ vkCmdDraw(info.cmd, 4, 1, 0, 0); vkCmdEndRenderPass(info.cmd); /** * Second renderpass in this sample. * Blended rendering, each subpass blends continuously onto the color */ /* note that we reuse a lot of the initialisation strutures from the first render pass, so this represents a 'delta' from that configuration */ /* This time, the first subpass will use color */ subpasses[0].colorAttachmentCount = 1; subpasses[0].pColorAttachments = &color_reference; /* The dependency between the subpasses now includes the color attachment */ dependency.srcAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT; dependency.dstAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT; /* Otherwise, the render pass is identical */ VkRenderPass blend_render_pass; res = vkCreateRenderPass(info.device, &rp_info, NULL, &blend_render_pass); assert(!res); pipeline.renderPass = blend_render_pass; /* We must recreate the framebuffers with this renderpass as the two render passes are not compatible. Store the current framebuffers for later deletion */ VkFramebuffer *stencil_framebuffers = info.framebuffers; info.framebuffers = NULL; info.render_pass = blend_render_pass; init_framebuffers(info, depthPresent); /* Now create the pipelines for the second render pass */ /* We are rendering the cube again, configure the vertex inputs */ ia.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; vi.vertexAttributeDescriptionCount = 2; vi.vertexBindingDescriptionCount = 1; /* The first pipeline will depth write and depth test */ ds.depthWriteEnable = VK_TRUE; ds.depthTestEnable = VK_TRUE; /* We don't want to stencil test */ ds.stencilTestEnable = VK_FALSE; /* This time, both pipelines will blend. the first pipeline uses the blend constant to determine the blend amount */ att_state[0].colorWriteMask = 0xf; att_state[0].blendEnable = VK_TRUE; att_state[0].alphaBlendOp = VK_BLEND_OP_ADD; att_state[0].colorBlendOp = VK_BLEND_OP_ADD; att_state[0].srcColorBlendFactor = VK_BLEND_FACTOR_CONSTANT_ALPHA; att_state[0].dstColorBlendFactor = VK_BLEND_FACTOR_ONE; att_state[0].srcColorBlendFactor = VK_BLEND_FACTOR_CONSTANT_ALPHA; att_state[0].srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; cb.blendConstants[0] = 1.0f; cb.blendConstants[1] = 1.0f; cb.blendConstants[2] = 1.0f; cb.blendConstants[3] = 0.3f; init_shaders(info, normalVertShaderText, fragShaderText); /* This is the first subpass's pipeline, to blend a cube onto the color * image */ pipeline.subpass = 0; VkPipeline blend_cube_pipe = VK_NULL_HANDLE; res = vkCreateGraphicsPipelines(info.device, info.pipelineCache, 1, &pipeline, NULL, &blend_cube_pipe); assert(res == VK_SUCCESS); /* Now we will set up the fullscreen pass to render on top. */ destroy_shaders(info); init_shaders(info, fullscreenVertShaderText, fragShaderText); /* the second pipeline will be a fullscreen triangle strip with no inputs */ ia.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; vi.vertexAttributeDescriptionCount = 0; vi.vertexBindingDescriptionCount = 0; /* We'll use the alpha output from the shader */ att_state[0].srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; att_state[0].dstColorBlendFactor = VK_BLEND_FACTOR_ONE; att_state[0].srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; att_state[0].dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE; /* This renders in the second subpass */ pipeline.subpass = 1; VkPipeline blend_fullscreen_pipe = VK_NULL_HANDLE; res = vkCreateGraphicsPipelines(info.device, info.pipelineCache, 1, &pipeline, NULL, &blend_fullscreen_pipe); assert(res == VK_SUCCESS); destroy_shaders(info); info.pipeline = VK_NULL_HANDLE; /* Now we are going to render in the right half of the screen */ viewport.x = (float)info.width / 2; scissor.offset.x = info.width / 2; rp_begin.renderArea.offset.x = info.width / 2; /* Use our framebuffer and render pass */ rp_begin.framebuffer = info.framebuffers[info.current_buffer]; rp_begin.renderPass = blend_render_pass; vkCmdBeginRenderPass(info.cmd, &rp_begin, VK_SUBPASS_CONTENTS_INLINE); vkCmdBindPipeline(info.cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, blend_cube_pipe); vkCmdBindDescriptorSets(info.cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, info.pipeline_layout, 0, NUM_DESCRIPTOR_SETS, info.desc_set.data(), 0, NULL); vkCmdBindVertexBuffers(info.cmd, 0, 1, &info.vertex_buffer.buf, offsets); vkCmdSetViewport(info.cmd, 0, NUM_VIEWPORTS, &viewport); vkCmdSetScissor(info.cmd, 0, NUM_SCISSORS, &scissor); /* Draw the cube blending */ vkCmdDraw(info.cmd, 12 * 3, 1, 0, 0); /* Advance to the next subpass */ vkCmdNextSubpass(info.cmd, VK_SUBPASS_CONTENTS_INLINE); vkCmdBindPipeline(info.cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, blend_fullscreen_pipe); vkCmdBindDescriptorSets(info.cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, info.pipeline_layout, 0, NUM_DESCRIPTOR_SETS, info.desc_set.data(), 0, NULL); /* Adjust the viewport to be a square in the centre, just overlapping the * cube */ viewport.x += 25.0f; viewport.y += 150.0f; viewport.width -= 50.0f; viewport.height -= 300.0f; vkCmdSetViewport(info.cmd, 0, NUM_VIEWPORTS, &viewport); vkCmdSetScissor(info.cmd, 0, NUM_SCISSORS, &scissor); vkCmdDraw(info.cmd, 4, 1, 0, 0); /* The second renderpass is complete */ vkCmdEndRenderPass(info.cmd); /* VULKAN_KEY_END */ VkImageMemoryBarrier prePresentBarrier = {}; prePresentBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; prePresentBarrier.pNext = NULL; prePresentBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; prePresentBarrier.dstAccessMask = 0; prePresentBarrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; prePresentBarrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; prePresentBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; prePresentBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; prePresentBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; prePresentBarrier.subresourceRange.baseMipLevel = 0; prePresentBarrier.subresourceRange.levelCount = 1; prePresentBarrier.subresourceRange.baseArrayLayer = 0; prePresentBarrier.subresourceRange.layerCount = 1; prePresentBarrier.image = info.buffers[info.current_buffer].image; vkCmdPipelineBarrier(info.cmd, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, NULL, 0, NULL, 1, &prePresentBarrier); res = vkEndCommandBuffer(info.cmd); const VkCommandBuffer cmd_bufs[] = {info.cmd}; VkFenceCreateInfo fenceInfo; VkFence drawFence; fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; fenceInfo.pNext = NULL; fenceInfo.flags = 0; vkCreateFence(info.device, &fenceInfo, NULL, &drawFence); VkPipelineStageFlags pipe_stage_flags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; VkSubmitInfo submit_info[1] = {}; submit_info[0].pNext = NULL; submit_info[0].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; submit_info[0].waitSemaphoreCount = 1; submit_info[0].pWaitSemaphores = &presentCompleteSemaphore; submit_info[0].commandBufferCount = 1; submit_info[0].pCommandBuffers = cmd_bufs; submit_info[0].pWaitDstStageMask = &pipe_stage_flags; submit_info[0].signalSemaphoreCount = 0; submit_info[0].pSignalSemaphores = NULL; /* Queue the command buffer for execution */ res = vkQueueSubmit(info.queue, 1, submit_info, drawFence); assert(res == VK_SUCCESS); /* Now present the image in the window */ VkPresentInfoKHR present; present.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; present.pNext = NULL; present.swapchainCount = 1; present.pSwapchains = &info.swap_chain; present.pImageIndices = &info.current_buffer; present.pWaitSemaphores = NULL; present.waitSemaphoreCount = 0; present.pResults = NULL; /* Make sure command buffer is finished before presenting */ do { res = vkWaitForFences(info.device, 1, &drawFence, VK_TRUE, FENCE_TIMEOUT); } while (res == VK_TIMEOUT); assert(res == VK_SUCCESS); res = vkQueuePresentKHR(info.queue, &present); assert(res == VK_SUCCESS); wait_seconds(1); /* VULKAN_KEY_END */ if (info.save_images) write_ppm(info, "drawsubpasses"); for (uint32_t i = 0; i < info.swapchainImageCount; i++) vkDestroyFramebuffer(info.device, stencil_framebuffers[i], NULL); free(stencil_framebuffers); vkDestroyRenderPass(info.device, stencil_render_pass, NULL); vkDestroyRenderPass(info.device, blend_render_pass, NULL); vkDestroyPipeline(info.device, blend_cube_pipe, NULL); vkDestroyPipeline(info.device, blend_fullscreen_pipe, NULL); vkDestroyPipeline(info.device, stencil_cube_pipe, NULL); vkDestroyPipeline(info.device, stencil_fullscreen_pipe, NULL); vkDestroySemaphore(info.device, presentCompleteSemaphore, NULL); vkDestroyFence(info.device, drawFence, NULL); destroy_pipeline_cache(info); destroy_descriptor_pool(info); destroy_vertex_buffer(info); destroy_framebuffers(info); destroy_descriptor_and_pipeline_layouts(info); destroy_uniform_buffer(info); destroy_depth_buffer(info); destroy_swap_chain(info); destroy_command_buffer(info); destroy_command_pool(info); destroy_device(info); destroy_window(info); destroy_instance(info); return 0; }
void preparePipelines() { VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = vks::initializers::pipelineInputAssemblyStateCreateInfo(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0, VK_FALSE); VkPipelineRasterizationStateCreateInfo rasterizationState = vks::initializers::pipelineRasterizationStateCreateInfo(VK_POLYGON_MODE_FILL, VK_CULL_MODE_NONE, VK_FRONT_FACE_COUNTER_CLOCKWISE); VkPipelineColorBlendAttachmentState blendAttachmentState = vks::initializers::pipelineColorBlendAttachmentState(0xf, VK_FALSE); VkPipelineColorBlendStateCreateInfo colorBlendState = vks::initializers::pipelineColorBlendStateCreateInfo(1, &blendAttachmentState); VkPipelineDepthStencilStateCreateInfo depthStencilState = vks::initializers::pipelineDepthStencilStateCreateInfo(VK_TRUE, VK_TRUE, VK_COMPARE_OP_LESS_OR_EQUAL); VkPipelineViewportStateCreateInfo viewportState = vks::initializers::pipelineViewportStateCreateInfo(1, 1, 0); VkPipelineMultisampleStateCreateInfo multisampleState = vks::initializers::pipelineMultisampleStateCreateInfo(VK_SAMPLE_COUNT_1_BIT); std::vector<VkDynamicState> dynamicStateEnables = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; VkPipelineDynamicStateCreateInfo dynamicState = vks::initializers::pipelineDynamicStateCreateInfo(dynamicStateEnables); // Load shaders std::array<VkPipelineShaderStageCreateInfo, 2> shaderStages; VkGraphicsPipelineCreateInfo pipelineCreateInfo = vks::initializers::pipelineCreateInfo(pipelineLayout, renderPass); pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState; pipelineCreateInfo.pRasterizationState = &rasterizationState; pipelineCreateInfo.pColorBlendState = &colorBlendState; pipelineCreateInfo.pMultisampleState = &multisampleState; pipelineCreateInfo.pViewportState = &viewportState; pipelineCreateInfo.pDepthStencilState = &depthStencilState; pipelineCreateInfo.pDynamicState = &dynamicState; pipelineCreateInfo.stageCount = static_cast<uint32_t>(shaderStages.size()); pipelineCreateInfo.pStages = shaderStages.data(); // Vertex bindings an attributes std::vector<VkVertexInputBindingDescription> vertexInputBindings = { vks::initializers::vertexInputBindingDescription(0, vertexLayout.stride(), VK_VERTEX_INPUT_RATE_VERTEX), }; std::vector<VkVertexInputAttributeDescription> vertexInputAttributes = { vks::initializers::vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 0, VK_FORMAT_R32G32B32_SFLOAT, 0), // Location 0: Position vks::initializers::vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 1, VK_FORMAT_R32G32_SFLOAT, sizeof(float) * 3), // Location 1: Texture coordinates vks::initializers::vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 2, VK_FORMAT_R32G32B32_SFLOAT, sizeof(float) * 5), // Location 2: Normal vks::initializers::vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 3, VK_FORMAT_R32G32B32_SFLOAT, sizeof(float) * 8), // Location 3: Tangent vks::initializers::vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 4, VK_FORMAT_R32G32B32_SFLOAT, sizeof(float) * 11), // Location 4: Bitangent }; VkPipelineVertexInputStateCreateInfo vertexInputState = vks::initializers::pipelineVertexInputStateCreateInfo(); vertexInputState.vertexBindingDescriptionCount = static_cast<uint32_t>(vertexInputBindings.size()); vertexInputState.pVertexBindingDescriptions = vertexInputBindings.data(); vertexInputState.vertexAttributeDescriptionCount = static_cast<uint32_t>(vertexInputAttributes.size()); vertexInputState.pVertexAttributeDescriptions = vertexInputAttributes.data(); pipelineCreateInfo.pVertexInputState = &vertexInputState; // Parallax mapping modes pipeline shaderStages[0] = loadShader(getAssetPath() + "shaders/parallaxmapping/parallax.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); shaderStages[1] = loadShader(getAssetPath() + "shaders/parallaxmapping/parallax.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipeline)); }
VulkanPipeline* VulkanGraphicsPipelineState::createPipeline(UINT32 deviceIdx, VulkanFramebuffer* framebuffer, UINT32 readOnlyFlags, DrawOperationType drawOp, const SPtr<VulkanVertexInput>& vertexInput) { mInputAssemblyInfo.topology = VulkanUtility::getDrawOp(drawOp); mTesselationInfo.patchControlPoints = 3; // Not provided by our shaders for now mMultiSampleInfo.rasterizationSamples = framebuffer->getSampleFlags(); mColorBlendStateInfo.attachmentCount = framebuffer->getNumColorAttachments(); DepthStencilState* dsState = getDepthStencilState().get(); if (dsState == nullptr) dsState = DepthStencilState::getDefault().get(); const DepthStencilProperties dsProps = dsState->getProperties(); bool enableDepthWrites = dsProps.getDepthWriteEnable() && (readOnlyFlags & FBT_DEPTH) == 0; mDepthStencilInfo.depthWriteEnable = enableDepthWrites; // If depth stencil attachment is read only, depthWriteEnable must be VK_FALSE // Save stencil ops as we might need to change them if depth/stencil is read-only VkStencilOp oldFrontPassOp = mDepthStencilInfo.front.passOp; VkStencilOp oldFrontFailOp = mDepthStencilInfo.front.failOp; VkStencilOp oldFrontZFailOp = mDepthStencilInfo.front.depthFailOp; VkStencilOp oldBackPassOp = mDepthStencilInfo.back.passOp; VkStencilOp oldBackFailOp = mDepthStencilInfo.back.failOp; VkStencilOp oldBackZFailOp = mDepthStencilInfo.back.depthFailOp; if((readOnlyFlags & FBT_STENCIL) != 0) { // Disable any stencil writes mDepthStencilInfo.front.passOp = VK_STENCIL_OP_KEEP; mDepthStencilInfo.front.failOp = VK_STENCIL_OP_KEEP; mDepthStencilInfo.front.depthFailOp = VK_STENCIL_OP_KEEP; mDepthStencilInfo.back.passOp = VK_STENCIL_OP_KEEP; mDepthStencilInfo.back.failOp = VK_STENCIL_OP_KEEP; mDepthStencilInfo.back.depthFailOp = VK_STENCIL_OP_KEEP; } // Note: We can use the default render pass here (default clear/load/read flags), even though that might not be the // exact one currently bound. This is because load/store operations and layout transitions are allowed to differ // (as per spec 7.2., such render passes are considered compatible). mPipelineInfo.renderPass = framebuffer->getRenderPass(RT_NONE, RT_NONE, CLEAR_NONE); mPipelineInfo.layout = mPerDeviceData[deviceIdx].pipelineLayout; mPipelineInfo.pVertexInputState = vertexInput->getCreateInfo(); bool depthReadOnly; if (framebuffer->hasDepthAttachment()) { mPipelineInfo.pDepthStencilState = &mDepthStencilInfo; depthReadOnly = (readOnlyFlags & FBT_DEPTH) != 0; } else { mPipelineInfo.pDepthStencilState = nullptr; depthReadOnly = true; } std::array<bool, BS_MAX_MULTIPLE_RENDER_TARGETS> colorReadOnly; if (framebuffer->getNumColorAttachments() > 0) { mPipelineInfo.pColorBlendState = &mColorBlendStateInfo; for (UINT32 i = 0; i < BS_MAX_MULTIPLE_RENDER_TARGETS; i++) { VkPipelineColorBlendAttachmentState& blendState = mAttachmentBlendStates[i]; colorReadOnly[i] = blendState.colorWriteMask == 0; } } else { mPipelineInfo.pColorBlendState = nullptr; for (UINT32 i = 0; i < BS_MAX_MULTIPLE_RENDER_TARGETS; i++) { VkPipelineColorBlendAttachmentState& blendState = mAttachmentBlendStates[i]; colorReadOnly[i] = true; } } std::pair<VkShaderStageFlagBits, GpuProgram*> stages[] = { { VK_SHADER_STAGE_VERTEX_BIT, mData.vertexProgram.get() }, { VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, mData.hullProgram.get() }, { VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, mData.domainProgram.get() }, { VK_SHADER_STAGE_GEOMETRY_BIT, mData.geometryProgram.get() }, { VK_SHADER_STAGE_FRAGMENT_BIT, mData.fragmentProgram.get() } }; UINT32 stageOutputIdx = 0; UINT32 numStages = sizeof(stages) / sizeof(stages[0]); for (UINT32 i = 0; i < numStages; i++) { VulkanGpuProgram* program = static_cast<VulkanGpuProgram*>(stages[i].second); if (program == nullptr) continue; VkPipelineShaderStageCreateInfo& stageCI = mShaderStageInfos[stageOutputIdx]; VulkanShaderModule* module = program->getShaderModule(deviceIdx); if (module != nullptr) stageCI.module = module->getHandle(); else stageCI.module = VK_NULL_HANDLE; stageOutputIdx++; } VulkanDevice* device = mPerDeviceData[deviceIdx].device; VkDevice vkDevice = mPerDeviceData[deviceIdx].device->getLogical(); VkPipeline pipeline; VkResult result = vkCreateGraphicsPipelines(vkDevice, VK_NULL_HANDLE, 1, &mPipelineInfo, gVulkanAllocator, &pipeline); assert(result == VK_SUCCESS); // Restore previous stencil op states mDepthStencilInfo.front.passOp = oldFrontPassOp; mDepthStencilInfo.front.failOp = oldFrontFailOp; mDepthStencilInfo.front.depthFailOp = oldFrontZFailOp; mDepthStencilInfo.back.passOp = oldBackPassOp; mDepthStencilInfo.back.failOp = oldBackFailOp; mDepthStencilInfo.back.depthFailOp = oldBackZFailOp; return device->getResourceManager().create<VulkanPipeline>(pipeline, colorReadOnly, depthReadOnly); }
void TriangleVK::OnCreate(DeviceVK* pDevice, DynamicBufferRingVK *pConstantBufferRing, StaticBufferPoolVK *pStaticGeom, VkRenderPass renderPass) { m_pDevice = pDevice; m_pConstantBufferRing = pConstantBufferRing; VkResult res; struct Vertex { float posX, posY, posZ, posW; // Position data float r, g, b, a; // Color }; #define XYZ1(_x_, _y_, _z_) (_x_), (_y_), (_z_), 1.f const Vertex g_vb_solid_face_colors_Data[] = { // red face { XYZ1(-1, -1, 1), XYZ1(1.f, 0.f, 0.f) }, { XYZ1(-1, 1, 1), XYZ1(1.f, 0.f, 0.f) }, { XYZ1(1, -1, 1), XYZ1(1.f, 0.f, 0.f) }, { XYZ1(1, -1, 1), XYZ1(1.f, 0.f, 0.f) }, { XYZ1(-1, 1, 1), XYZ1(1.f, 0.f, 0.f) }, { XYZ1(1, 1, 1), XYZ1(1.f, 0.f, 0.f) }, // green face { XYZ1(-1, -1, -1), XYZ1(0.f, 1.f, 0.f) }, { XYZ1(1, -1, -1), XYZ1(0.f, 1.f, 0.f) }, { XYZ1(-1, 1, -1), XYZ1(0.f, 1.f, 0.f) }, { XYZ1(-1, 1, -1), XYZ1(0.f, 1.f, 0.f) }, { XYZ1(1, -1, -1), XYZ1(0.f, 1.f, 0.f) }, { XYZ1(1, 1, -1), XYZ1(0.f, 1.f, 0.f) }, // blue face { XYZ1(-1, 1, 1), XYZ1(0.f, 0.f, 1.f) }, { XYZ1(-1, -1, 1), XYZ1(0.f, 0.f, 1.f) }, { XYZ1(-1, 1, -1), XYZ1(0.f, 0.f, 1.f) }, { XYZ1(-1, 1, -1), XYZ1(0.f, 0.f, 1.f) }, { XYZ1(-1, -1, 1), XYZ1(0.f, 0.f, 1.f) }, { XYZ1(-1, -1, -1), XYZ1(0.f, 0.f, 1.f) }, // yellow face { XYZ1(1, 1, 1), XYZ1(1.f, 1.f, 0.f) }, { XYZ1(1, 1, -1), XYZ1(1.f, 1.f, 0.f) }, { XYZ1(1, -1, 1), XYZ1(1.f, 1.f, 0.f) }, { XYZ1(1, -1, 1), XYZ1(1.f, 1.f, 0.f) }, { XYZ1(1, 1, -1), XYZ1(1.f, 1.f, 0.f) }, { XYZ1(1, -1, -1), XYZ1(1.f, 1.f, 0.f) }, // magenta face { XYZ1(1, 1, 1), XYZ1(1.f, 0.f, 1.f) }, { XYZ1(-1, 1, 1), XYZ1(1.f, 0.f, 1.f) }, { XYZ1(1, 1, -1), XYZ1(1.f, 0.f, 1.f) }, { XYZ1(1, 1, -1), XYZ1(1.f, 0.f, 1.f) }, { XYZ1(-1, 1, 1), XYZ1(1.f, 0.f, 1.f) }, { XYZ1(-1, 1, -1), XYZ1(1.f, 0.f, 1.f) }, // cyan face { XYZ1(1, -1, 1), XYZ1(0.f, 1.f, 1.f) }, { XYZ1(1, -1, -1), XYZ1(0.f, 1.f, 1.f) }, { XYZ1(-1, -1, 1), XYZ1(0.f, 1.f, 1.f) }, { XYZ1(-1, -1, 1), XYZ1(0.f, 1.f, 1.f) }, { XYZ1(1, -1, -1), XYZ1(0.f, 1.f, 1.f) }, { XYZ1(-1, -1, -1), XYZ1(0.f, 1.f, 1.f) }, }; int vertices = 6 * 6; int vertexSize = 8 * sizeof(float); void *pData; pStaticGeom->AllocVertexBuffer(vertices, vertexSize, &pData, &m_geometry); memcpy(pData, g_vb_solid_face_colors_Data, sizeof(g_vb_solid_face_colors_Data)); /////////////////////////////////////////////// // shaders const char *vertShaderText = "#version 400\n" "#extension GL_ARB_separate_shader_objects : enable\n" "#extension GL_ARB_shading_language_420pack : enable\n" "layout (std140, binding = 0) uniform bufferVals {\n" " mat4 mvp;\n" "} myBufferVals;\n" "layout (location = 0) in vec4 pos;\n" "layout (location = 1) in vec4 inColor;\n" "layout (location = 0) out vec4 outColor;\n" "void main() {\n" " outColor = inColor;\n" " gl_Position = myBufferVals.mvp * pos;\n" "}\n"; const char *fragShaderText = "#version 400\n" "#extension GL_ARB_separate_shader_objects : enable\n" "#extension GL_ARB_shading_language_420pack : enable\n" "layout (location = 0) in vec4 color;\n" "layout (location = 0) out vec4 outColor;\n" "void main() {\n" " outColor = color;\n" "}\n"; ///////////////////////////////////////////// // Compile and create shaders init_glslang(); std::map<std::string, std::string> attributeDefines; VkPipelineShaderStageCreateInfo m_vertexShader; res = VKCompile(pDevice->GetDevice(), SST_GLSL, VK_SHADER_STAGE_VERTEX_BIT, vertShaderText, "main", attributeDefines, &m_vertexShader); assert(res == VK_SUCCESS); VkPipelineShaderStageCreateInfo m_fragmentShader; res = VKCompile(pDevice->GetDevice(), SST_GLSL, VK_SHADER_STAGE_FRAGMENT_BIT, fragShaderText, "main", attributeDefines, &m_fragmentShader); assert(res == VK_SUCCESS); finalize_glslang(); std::vector<VkPipelineShaderStageCreateInfo> shaderStages = { m_vertexShader, m_fragmentShader }; ///////////////////////////////////////////// // Create descriptor pool std::vector<VkDescriptorPoolSize> type_count = { { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1} }; VkDescriptorPoolCreateInfo descriptor_pool = {}; descriptor_pool.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; descriptor_pool.pNext = NULL; descriptor_pool.maxSets = 1; descriptor_pool.poolSizeCount = (uint32_t)type_count.size(); descriptor_pool.pPoolSizes = type_count.data(); res = vkCreateDescriptorPool(pDevice->GetDevice(), &descriptor_pool, NULL, &m_descriptorPool); assert(res == VK_SUCCESS); ///////////////////////////////////////////// // Create pipeline layout VkDescriptorSetLayoutBinding layout_bindings[1]; layout_bindings[0].binding = 0; layout_bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; layout_bindings[0].descriptorCount = 1; layout_bindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; layout_bindings[0].pImmutableSamplers = NULL; /* Next take layout bindings and use them to create a descriptor set layout */ VkDescriptorSetLayoutCreateInfo descriptor_layout = {}; descriptor_layout.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; descriptor_layout.pNext = NULL; descriptor_layout.flags = 0; descriptor_layout.bindingCount = 1; descriptor_layout.pBindings = layout_bindings; std::vector<VkDescriptorSetLayout> desc_layout; desc_layout.resize(1); res = vkCreateDescriptorSetLayout(pDevice->GetDevice(), &descriptor_layout, NULL, desc_layout.data()); assert(res == VK_SUCCESS); /* Now use the descriptor layout to create a pipeline layout */ VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo = {}; pPipelineLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; pPipelineLayoutCreateInfo.pNext = NULL; pPipelineLayoutCreateInfo.pushConstantRangeCount = 0; pPipelineLayoutCreateInfo.pPushConstantRanges = NULL; pPipelineLayoutCreateInfo.setLayoutCount = (uint32_t)desc_layout.size(); pPipelineLayoutCreateInfo.pSetLayouts = desc_layout.data(); res = vkCreatePipelineLayout(pDevice->GetDevice(), &pPipelineLayoutCreateInfo, NULL, &m_pipelineLayout); assert(res == VK_SUCCESS); ///////////////////////////////////////////// // Create descriptor sets VkDescriptorSetAllocateInfo alloc_info[1]; alloc_info[0].sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; alloc_info[0].pNext = NULL; alloc_info[0].descriptorPool = m_descriptorPool; alloc_info[0].descriptorSetCount = (uint32_t)desc_layout.size(); alloc_info[0].pSetLayouts = desc_layout.data(); m_descriptorSets.resize(desc_layout.size()); res = vkAllocateDescriptorSets(pDevice->GetDevice(), alloc_info, m_descriptorSets.data()); assert(res == VK_SUCCESS); ///////////////////////////////////////////// // Create pipeline // vertex input state VkVertexInputBindingDescription vi_binding = {}; vi_binding.binding = 0; vi_binding.stride = sizeof(float) * 8; vi_binding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; std::vector<VkVertexInputAttributeDescription> vi_attrs(2); // Position vi_attrs[0].location = 0; vi_attrs[0].binding = 0; vi_attrs[0].format = VK_FORMAT_R32G32B32A32_SFLOAT; vi_attrs[0].offset = 0; // Normal vi_attrs[1].location = 1; vi_attrs[1].binding = 0; vi_attrs[1].format = VK_FORMAT_R32G32B32A32_SFLOAT; vi_attrs[1].offset = sizeof(float) * 4; VkPipelineVertexInputStateCreateInfo vi = {}; vi.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; vi.pNext = NULL; vi.flags = 0; vi.vertexBindingDescriptionCount = 1; vi.pVertexBindingDescriptions = &vi_binding; vi.vertexAttributeDescriptionCount = (uint32_t)vi_attrs.size(); vi.pVertexAttributeDescriptions = vi_attrs.data(); // input assembly state VkPipelineInputAssemblyStateCreateInfo ia; ia.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; ia.pNext = NULL; ia.flags = 0; ia.primitiveRestartEnable = VK_FALSE; ia.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; // rasterizer state VkPipelineRasterizationStateCreateInfo rs; rs.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; rs.pNext = NULL; rs.flags = 0; rs.polygonMode = VK_POLYGON_MODE_FILL; rs.cullMode = VK_CULL_MODE_BACK_BIT; rs.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; rs.depthClampEnable = VK_FALSE; rs.rasterizerDiscardEnable = VK_FALSE; rs.depthBiasEnable = VK_FALSE; rs.depthBiasConstantFactor = 0; rs.depthBiasClamp = 0; rs.depthBiasSlopeFactor = 0; rs.lineWidth = 1.0f; VkPipelineColorBlendAttachmentState att_state[1]; att_state[0].colorWriteMask = 0xf; att_state[0].blendEnable = VK_FALSE; att_state[0].alphaBlendOp = VK_BLEND_OP_ADD; att_state[0].colorBlendOp = VK_BLEND_OP_ADD; att_state[0].srcColorBlendFactor = VK_BLEND_FACTOR_ZERO; att_state[0].dstColorBlendFactor = VK_BLEND_FACTOR_ZERO; att_state[0].srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; att_state[0].dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; // Color blend state VkPipelineColorBlendStateCreateInfo cb; cb.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; cb.flags = 0; cb.pNext = NULL; cb.attachmentCount = 1; cb.pAttachments = att_state; cb.logicOpEnable = VK_FALSE; cb.logicOp = VK_LOGIC_OP_NO_OP; cb.blendConstants[0] = 1.0f; cb.blendConstants[1] = 1.0f; cb.blendConstants[2] = 1.0f; cb.blendConstants[3] = 1.0f; std::vector<VkDynamicState> dynamicStateEnables = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; VkPipelineDynamicStateCreateInfo dynamicState = {}; dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; dynamicState.pNext = NULL; dynamicState.pDynamicStates = dynamicStateEnables.data(); dynamicState.dynamicStateCount = (uint32_t)dynamicStateEnables.size(); // view port state VkPipelineViewportStateCreateInfo vp = {}; vp.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; vp.pNext = NULL; vp.flags = 0; vp.viewportCount = 1; vp.scissorCount = 1; vp.pScissors = NULL; vp.pViewports = NULL; // depth stencil state VkPipelineDepthStencilStateCreateInfo ds; ds.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; ds.pNext = NULL; ds.flags = 0; ds.depthTestEnable = true; ds.depthWriteEnable = true; ds.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL; ds.depthBoundsTestEnable = VK_FALSE; ds.stencilTestEnable = VK_FALSE; ds.back.failOp = VK_STENCIL_OP_KEEP; ds.back.passOp = VK_STENCIL_OP_KEEP; ds.back.compareOp = VK_COMPARE_OP_ALWAYS; ds.back.compareMask = 0; ds.back.reference = 0; ds.back.depthFailOp = VK_STENCIL_OP_KEEP; ds.back.writeMask = 0; ds.minDepthBounds = 0; ds.maxDepthBounds = 0; ds.stencilTestEnable = VK_FALSE; ds.front = ds.back; // multi sample state VkPipelineMultisampleStateCreateInfo ms; ms.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; ms.pNext = NULL; ms.flags = 0; ms.pSampleMask = NULL; ms.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; ms.sampleShadingEnable = VK_FALSE; ms.alphaToCoverageEnable = VK_FALSE; ms.alphaToOneEnable = VK_FALSE; ms.minSampleShading = 0.0; // create pipeline cache VkPipelineCacheCreateInfo pipelineCache; pipelineCache.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; pipelineCache.pNext = NULL; pipelineCache.initialDataSize = 0; pipelineCache.pInitialData = NULL; pipelineCache.flags = 0; res = vkCreatePipelineCache(pDevice->GetDevice(), &pipelineCache, NULL, &m_pipelineCache); assert(res == VK_SUCCESS); // create pipeline VkGraphicsPipelineCreateInfo pipeline = {}; pipeline.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; pipeline.pNext = NULL; pipeline.layout = m_pipelineLayout; pipeline.basePipelineHandle = VK_NULL_HANDLE; pipeline.basePipelineIndex = 0; pipeline.flags = 0; pipeline.pVertexInputState = &vi; pipeline.pInputAssemblyState = &ia; pipeline.pRasterizationState = &rs; pipeline.pColorBlendState = &cb; pipeline.pTessellationState = NULL; pipeline.pMultisampleState = &ms; pipeline.pDynamicState = &dynamicState; pipeline.pViewportState = &vp; pipeline.pDepthStencilState = &ds; pipeline.pStages = shaderStages.data(); pipeline.stageCount = (uint32_t)shaderStages.size(); pipeline.renderPass = renderPass; pipeline.subpass = 0; res = vkCreateGraphicsPipelines(pDevice->GetDevice(), m_pipelineCache, 1, &pipeline, NULL, &m_pipeline); assert(res == VK_SUCCESS); }
void preparePipelines() { VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = vkTools::initializers::pipelineInputAssemblyStateCreateInfo( VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0, VK_FALSE); VkPipelineRasterizationStateCreateInfo rasterizationState = vkTools::initializers::pipelineRasterizationStateCreateInfo( VK_POLYGON_MODE_FILL, VK_CULL_MODE_NONE, VK_FRONT_FACE_CLOCKWISE, 0); VkPipelineColorBlendAttachmentState blendAttachmentState = vkTools::initializers::pipelineColorBlendAttachmentState( 0xf, VK_FALSE); VkPipelineColorBlendStateCreateInfo colorBlendState = vkTools::initializers::pipelineColorBlendStateCreateInfo( 1, &blendAttachmentState); VkPipelineDepthStencilStateCreateInfo depthStencilState = vkTools::initializers::pipelineDepthStencilStateCreateInfo( VK_TRUE, VK_TRUE, VK_COMPARE_OP_LESS_OR_EQUAL); VkPipelineViewportStateCreateInfo viewportState = vkTools::initializers::pipelineViewportStateCreateInfo(1, 1, 0); VkPipelineMultisampleStateCreateInfo multisampleState = vkTools::initializers::pipelineMultisampleStateCreateInfo( VK_SAMPLE_COUNT_1_BIT, 0); std::vector<VkDynamicState> dynamicStateEnables = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, VK_DYNAMIC_STATE_LINE_WIDTH, }; VkPipelineDynamicStateCreateInfo dynamicState = vkTools::initializers::pipelineDynamicStateCreateInfo( dynamicStateEnables.data(), static_cast<uint32_t>(dynamicStateEnables.size()), 0); std::array<VkPipelineShaderStageCreateInfo, 2> shaderStages; VkGraphicsPipelineCreateInfo pipelineCreateInfo = vkTools::initializers::pipelineCreateInfo( pipelineLayout, renderPass, 0); pipelineCreateInfo.pVertexInputState = &vertices.inputState; pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState; pipelineCreateInfo.pRasterizationState = &rasterizationState; pipelineCreateInfo.pColorBlendState = &colorBlendState; pipelineCreateInfo.pMultisampleState = &multisampleState; pipelineCreateInfo.pViewportState = &viewportState; pipelineCreateInfo.pDepthStencilState = &depthStencilState; pipelineCreateInfo.pDynamicState = &dynamicState; pipelineCreateInfo.stageCount = static_cast<uint32_t>(shaderStages.size()); pipelineCreateInfo.pStages = shaderStages.data(); // Prepare specialization data // Host data to take specialization constants from struct SpecializationData { // Sets the lighting model used in the fragment "uber" shader uint32_t lightingModel; // Parameter for the toon shading part of the fragment shader float toonDesaturationFactor = 0.5f; } specializationData; // Each shader constant of a shader stage corresponds to one map entry std::array<VkSpecializationMapEntry, 2> specializationMapEntries; // Shader bindings based on specialization constants are marked by the new "constant_id" layout qualifier: // layout (constant_id = 0) const int LIGHTING_MODEL = 0; // layout (constant_id = 1) const float PARAM_TOON_DESATURATION = 0.0f; // Map entry for the lighting model to be used by the fragment shader specializationMapEntries[0].constantID = 0; specializationMapEntries[0].size = sizeof(specializationData.lightingModel); specializationMapEntries[0].offset = 0; // Map entry for the toon shader parameter specializationMapEntries[1].constantID = 1; specializationMapEntries[1].size = sizeof(specializationData.toonDesaturationFactor); specializationMapEntries[1].offset = offsetof(SpecializationData, toonDesaturationFactor); // Prepare specialization info block for the shader stage VkSpecializationInfo specializationInfo{}; specializationInfo.dataSize = sizeof(specializationData); specializationInfo.mapEntryCount = static_cast<uint32_t>(specializationMapEntries.size()); specializationInfo.pMapEntries = specializationMapEntries.data(); specializationInfo.pData = &specializationData; // Create pipelines // All pipelines will use the same "uber" shader and specialization constants to change branching and parameters of that shader shaderStages[0] = loadShader(getAssetPath() + "shaders/specializationconstants/uber.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); shaderStages[1] = loadShader(getAssetPath() + "shaders/specializationconstants/uber.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); // Specialization info is assigned is part of the shader stage (modul) and must be set after creating the module and before creating the pipeline shaderStages[1].pSpecializationInfo = &specializationInfo; // Solid phong shading specializationData.lightingModel = 0; VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.phong)); // Phong and textured specializationData.lightingModel = 1; VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.toon)); // Textured discard specializationData.lightingModel = 2; VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.textured)); }
void preparePipelines() { std::array<VkPipelineShaderStageCreateInfo, 2> shaderStages; VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCI = vks::initializers::pipelineInputAssemblyStateCreateInfo(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0, VK_FALSE); VkPipelineRasterizationStateCreateInfo rasterizationStateCI = vks::initializers::pipelineRasterizationStateCreateInfo(VK_POLYGON_MODE_FILL, VK_CULL_MODE_BACK_BIT, VK_FRONT_FACE_CLOCKWISE, 0); VkPipelineColorBlendAttachmentState blendAttachmentState = vks::initializers::pipelineColorBlendAttachmentState(0xf, VK_FALSE); VkPipelineColorBlendStateCreateInfo colorBlendStateCI = vks::initializers::pipelineColorBlendStateCreateInfo(1, &blendAttachmentState); VkPipelineDepthStencilStateCreateInfo depthStencilStateCI = vks::initializers::pipelineDepthStencilStateCreateInfo(VK_TRUE, VK_TRUE, VK_COMPARE_OP_LESS_OR_EQUAL); VkPipelineViewportStateCreateInfo viewportStateCI = vks::initializers::pipelineViewportStateCreateInfo(1, 1, 0); VkPipelineMultisampleStateCreateInfo multisampleStateCI = vks::initializers::pipelineMultisampleStateCreateInfo(VK_SAMPLE_COUNT_1_BIT, 0); std::vector<VkDynamicState> dynamicStateEnables = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; VkPipelineDynamicStateCreateInfo dynamicStateCI = vks::initializers::pipelineDynamicStateCreateInfo(dynamicStateEnables); VkGraphicsPipelineCreateInfo pipelineCI = vks::initializers::pipelineCreateInfo(); pipelineCI.renderPass = renderPass; pipelineCI.pInputAssemblyState = &inputAssemblyStateCI; pipelineCI.pRasterizationState = &rasterizationStateCI; pipelineCI.pColorBlendState = &colorBlendStateCI; pipelineCI.pMultisampleState = &multisampleStateCI; pipelineCI.pViewportState = &viewportStateCI; pipelineCI.pDepthStencilState = &depthStencilStateCI; pipelineCI.pDynamicState = &dynamicStateCI; pipelineCI.stageCount = static_cast<uint32_t>(shaderStages.size()); pipelineCI.pStages = shaderStages.data(); /* Attachment write */ // Pipeline will be used in first sub pass pipelineCI.subpass = 0; pipelineCI.layout = pipelineLayouts.attachmentWrite; // Binding description std::vector<VkVertexInputBindingDescription> vertexInputBindings = { vks::initializers::vertexInputBindingDescription(0, vertexLayout.stride(), VK_VERTEX_INPUT_RATE_VERTEX), }; // Attribute descriptions std::vector<VkVertexInputAttributeDescription> vertexInputAttributes = { vks::initializers::vertexInputAttributeDescription(0, 0, VK_FORMAT_R32G32B32_SFLOAT, 0), // Location 0: Position vks::initializers::vertexInputAttributeDescription(0, 1, VK_FORMAT_R32G32B32_SFLOAT, sizeof(float) * 3), // Location 1: Color vks::initializers::vertexInputAttributeDescription(0, 2, VK_FORMAT_R32G32B32_SFLOAT, sizeof(float) * 6), // Location 2: Normal vks::initializers::vertexInputAttributeDescription(0, 3, VK_FORMAT_R32G32_SFLOAT, sizeof(float) * 9), // Location 3: UV }; VkPipelineVertexInputStateCreateInfo vertexInputStateCI = vks::initializers::pipelineVertexInputStateCreateInfo(); vertexInputStateCI.vertexBindingDescriptionCount = static_cast<uint32_t>(vertexInputBindings.size()); vertexInputStateCI.pVertexBindingDescriptions = vertexInputBindings.data(); vertexInputStateCI.vertexAttributeDescriptionCount = static_cast<uint32_t>(vertexInputAttributes.size()); vertexInputStateCI.pVertexAttributeDescriptions = vertexInputAttributes.data(); pipelineCI.pVertexInputState = &vertexInputStateCI; shaderStages[0] = loadShader(getAssetPath() + "shaders/inputattachments/attachmentwrite.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); shaderStages[1] = loadShader(getAssetPath() + "shaders/inputattachments/attachmentwrite.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.attachmentWrite)); /* Attachment read */ // Pipeline will be used in second sub pass pipelineCI.subpass = 1; pipelineCI.layout = pipelineLayouts.attachmentRead; VkPipelineVertexInputStateCreateInfo emptyInputStateCI{}; emptyInputStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; pipelineCI.pVertexInputState = &emptyInputStateCI; colorBlendStateCI.attachmentCount = 1; rasterizationStateCI.cullMode = VK_CULL_MODE_NONE; depthStencilStateCI.depthWriteEnable = VK_FALSE; shaderStages[0] = loadShader(getAssetPath() + "shaders/inputattachments/attachmentread.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); shaderStages[1] = loadShader(getAssetPath() + "shaders/inputattachments/attachmentread.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.attachmentRead)); }
void preparePipelines() { VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCI = vks::initializers::pipelineInputAssemblyStateCreateInfo(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0, VK_FALSE); VkPipelineRasterizationStateCreateInfo rasterizationStateCI = vks::initializers::pipelineRasterizationStateCreateInfo(VK_POLYGON_MODE_FILL, VK_CULL_MODE_NONE, VK_FRONT_FACE_COUNTER_CLOCKWISE, 0); VkPipelineColorBlendAttachmentState blendAttachmentState = vks::initializers::pipelineColorBlendAttachmentState(0xf, VK_FALSE); VkPipelineColorBlendStateCreateInfo colorBlendStateCI = vks::initializers::pipelineColorBlendStateCreateInfo(1, &blendAttachmentState); VkPipelineDepthStencilStateCreateInfo depthStencilStateCI = vks::initializers::pipelineDepthStencilStateCreateInfo(VK_TRUE, VK_TRUE, VK_COMPARE_OP_LESS_OR_EQUAL); VkPipelineViewportStateCreateInfo viewportStateCI = vks::initializers::pipelineViewportStateCreateInfo(1, 1, 0); VkPipelineMultisampleStateCreateInfo multisampleStateCI = vks::initializers::pipelineMultisampleStateCreateInfo(VK_SAMPLE_COUNT_1_BIT, 0); std::vector<VkDynamicState> dynamicStateEnables = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; VkPipelineDynamicStateCreateInfo dynamicStateCI = vks::initializers::pipelineDynamicStateCreateInfo(dynamicStateEnables.data(), dynamicStateEnables.size(), 0); std::array<VkPipelineShaderStageCreateInfo, 2> shaderStages; VkGraphicsPipelineCreateInfo pipelineCI = vks::initializers::pipelineCreateInfo(pipelineLayouts.radialBlur, renderPass, 0); pipelineCI.pInputAssemblyState = &inputAssemblyStateCI; pipelineCI.pRasterizationState = &rasterizationStateCI; pipelineCI.pColorBlendState = &colorBlendStateCI; pipelineCI.pMultisampleState = &multisampleStateCI; pipelineCI.pViewportState = &viewportStateCI; pipelineCI.pDepthStencilState = &depthStencilStateCI; pipelineCI.pDynamicState = &dynamicStateCI; pipelineCI.stageCount = shaderStages.size(); pipelineCI.pStages = shaderStages.data(); // Radial blur pipeline shaderStages[0] = loadShader(getAssetPath() + "shaders/radialblur/radialblur.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); shaderStages[1] = loadShader(getAssetPath() + "shaders/radialblur/radialblur.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); // Empty vertex input state VkPipelineVertexInputStateCreateInfo emptyInputState = vks::initializers::pipelineVertexInputStateCreateInfo(); pipelineCI.pVertexInputState = &emptyInputState; pipelineCI.layout = pipelineLayouts.radialBlur; // Additive blending blendAttachmentState.colorWriteMask = 0xF; blendAttachmentState.blendEnable = VK_TRUE; blendAttachmentState.colorBlendOp = VK_BLEND_OP_ADD; blendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_ONE; blendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE; blendAttachmentState.alphaBlendOp = VK_BLEND_OP_ADD; blendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; blendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_DST_ALPHA; VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.radialBlur)); // No blending (for debug display) blendAttachmentState.blendEnable = VK_FALSE; VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.offscreenDisplay)); // Phong pass pipelineCI.layout = pipelineLayouts.scene; shaderStages[0] = loadShader(getAssetPath() + "shaders/radialblur/phongpass.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); shaderStages[1] = loadShader(getAssetPath() + "shaders/radialblur/phongpass.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); blendAttachmentState.blendEnable = VK_FALSE; depthStencilStateCI.depthWriteEnable = VK_TRUE; // Vertex bindings and attributes std::vector<VkVertexInputBindingDescription> vertexInputBindings = { vks::initializers::vertexInputBindingDescription(0, vertexLayout.stride(), VK_VERTEX_INPUT_RATE_VERTEX), }; std::vector<VkVertexInputAttributeDescription> vertexInputAttributes = { vks::initializers::vertexInputAttributeDescription(0, 0, VK_FORMAT_R32G32B32_SFLOAT, 0), // Position vks::initializers::vertexInputAttributeDescription(0, 1, VK_FORMAT_R32G32_SFLOAT, sizeof(float) * 3), // Texture coordinates vks::initializers::vertexInputAttributeDescription(0, 2, VK_FORMAT_R32G32B32_SFLOAT, sizeof(float) * 5), // Color vks::initializers::vertexInputAttributeDescription(0, 3, VK_FORMAT_R32G32B32_SFLOAT, sizeof(float) * 8), // Normal }; VkPipelineVertexInputStateCreateInfo vertexInputState = vks::initializers::pipelineVertexInputStateCreateInfo(); vertexInputState.vertexBindingDescriptionCount = static_cast<uint32_t>(vertexInputBindings.size()); vertexInputState.pVertexBindingDescriptions = vertexInputBindings.data(); vertexInputState.vertexAttributeDescriptionCount = static_cast<uint32_t>(vertexInputAttributes.size()); vertexInputState.pVertexAttributeDescriptions = vertexInputAttributes.data(); pipelineCI.pVertexInputState = &vertexInputState; VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.phongPass)); // Color only pass (offscreen blur base) shaderStages[0] = loadShader(getAssetPath() + "shaders/radialblur/colorpass.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); shaderStages[1] = loadShader(getAssetPath() + "shaders/radialblur/colorpass.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); pipelineCI.renderPass = offscreenPass.renderPass; VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.colorPass)); }
void preparePipelines() { VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = vks::initializers::pipelineInputAssemblyStateCreateInfo( VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0, VK_FALSE); VkPipelineRasterizationStateCreateInfo rasterizationState = vks::initializers::pipelineRasterizationStateCreateInfo( VK_POLYGON_MODE_FILL, VK_CULL_MODE_BACK_BIT, VK_FRONT_FACE_COUNTER_CLOCKWISE, 0); VkPipelineColorBlendAttachmentState blendAttachmentState = vks::initializers::pipelineColorBlendAttachmentState( 0xf, VK_FALSE); VkPipelineColorBlendStateCreateInfo colorBlendState = vks::initializers::pipelineColorBlendStateCreateInfo( 1, &blendAttachmentState); VkPipelineDepthStencilStateCreateInfo depthStencilState = vks::initializers::pipelineDepthStencilStateCreateInfo( VK_FALSE, VK_FALSE, VK_COMPARE_OP_LESS_OR_EQUAL); VkPipelineViewportStateCreateInfo viewportState = vks::initializers::pipelineViewportStateCreateInfo(1, 1, 0); VkPipelineMultisampleStateCreateInfo multisampleState = vks::initializers::pipelineMultisampleStateCreateInfo( VK_SAMPLE_COUNT_1_BIT, 0); std::vector<VkDynamicState> dynamicStateEnables = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; VkPipelineDynamicStateCreateInfo dynamicState = vks::initializers::pipelineDynamicStateCreateInfo( dynamicStateEnables.data(), dynamicStateEnables.size(), 0); // Vertex bindings and attributes VkVertexInputBindingDescription vertexInputBinding = vks::initializers::vertexInputBindingDescription(0, vertexLayout.stride(), VK_VERTEX_INPUT_RATE_VERTEX); std::vector<VkVertexInputAttributeDescription> vertexInputAttributes = { vks::initializers::vertexInputAttributeDescription(0, 0, VK_FORMAT_R32G32B32_SFLOAT, 0), // Location 0: Position vks::initializers::vertexInputAttributeDescription(0, 1, VK_FORMAT_R32G32B32_SFLOAT, sizeof(float) * 3), // Location 1: Normal }; VkPipelineVertexInputStateCreateInfo vertexInputState = vks::initializers::pipelineVertexInputStateCreateInfo(); vertexInputState.vertexBindingDescriptionCount = 1; vertexInputState.pVertexBindingDescriptions = &vertexInputBinding; vertexInputState.vertexAttributeDescriptionCount = static_cast<uint32_t>(vertexInputAttributes.size()); vertexInputState.pVertexAttributeDescriptions = vertexInputAttributes.data(); std::array<VkPipelineShaderStageCreateInfo, 2> shaderStages; VkGraphicsPipelineCreateInfo pipelineCreateInfo = vks::initializers::pipelineCreateInfo(pipelineLayout, renderPass, 0); pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState; pipelineCreateInfo.pRasterizationState = &rasterizationState; pipelineCreateInfo.pColorBlendState = &colorBlendState; pipelineCreateInfo.pMultisampleState = &multisampleState; pipelineCreateInfo.pViewportState = &viewportState; pipelineCreateInfo.pDepthStencilState = &depthStencilState; pipelineCreateInfo.pDynamicState = &dynamicState; pipelineCreateInfo.stageCount = shaderStages.size(); pipelineCreateInfo.pStages = shaderStages.data(); pipelineCreateInfo.pVertexInputState = &vertexInputState; // Skybox pipeline (background cube) shaderStages[0] = loadShader(getAssetPath() + "shaders/texturecubemap/skybox.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); shaderStages[1] = loadShader(getAssetPath() + "shaders/texturecubemap/skybox.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.skybox)); // Cube map reflect pipeline shaderStages[0] = loadShader(getAssetPath() + "shaders/texturecubemap/reflect.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); shaderStages[1] = loadShader(getAssetPath() + "shaders/texturecubemap/reflect.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); // Enable depth test and write depthStencilState.depthWriteEnable = VK_TRUE; depthStencilState.depthTestEnable = VK_TRUE; // Flip cull mode rasterizationState.cullMode = VK_CULL_MODE_FRONT_BIT; VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.reflect)); }
void preparePipelines() { VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = vkTools::initializers::pipelineInputAssemblyStateCreateInfo( VK_PRIMITIVE_TOPOLOGY_POINT_LIST, 0, VK_FALSE); VkPipelineRasterizationStateCreateInfo rasterizationState = vkTools::initializers::pipelineRasterizationStateCreateInfo( VK_POLYGON_MODE_FILL, VK_CULL_MODE_NONE, VK_FRONT_FACE_COUNTER_CLOCKWISE, 0); VkPipelineColorBlendAttachmentState blendAttachmentState = vkTools::initializers::pipelineColorBlendAttachmentState( 0xf, VK_FALSE); VkPipelineColorBlendStateCreateInfo colorBlendState = vkTools::initializers::pipelineColorBlendStateCreateInfo( 1, &blendAttachmentState); VkPipelineDepthStencilStateCreateInfo depthStencilState = vkTools::initializers::pipelineDepthStencilStateCreateInfo( VK_FALSE, VK_FALSE, VK_COMPARE_OP_ALWAYS); VkPipelineViewportStateCreateInfo viewportState = vkTools::initializers::pipelineViewportStateCreateInfo(1, 1, 0); VkPipelineMultisampleStateCreateInfo multisampleState = vkTools::initializers::pipelineMultisampleStateCreateInfo( VK_SAMPLE_COUNT_1_BIT, 0); std::vector<VkDynamicState> dynamicStateEnables = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; VkPipelineDynamicStateCreateInfo dynamicState = vkTools::initializers::pipelineDynamicStateCreateInfo( dynamicStateEnables.data(), dynamicStateEnables.size(), 0); // Rendering pipeline // Load shaders std::array<VkPipelineShaderStageCreateInfo,2> shaderStages; shaderStages[0] = loadShader(getAssetPath() + "shaders/computeparticles/particle.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); shaderStages[1] = loadShader(getAssetPath() + "shaders/computeparticles/particle.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); VkGraphicsPipelineCreateInfo pipelineCreateInfo = vkTools::initializers::pipelineCreateInfo( pipelineLayout, renderPass, 0); pipelineCreateInfo.pVertexInputState = &vertices.inputState; pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState; pipelineCreateInfo.pRasterizationState = &rasterizationState; pipelineCreateInfo.pColorBlendState = &colorBlendState; pipelineCreateInfo.pMultisampleState = &multisampleState; pipelineCreateInfo.pViewportState = &viewportState; pipelineCreateInfo.pDepthStencilState = &depthStencilState; pipelineCreateInfo.pDynamicState = &dynamicState; pipelineCreateInfo.stageCount = shaderStages.size(); pipelineCreateInfo.pStages = shaderStages.data(); pipelineCreateInfo.renderPass = renderPass; // Additive blending blendAttachmentState.colorWriteMask = 0xF; blendAttachmentState.blendEnable = VK_TRUE; blendAttachmentState.colorBlendOp = VK_BLEND_OP_ADD; blendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_ONE; blendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE; blendAttachmentState.alphaBlendOp = VK_BLEND_OP_ADD; blendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; blendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_DST_ALPHA; VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.postCompute)); }
void preparePipelines() { VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = vks::initializers::pipelineInputAssemblyStateCreateInfo( VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0, VK_FALSE); VkPipelineRasterizationStateCreateInfo rasterizationState = vks::initializers::pipelineRasterizationStateCreateInfo( VK_POLYGON_MODE_FILL, VK_CULL_MODE_NONE, VK_FRONT_FACE_COUNTER_CLOCKWISE, 0); VkPipelineColorBlendAttachmentState blendAttachmentState = vks::initializers::pipelineColorBlendAttachmentState( 0xf, VK_FALSE); VkPipelineColorBlendStateCreateInfo colorBlendState = vks::initializers::pipelineColorBlendStateCreateInfo( 1, &blendAttachmentState); VkPipelineDepthStencilStateCreateInfo depthStencilState = vks::initializers::pipelineDepthStencilStateCreateInfo( VK_TRUE, VK_TRUE, VK_COMPARE_OP_LESS_OR_EQUAL); VkPipelineViewportStateCreateInfo viewportState = vks::initializers::pipelineViewportStateCreateInfo(1, 1, 0); VkPipelineMultisampleStateCreateInfo multisampleState = vks::initializers::pipelineMultisampleStateCreateInfo( VK_SAMPLE_COUNT_1_BIT, 0); std::vector<VkDynamicState> dynamicStateEnables = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; VkPipelineDynamicStateCreateInfo dynamicState = vks::initializers::pipelineDynamicStateCreateInfo( dynamicStateEnables.data(), static_cast<uint32_t>(dynamicStateEnables.size()), 0); // Load shaders std::array<VkPipelineShaderStageCreateInfo, 2> shaderStages; shaderStages[0] = loadShader(getAssetPath() + "shaders/dynamicuniformbuffer/base.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); shaderStages[1] = loadShader(getAssetPath() + "shaders/dynamicuniformbuffer/base.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); VkGraphicsPipelineCreateInfo pipelineCreateInfo = vks::initializers::pipelineCreateInfo( pipelineLayout, renderPass, 0); pipelineCreateInfo.pVertexInputState = &vertices.inputState; pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState; pipelineCreateInfo.pRasterizationState = &rasterizationState; pipelineCreateInfo.pColorBlendState = &colorBlendState; pipelineCreateInfo.pMultisampleState = &multisampleState; pipelineCreateInfo.pViewportState = &viewportState; pipelineCreateInfo.pDepthStencilState = &depthStencilState; pipelineCreateInfo.pDynamicState = &dynamicState; pipelineCreateInfo.stageCount = static_cast<uint32_t>(shaderStages.size()); pipelineCreateInfo.pStages = shaderStages.data(); VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipeline)); }
static VulkanPipeline *CreateVulkanPipeline(VkDevice device, VkPipelineCache pipelineCache, VkPipelineLayout layout, VkRenderPass renderPass, const VulkanPipelineRasterStateKey &key, const DecVtxFormat *decFmt, VulkanVertexShader *vs, VulkanFragmentShader *fs, bool useHwTransform, float lineWidth) { bool useBlendConstant = false; VkPipelineColorBlendAttachmentState blend0 = {}; blend0.blendEnable = key.blendEnable; if (key.blendEnable) { blend0.colorBlendOp = (VkBlendOp)key.blendOpColor; blend0.alphaBlendOp = (VkBlendOp)key.blendOpAlpha; blend0.srcColorBlendFactor = (VkBlendFactor)key.srcColor; blend0.srcAlphaBlendFactor = (VkBlendFactor)key.srcAlpha; blend0.dstColorBlendFactor = (VkBlendFactor)key.destColor; blend0.dstAlphaBlendFactor = (VkBlendFactor)key.destAlpha; } blend0.colorWriteMask = key.colorWriteMask; VkPipelineColorBlendStateCreateInfo cbs = { VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO }; cbs.flags = 0; cbs.pAttachments = &blend0; cbs.attachmentCount = 1; cbs.logicOpEnable = key.logicOpEnable; if (key.logicOpEnable) cbs.logicOp = (VkLogicOp)key.logicOp; else cbs.logicOp = VK_LOGIC_OP_COPY; VkPipelineDepthStencilStateCreateInfo dss = { VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO }; dss.depthBoundsTestEnable = false; dss.stencilTestEnable = key.stencilTestEnable; if (key.stencilTestEnable) { dss.front.compareOp = (VkCompareOp)key.stencilCompareOp; dss.front.passOp = (VkStencilOp)key.stencilPassOp; dss.front.failOp = (VkStencilOp)key.stencilFailOp; dss.front.depthFailOp = (VkStencilOp)key.stencilDepthFailOp; // Back stencil is always the same as front on PSP. memcpy(&dss.back, &dss.front, sizeof(dss.front)); } dss.depthTestEnable = key.depthTestEnable; if (key.depthTestEnable) { dss.depthCompareOp = (VkCompareOp)key.depthCompareOp; dss.depthWriteEnable = key.depthWriteEnable; } VkDynamicState dynamicStates[8]; int numDyn = 0; if (key.blendEnable && (UsesBlendConstant(key.srcAlpha) || UsesBlendConstant(key.srcColor) || UsesBlendConstant(key.destAlpha) || UsesBlendConstant(key.destColor))) { dynamicStates[numDyn++] = VK_DYNAMIC_STATE_BLEND_CONSTANTS; useBlendConstant = true; } dynamicStates[numDyn++] = VK_DYNAMIC_STATE_SCISSOR; dynamicStates[numDyn++] = VK_DYNAMIC_STATE_VIEWPORT; if (key.stencilTestEnable) { dynamicStates[numDyn++] = VK_DYNAMIC_STATE_STENCIL_WRITE_MASK; dynamicStates[numDyn++] = VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK; dynamicStates[numDyn++] = VK_DYNAMIC_STATE_STENCIL_REFERENCE; } VkPipelineDynamicStateCreateInfo ds = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; ds.flags = 0; ds.pDynamicStates = dynamicStates; ds.dynamicStateCount = numDyn; VkPipelineRasterizationStateCreateInfo rs = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO }; rs.flags = 0; rs.depthBiasEnable = false; rs.cullMode = key.cullMode; rs.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; rs.lineWidth = lineWidth; rs.rasterizerDiscardEnable = false; rs.polygonMode = VK_POLYGON_MODE_FILL; rs.depthClampEnable = key.depthClampEnable; VkPipelineMultisampleStateCreateInfo ms = { VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO }; ms.pSampleMask = nullptr; ms.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; VkPipelineShaderStageCreateInfo ss[2]; ss[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; ss[0].pNext = nullptr; ss[0].stage = VK_SHADER_STAGE_VERTEX_BIT; ss[0].pSpecializationInfo = nullptr; ss[0].module = vs->GetModule(); ss[0].pName = "main"; ss[0].flags = 0; ss[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; ss[1].pNext = nullptr; ss[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT; ss[1].pSpecializationInfo = nullptr; ss[1].module = fs->GetModule(); ss[1].pName = "main"; ss[1].flags = 0; if (!ss[0].module || !ss[1].module) { ERROR_LOG(G3D, "Failed creating graphics pipeline - bad shaders"); return nullptr; } VkPipelineInputAssemblyStateCreateInfo inputAssembly = { VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO }; inputAssembly.flags = 0; inputAssembly.topology = (VkPrimitiveTopology)key.topology; inputAssembly.primitiveRestartEnable = false; int vertexStride = 0; int offset = 0; VkVertexInputAttributeDescription attrs[8]; int attributeCount; if (useHwTransform) { attributeCount = SetupVertexAttribs(attrs, *decFmt); vertexStride = decFmt->stride; } else { attributeCount = SetupVertexAttribsPretransformed(attrs, *decFmt); vertexStride = 36; } VkVertexInputBindingDescription ibd; ibd.binding = 0; ibd.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; ibd.stride = vertexStride; VkPipelineVertexInputStateCreateInfo vis = { VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO }; vis.flags = 0; vis.vertexBindingDescriptionCount = 1; vis.pVertexBindingDescriptions = &ibd; vis.vertexAttributeDescriptionCount = attributeCount; vis.pVertexAttributeDescriptions = attrs; VkPipelineViewportStateCreateInfo views = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO }; views.flags = 0; views.viewportCount = 1; views.scissorCount = 1; views.pViewports = nullptr; // dynamic views.pScissors = nullptr; // dynamic VkGraphicsPipelineCreateInfo pipe = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO }; pipe.flags = 0; pipe.stageCount = 2; pipe.pStages = ss; pipe.basePipelineIndex = 0; pipe.pColorBlendState = &cbs; pipe.pDepthStencilState = &dss; pipe.pRasterizationState = &rs; // We will use dynamic viewport state. pipe.pVertexInputState = &vis; pipe.pViewportState = &views; pipe.pTessellationState = nullptr; pipe.pDynamicState = &ds; pipe.pInputAssemblyState = &inputAssembly; pipe.pMultisampleState = &ms; pipe.layout = layout; pipe.basePipelineHandle = VK_NULL_HANDLE; pipe.basePipelineIndex = 0; pipe.renderPass = renderPass; pipe.subpass = 0; VkPipeline pipeline; VkResult result = vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipe, nullptr, &pipeline); if (result != VK_SUCCESS) { _assert_msg_(G3D, false, "Failed creating graphics pipeline! result='%s'", VulkanResultToString(result)); ERROR_LOG(G3D, "Failed creating graphics pipeline! result='%s'", VulkanResultToString(result)); return nullptr; } VulkanPipeline *vulkanPipeline = new VulkanPipeline(); vulkanPipeline->pipeline = pipeline; vulkanPipeline->uniformBlocks = UB_VS_FS_BASE; vulkanPipeline->useBlendConstant = useBlendConstant; vulkanPipeline->usesLines = key.topology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST || key.topology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP; if (useHwTransform) { if (vs->HasLights()) { vulkanPipeline->uniformBlocks |= UB_VS_LIGHTS; } if (vs->HasBones()) { vulkanPipeline->uniformBlocks |= UB_VS_BONES; } } return vulkanPipeline; }
void preparePipelines() { if (pipeline != VK_NULL_HANDLE) { vkDestroyPipeline(device, pipeline, nullptr); } VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = vks::initializers::pipelineInputAssemblyStateCreateInfo(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0, VK_FALSE); VkPipelineRasterizationStateCreateInfo rasterizationState = vks::initializers::pipelineRasterizationStateCreateInfo(VK_POLYGON_MODE_FILL, cullMode, VK_FRONT_FACE_CLOCKWISE, 0); VkPipelineColorBlendAttachmentState blendAttachmentState = vks::initializers::pipelineColorBlendAttachmentState(0xf, VK_FALSE); VkPipelineColorBlendStateCreateInfo colorBlendState = vks::initializers::pipelineColorBlendStateCreateInfo(1, &blendAttachmentState); VkPipelineDepthStencilStateCreateInfo depthStencilState = vks::initializers::pipelineDepthStencilStateCreateInfo(VK_TRUE, VK_TRUE, VK_COMPARE_OP_LESS_OR_EQUAL); VkPipelineViewportStateCreateInfo viewportState = vks::initializers::pipelineViewportStateCreateInfo(1, 1, 0); VkPipelineMultisampleStateCreateInfo multisampleState = vks::initializers::pipelineMultisampleStateCreateInfo(VK_SAMPLE_COUNT_1_BIT, 0); std::vector<VkDynamicState> dynamicStateEnables = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; VkPipelineDynamicStateCreateInfo dynamicState = vks::initializers::pipelineDynamicStateCreateInfo(dynamicStateEnables.data(), static_cast<uint32_t>(dynamicStateEnables.size()), 0); VkGraphicsPipelineCreateInfo pipelineCreateInfo = vks::initializers::pipelineCreateInfo(pipelineLayout, renderPass, 0); VkPipelineTessellationStateCreateInfo tessellationState = vks::initializers::pipelineTessellationStateCreateInfo(3); pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState; pipelineCreateInfo.pRasterizationState = &rasterizationState; pipelineCreateInfo.pColorBlendState = &colorBlendState; pipelineCreateInfo.pMultisampleState = &multisampleState; pipelineCreateInfo.pViewportState = &viewportState; pipelineCreateInfo.pDepthStencilState = &depthStencilState; pipelineCreateInfo.pDynamicState = &dynamicState; // Vertex bindings and attributes std::vector<VkVertexInputBindingDescription> vertexInputBindings = { vks::initializers::vertexInputBindingDescription(0, vertexLayout.stride(), VK_VERTEX_INPUT_RATE_VERTEX) }; std::vector<VkVertexInputAttributeDescription> vertexInputAttributes = { vks::initializers::vertexInputAttributeDescription(0, 0, VK_FORMAT_R32G32B32_SFLOAT, 0), // Location 0 : Position vks::initializers::vertexInputAttributeDescription(0, 1, VK_FORMAT_R32G32B32_SFLOAT, sizeof(float) * 3), // Location 1 : Normal vks::initializers::vertexInputAttributeDescription(0, 2, VK_FORMAT_R32G32B32_SFLOAT, sizeof(float) * 6) // Location 3 : Color }; VkPipelineVertexInputStateCreateInfo vertexInputState = vks::initializers::pipelineVertexInputStateCreateInfo(); vertexInputState.vertexBindingDescriptionCount = static_cast<uint32_t>(vertexInputBindings.size()); vertexInputState.pVertexBindingDescriptions = vertexInputBindings.data(); vertexInputState.vertexAttributeDescriptionCount = static_cast<uint32_t>(vertexInputAttributes.size()); vertexInputState.pVertexAttributeDescriptions = vertexInputAttributes.data(); pipelineCreateInfo.pVertexInputState = &vertexInputState; if (blending) { blendAttachmentState.blendEnable = VK_TRUE; blendAttachmentState.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; blendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; blendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; blendAttachmentState.colorBlendOp = VK_BLEND_OP_ADD; blendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; blendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; blendAttachmentState.alphaBlendOp = VK_BLEND_OP_ADD; depthStencilState.depthWriteEnable = VK_FALSE; } if (discard) { rasterizationState.rasterizerDiscardEnable = VK_TRUE; } if (wireframe) { rasterizationState.polygonMode = VK_POLYGON_MODE_LINE; } std::vector<VkPipelineShaderStageCreateInfo> shaderStages; shaderStages.resize(tessellation ? 4 : 2); shaderStages[0] = loadShader(getAssetPath() + "shaders/pipelinestatistics/scene.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); shaderStages[1] = loadShader(getAssetPath() + "shaders/pipelinestatistics/scene.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); if (tessellation) { inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST; pipelineCreateInfo.pTessellationState = &tessellationState; shaderStages[2] = loadShader(getAssetPath() + "shaders/pipelinestatistics/scene.tesc.spv", VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT); shaderStages[3] = loadShader(getAssetPath() + "shaders/pipelinestatistics/scene.tese.spv", VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT); } pipelineCreateInfo.stageCount = static_cast<uint32_t>(shaderStages.size()); pipelineCreateInfo.pStages = shaderStages.data(); VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipeline)); }
void preparePipelines() { VkResult err; VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = vkTools::initializers::pipelineInputAssemblyStateCreateInfo( VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0, VK_FALSE); VkPipelineRasterizationStateCreateInfo rasterizationState = vkTools::initializers::pipelineRasterizationStateCreateInfo( VK_POLYGON_MODE_FILL, VK_CULL_MODE_BACK_BIT, VK_FRONT_FACE_CLOCKWISE, 0); VkPipelineColorBlendAttachmentState blendAttachmentState = vkTools::initializers::pipelineColorBlendAttachmentState( 0xf, VK_FALSE); VkPipelineColorBlendStateCreateInfo colorBlendState = vkTools::initializers::pipelineColorBlendStateCreateInfo( 1, &blendAttachmentState); VkPipelineDepthStencilStateCreateInfo depthStencilState = vkTools::initializers::pipelineDepthStencilStateCreateInfo( VK_TRUE, VK_TRUE, VK_COMPARE_OP_LESS_OR_EQUAL); VkPipelineViewportStateCreateInfo viewportState = vkTools::initializers::pipelineViewportStateCreateInfo(1, 1, 0); VkPipelineMultisampleStateCreateInfo multisampleState = vkTools::initializers::pipelineMultisampleStateCreateInfo( VK_SAMPLE_COUNT_1_BIT, 0); std::vector<VkDynamicState> dynamicStateEnables = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, VK_DYNAMIC_STATE_LINE_WIDTH }; VkPipelineDynamicStateCreateInfo dynamicState = vkTools::initializers::pipelineDynamicStateCreateInfo( dynamicStateEnables.data(), dynamicStateEnables.size(), 0); // Tessellation pipeline // Load shaders std::array<VkPipelineShaderStageCreateInfo, 3> shaderStages; shaderStages[0] = loadShader("./../data/shaders/geometryshader/base.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); shaderStages[1] = loadShader("./../data/shaders/geometryshader/base.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); shaderStages[2] = loadShader("./../data/shaders/geometryshader/normaldebug.geom.spv", VK_SHADER_STAGE_GEOMETRY_BIT); VkGraphicsPipelineCreateInfo pipelineCreateInfo = vkTools::initializers::pipelineCreateInfo( pipelineLayout, renderPass, 0); pipelineCreateInfo.pVertexInputState = &vertices.inputState; pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState; pipelineCreateInfo.pRasterizationState = &rasterizationState; pipelineCreateInfo.pColorBlendState = &colorBlendState; pipelineCreateInfo.pMultisampleState = &multisampleState; pipelineCreateInfo.pViewportState = &viewportState; pipelineCreateInfo.pDepthStencilState = &depthStencilState; pipelineCreateInfo.pDynamicState = &dynamicState; pipelineCreateInfo.stageCount = shaderStages.size(); pipelineCreateInfo.pStages = shaderStages.data(); pipelineCreateInfo.renderPass = renderPass; // Normal debugging pipeline err = vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.normals); assert(!err); // Solid rendering pipeline // Shader shaderStages[0] = loadShader("./../data/shaders/geometryshader/mesh.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); shaderStages[1] = loadShader("./../data/shaders/geometryshader/mesh.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); pipelineCreateInfo.stageCount = 2; err = vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.solid); assert(!err); }
bool game_buffer_editor_create(game_buffer_editor_create_info *game_buffer_editor_create_info, game_buffer_editor *game_buffer_editor) { ImGuiIO *imgui_io = &ImGui::GetIO(); vulkan_image_2d_bgra_srgb imgui_white_vulkan_image = {}; vulkan_image_2d_bgra_srgb imgui_font_atlas_vulkan_image = {}; vulkan_buffer imgui_vertex_index_vulkan_buffer = {}; VkResult vk_result = {}; VkPipeline imgui_vulkan_pipeline = {}; VkDescriptorSetLayout imgui_vulkan_pipeline_descriptor_set_layout = {}; VkPipelineLayout imgui_vulkan_pipeline_layout; VkDescriptorPool imgui_vulkan_descriptor_pool = {}; VkDescriptorSet imgui_vulkan_descriptor_sets[2] = {}; { { game_buffer_editor_create_info->set_imgui_keymap(imgui_io); imgui_io->DisplaySize.x = (float)game_buffer_editor_create_info->game_buffer->vulkan_framebuffer_image_width; imgui_io->DisplaySize.y = (float)game_buffer_editor_create_info->game_buffer->vulkan_framebuffer_image_height; imgui_io->IniFilename = game_buffer_editor_create_info->imgui_init_file; imgui_io->MousePos = {-1, -1}; { uint8 white_image_data[4 * 4 * 4]; memset(white_image_data, 0xFF, sizeof(white_image_data)); if (!vulkan_image_2d_bgra_srgb_create(game_buffer_editor_create_info->vulkan->device, &game_buffer_editor_create_info->vulkan->physical_device_memory_properties, white_image_data, 4, 4, VK_IMAGE_USAGE_SAMPLED_BIT, &imgui_white_vulkan_image)) { return false; } if (!imgui_io->Fonts->AddFontFromFileTTF(game_buffer_editor_create_info->imgui_font_file, (float)game_buffer_editor_create_info->imgui_font_size)) { return false; } unsigned char* font_atlas; int font_atlas_width; int font_atlas_height; imgui_io->Fonts->GetTexDataAsRGBA32(&font_atlas, &font_atlas_width, &font_atlas_height); if (!vulkan_image_2d_bgra_srgb_create(game_buffer_editor_create_info->vulkan->device, &game_buffer_editor_create_info->vulkan->physical_device_memory_properties, font_atlas, font_atlas_width, font_atlas_height, VK_IMAGE_USAGE_SAMPLED_BIT, &imgui_font_atlas_vulkan_image)) { return false; } imgui_io->Fonts->TexID = (void *)imgui_font_atlas_vulkan_image.image; } if (!vulkan_buffer_create(game_buffer_editor_create_info->vulkan->device, &game_buffer_editor_create_info->vulkan->physical_device_memory_properties, m_megabytes(16), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &imgui_vertex_index_vulkan_buffer)) { return false; } } { VkPipelineShaderStageCreateInfo shader_stage_create_infos[2] = { { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO }, { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO } }; shader_stage_create_infos[0].stage = VK_SHADER_STAGE_VERTEX_BIT; shader_stage_create_infos[0].module = game_buffer_editor_create_info->imgui_vulkan_shaders[0]; shader_stage_create_infos[0].pName = "main"; shader_stage_create_infos[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT; shader_stage_create_infos[1].module = game_buffer_editor_create_info->imgui_vulkan_shaders[1]; shader_stage_create_infos[1].pName = "main"; VkVertexInputBindingDescription vertex_input_binding_description = { 0, sizeof(ImDrawVert), VK_VERTEX_INPUT_RATE_VERTEX }; VkVertexInputAttributeDescription vertex_input_attribute_descriptions[3] = { { 0, 0, VK_FORMAT_R32G32_SFLOAT, 0 }, { 1, 0, VK_FORMAT_R32G32_SFLOAT, 8 }, { 2, 0, VK_FORMAT_R8G8B8A8_UNORM, 16 } }; VkPipelineVertexInputStateCreateInfo vertex_input_state_info = { VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO }; vertex_input_state_info.vertexBindingDescriptionCount = 1; vertex_input_state_info.pVertexBindingDescriptions = &vertex_input_binding_description; vertex_input_state_info.vertexAttributeDescriptionCount = m_countof(vertex_input_attribute_descriptions); vertex_input_state_info.pVertexAttributeDescriptions = vertex_input_attribute_descriptions; VkPipelineInputAssemblyStateCreateInfo input_assembly_state_info = { VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO }; input_assembly_state_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; VkPipelineViewportStateCreateInfo viewport_state_info = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO }; viewport_state_info.viewportCount = 1; viewport_state_info.scissorCount = 1; VkViewport viewport = {}; VkRect2D scissor = {}; viewport_state_info.pViewports = &viewport; viewport_state_info.pScissors = &scissor; VkPipelineRasterizationStateCreateInfo rasterization_state_info = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO }; rasterization_state_info.polygonMode = VK_POLYGON_MODE_FILL; rasterization_state_info.cullMode = VK_CULL_MODE_BACK_BIT; rasterization_state_info.frontFace = VK_FRONT_FACE_CLOCKWISE; rasterization_state_info.lineWidth = 1; VkPipelineMultisampleStateCreateInfo multisample_state_info = { VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO }; multisample_state_info.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; VkPipelineDepthStencilStateCreateInfo depth_stencil_state_info = { VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO }; VkPipelineColorBlendStateCreateInfo color_blend_state_info = { VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO }; color_blend_state_info.attachmentCount = 1; VkPipelineColorBlendAttachmentState color_blend_attachment_state = {}; color_blend_attachment_state.blendEnable = VK_TRUE; color_blend_attachment_state.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; color_blend_attachment_state.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; color_blend_attachment_state.colorBlendOp = VK_BLEND_OP_ADD; color_blend_attachment_state.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; color_blend_attachment_state.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; color_blend_attachment_state.alphaBlendOp = VK_BLEND_OP_ADD; color_blend_attachment_state.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; color_blend_state_info.pAttachments = &color_blend_attachment_state; VkPipelineDynamicStateCreateInfo dynamic_state_info = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; dynamic_state_info.dynamicStateCount = 2; VkDynamicState dynamic_states[2] = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; dynamic_state_info.pDynamicStates = dynamic_states; VkDescriptorSetLayoutBinding descriptor_set_layout_binding = { 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr }; VkDescriptorSetLayoutCreateInfo descriptor_set_layout_create_info = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO }; descriptor_set_layout_create_info.bindingCount = 1; descriptor_set_layout_create_info.pBindings = &descriptor_set_layout_binding; if ((vk_result = vkCreateDescriptorSetLayout(game_buffer_editor_create_info->vulkan->device, &descriptor_set_layout_create_info, nullptr, &imgui_vulkan_pipeline_descriptor_set_layout)) != VK_SUCCESS) { return false; } VkPipelineLayoutCreateInfo pipeline_layout_create_info = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO }; pipeline_layout_create_info.setLayoutCount = 1; pipeline_layout_create_info.pSetLayouts = &imgui_vulkan_pipeline_descriptor_set_layout; VkPushConstantRange push_constant_range = { VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(mat4) }; pipeline_layout_create_info.pushConstantRangeCount = 1; pipeline_layout_create_info.pPushConstantRanges = &push_constant_range; if((vk_result = vkCreatePipelineLayout(game_buffer_editor_create_info->vulkan->device, &pipeline_layout_create_info, nullptr, &imgui_vulkan_pipeline_layout)) != VK_SUCCESS) { return false; } VkGraphicsPipelineCreateInfo pipeline_info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO }; pipeline_info.stageCount = m_countof(shader_stage_create_infos); pipeline_info.pStages = shader_stage_create_infos; pipeline_info.pVertexInputState = &vertex_input_state_info; pipeline_info.pInputAssemblyState = &input_assembly_state_info; pipeline_info.pViewportState = &viewport_state_info; pipeline_info.pRasterizationState = &rasterization_state_info; pipeline_info.pMultisampleState = &multisample_state_info; pipeline_info.pDepthStencilState = &depth_stencil_state_info; pipeline_info.pColorBlendState = &color_blend_state_info; pipeline_info.pDynamicState = &dynamic_state_info; pipeline_info.layout = imgui_vulkan_pipeline_layout; pipeline_info.renderPass = game_buffer_editor_create_info->game_buffer->vulkan_render_pass; pipeline_info.basePipelineIndex = -1; if((vk_result = vkCreateGraphicsPipelines(game_buffer_editor_create_info->vulkan->device, VK_NULL_HANDLE, 1, &pipeline_info, nullptr, &imgui_vulkan_pipeline)) != VK_SUCCESS) { return false; } } { VkDescriptorPoolCreateInfo descriptor_pool_create_info = { VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO }; descriptor_pool_create_info.maxSets = 2; descriptor_pool_create_info.poolSizeCount = 2; VkDescriptorPoolSize descriptor_pool_sizes[2] = { { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1 }, { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1 } }; descriptor_pool_create_info.pPoolSizes = descriptor_pool_sizes; if ((vk_result = vkCreateDescriptorPool(game_buffer_editor_create_info->vulkan->device, &descriptor_pool_create_info, nullptr, &imgui_vulkan_descriptor_pool)) != VK_SUCCESS) { return false; } VkDescriptorSetAllocateInfo descriptor_set_allocate_info = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO }; descriptor_set_allocate_info.descriptorPool = imgui_vulkan_descriptor_pool; descriptor_set_allocate_info.descriptorSetCount = 2; VkDescriptorSetLayout descriptor_set_layouts[2] = { imgui_vulkan_pipeline_descriptor_set_layout, imgui_vulkan_pipeline_descriptor_set_layout }; descriptor_set_allocate_info.pSetLayouts = descriptor_set_layouts; if ((vk_result = vkAllocateDescriptorSets(game_buffer_editor_create_info->vulkan->device, &descriptor_set_allocate_info, imgui_vulkan_descriptor_sets)) != VK_SUCCESS) { return false; } VkSamplerCreateInfo sampler_create_info = { VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO }; sampler_create_info.magFilter = VK_FILTER_LINEAR; sampler_create_info.minFilter = VK_FILTER_LINEAR; sampler_create_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; sampler_create_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; sampler_create_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; sampler_create_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; VkSampler sampler = {}; if ((vk_result = vkCreateSampler(game_buffer_editor_create_info->vulkan->device, &sampler_create_info, nullptr, &sampler)) != VK_SUCCESS) { return false; } VkWriteDescriptorSet write_descriptor_sets[2] = { { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET }, { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET } }; write_descriptor_sets[0].dstSet = imgui_vulkan_descriptor_sets[0]; write_descriptor_sets[0].descriptorCount = 1; write_descriptor_sets[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; VkDescriptorImageInfo descriptor_image_info_0 = { sampler, imgui_font_atlas_vulkan_image.view, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }; write_descriptor_sets[0].pImageInfo = &descriptor_image_info_0; write_descriptor_sets[1].dstSet = imgui_vulkan_descriptor_sets[1]; write_descriptor_sets[1].descriptorCount = 1; write_descriptor_sets[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; VkDescriptorImageInfo descriptor_image_info_1 = { sampler, imgui_white_vulkan_image.view, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }; write_descriptor_sets[1].pImageInfo = &descriptor_image_info_1; vkUpdateDescriptorSets(game_buffer_editor_create_info->vulkan->device, 2, write_descriptor_sets, 0, nullptr); } } string_ring_buffer message_string_ring_buffer = {}; memory_pool job_memory_pool = {}; memory_pool job_message_memory_pool = {}; { string_ring_buffer_create(&game_buffer_editor_create_info->game_buffer->memory_arena, 256, 2048, &message_string_ring_buffer); memory_pool_create<game_buffer_editor_job>(&game_buffer_editor_create_info->game_buffer->memory_arena, 32, &job_memory_pool); memory_pool_create<game_buffer_editor_job_message>(&game_buffer_editor_create_info->game_buffer->memory_arena, 32 * 32, &job_message_memory_pool); } { game_buffer_editor->imgui_io = imgui_io; game_buffer_editor->imgui_white_vulkan_image = imgui_white_vulkan_image; game_buffer_editor->imgui_font_atlas_vulkan_image = imgui_font_atlas_vulkan_image; game_buffer_editor->imgui_vertex_index_vulkan_buffer = imgui_vertex_index_vulkan_buffer; game_buffer_editor->imgui_vulkan_pipeline = imgui_vulkan_pipeline; game_buffer_editor->imgui_vulkan_pipeline_layout = imgui_vulkan_pipeline_layout; game_buffer_editor->imgui_vulkan_descriptor_pool = imgui_vulkan_descriptor_pool; m_array_assign(game_buffer_editor->imgui_vulkan_descriptor_sets, imgui_vulkan_descriptor_sets); game_buffer_editor->message_string_ring_buffer = message_string_ring_buffer; game_buffer_editor->job_memory_pool = job_memory_pool; game_buffer_editor->job_message_memory_pool = job_message_memory_pool; } return true; }
void preparePipelines() { VkResult err; VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = vkTools::initializers::pipelineInputAssemblyStateCreateInfo( VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, 0, VK_FALSE); VkPipelineRasterizationStateCreateInfo rasterizationState = vkTools::initializers::pipelineRasterizationStateCreateInfo( VK_POLYGON_MODE_FILL, VK_CULL_MODE_NONE, VK_FRONT_FACE_COUNTER_CLOCKWISE, 0); VkPipelineColorBlendAttachmentState blendAttachmentState = vkTools::initializers::pipelineColorBlendAttachmentState( 0xf, VK_FALSE); VkPipelineColorBlendStateCreateInfo colorBlendState = vkTools::initializers::pipelineColorBlendStateCreateInfo( 1, &blendAttachmentState); VkPipelineDepthStencilStateCreateInfo depthStencilState = vkTools::initializers::pipelineDepthStencilStateCreateInfo( VK_TRUE, VK_TRUE, VK_COMPARE_OP_LESS_OR_EQUAL); VkPipelineViewportStateCreateInfo viewportState = vkTools::initializers::pipelineViewportStateCreateInfo(1, 1, 0); VkPipelineMultisampleStateCreateInfo multisampleState = vkTools::initializers::pipelineMultisampleStateCreateInfo( VK_SAMPLE_COUNT_1_BIT, 0); std::vector<VkDynamicState> dynamicStateEnables = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, VK_DYNAMIC_STATE_LINE_WIDTH }; VkPipelineDynamicStateCreateInfo dynamicState = vkTools::initializers::pipelineDynamicStateCreateInfo( dynamicStateEnables.data(), dynamicStateEnables.size(), 0); VkPipelineTessellationStateCreateInfo tessellationState = vkTools::initializers::pipelineTessellationStateCreateInfo(3); // Tessellation pipeline // Load shaders std::array<VkPipelineShaderStageCreateInfo, 4> shaderStages; shaderStages[0] = loadShader(getAssetPath() + "shaders/displacement/base.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); shaderStages[1] = loadShader(getAssetPath() + "shaders/displacement/base.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); shaderStages[2] = loadShader(getAssetPath() + "shaders/displacement/displacement.tesc.spv", VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT); shaderStages[3] = loadShader(getAssetPath() + "shaders/displacement/displacement.tese.spv", VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT); VkGraphicsPipelineCreateInfo pipelineCreateInfo = vkTools::initializers::pipelineCreateInfo( pipelineLayout, renderPass, 0); pipelineCreateInfo.pVertexInputState = &vertices.inputState; pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState; pipelineCreateInfo.pRasterizationState = &rasterizationState; pipelineCreateInfo.pColorBlendState = &colorBlendState; pipelineCreateInfo.pMultisampleState = &multisampleState; pipelineCreateInfo.pViewportState = &viewportState; pipelineCreateInfo.pDepthStencilState = &depthStencilState; pipelineCreateInfo.pDynamicState = &dynamicState; pipelineCreateInfo.pTessellationState = &tessellationState; pipelineCreateInfo.stageCount = shaderStages.size(); pipelineCreateInfo.pStages = shaderStages.data(); pipelineCreateInfo.renderPass = renderPass; // Solid pipeline err = vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.solid); assert(!err); // Wireframe pipeline rasterizationState.polygonMode = VK_POLYGON_MODE_LINE; err = vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.wire); assert(!err); // Pass through pipelines // Load pass through tessellation shaders (Vert and frag are reused) shaderStages[2] = loadShader(getAssetPath() + "shaders/displacement/passthrough.tesc.spv", VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT); shaderStages[3] = loadShader(getAssetPath() + "shaders/displacement/passthrough.tese.spv", VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT); // Solid rasterizationState.polygonMode = VK_POLYGON_MODE_FILL; err = vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.solidPassThrough); assert(!err); // Wireframe rasterizationState.polygonMode = VK_POLYGON_MODE_LINE; err = vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.wirePassThrough); assert(!err); }
void SkinningAppVk::initRendering(void) { setGLDrawCallbacks(this); VkResult result = VK_ERROR_INITIALIZATION_FAILED; NvAssetLoaderAddSearchPath("vk10-kepler/SkinningAppVk"); mMesh.initRendering(vk()); SkinnedMesh::UBOBlock& ubo = *mMesh.mUBO; ubo.mRenderMode[2] = 0; ubo.mLightDir0 = nv::vec4f(0.267f, 0.535f, 0.802f, 0.0f); ubo.mLightDir1 = nv::vec4f(-0.408f, 0.816f, -0.408f, 0.0f); mMesh.mUBO.Update(); VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO }; pipelineLayoutCreateInfo.setLayoutCount = 1; pipelineLayoutCreateInfo.pSetLayouts = &mMesh.mDescriptorSetLayout; result = vkCreatePipelineLayout(device(), &pipelineLayoutCreateInfo, 0, &mPipelineLayout); CHECK_VK_RESULT(); // Create static state info for the mPipeline. // set dynamically VkPipelineViewportStateCreateInfo vpStateInfo = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO }; vpStateInfo.pNext = 0; vpStateInfo.viewportCount = 1; vpStateInfo.scissorCount = 1; VkPipelineRasterizationStateCreateInfo rsStateInfo = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO }; rsStateInfo.depthClampEnable = VK_TRUE; rsStateInfo.rasterizerDiscardEnable = VK_FALSE; rsStateInfo.polygonMode = VK_POLYGON_MODE_FILL; rsStateInfo.cullMode = VK_CULL_MODE_BACK_BIT; rsStateInfo.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; VkPipelineColorBlendAttachmentState attachments[1] = {}; attachments[0].blendEnable = VK_FALSE; attachments[0].colorWriteMask = ~0; VkPipelineColorBlendStateCreateInfo cbStateInfo = { VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO }; cbStateInfo.logicOpEnable = VK_FALSE; cbStateInfo.attachmentCount = ARRAY_SIZE(attachments); cbStateInfo.pAttachments = attachments; VkPipelineDepthStencilStateCreateInfo dsStateInfo = { VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO }; dsStateInfo.depthTestEnable = VK_TRUE; dsStateInfo.depthWriteEnable = VK_TRUE; dsStateInfo.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL; dsStateInfo.depthBoundsTestEnable = VK_FALSE; dsStateInfo.stencilTestEnable = VK_FALSE; dsStateInfo.minDepthBounds = 0.0f; dsStateInfo.maxDepthBounds = 1.0f; VkPipelineMultisampleStateCreateInfo msStateInfo = { VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO }; msStateInfo.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; msStateInfo.alphaToCoverageEnable = VK_FALSE; msStateInfo.sampleShadingEnable = VK_FALSE; msStateInfo.minSampleShading = 1.0f; uint32_t smplMask = 0x1; msStateInfo.pSampleMask = &smplMask; VkPipelineTessellationStateCreateInfo tessStateInfo = { VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO }; tessStateInfo.patchControlPoints = 0; VkPipelineDynamicStateCreateInfo dynStateInfo; VkDynamicState dynStates[] = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; memset(&dynStateInfo, 0, sizeof(dynStateInfo)); dynStateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; dynStateInfo.dynamicStateCount = 2; dynStateInfo.pDynamicStates = dynStates; // Shaders VkPipelineShaderStageCreateInfo shaderStages[2]; uint32_t shaderCount = 0; #ifdef SOURCE_SHADERS shaderCount = vk().createShadersFromSourceFile( NvAssetLoadTextFile("src_shaders/skinning.glsl"), shaderStages, 2); #else { int32_t length; char* data = NvAssetLoaderRead("shaders/skinning.nvs", length); shaderCount = vk().createShadersFromBinaryFile((uint32_t*)data, length, shaderStages, 2); } #endif // Create mPipeline state VI-IA-VS-VP-RS-FS-CB VkGraphicsPipelineCreateInfo pipelineInfo = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO }; pipelineInfo.pVertexInputState = &mMesh.mVIStateInfo; pipelineInfo.pInputAssemblyState = &mMesh.mIAStateInfo; pipelineInfo.pViewportState = &vpStateInfo; pipelineInfo.pRasterizationState = &rsStateInfo; pipelineInfo.pColorBlendState = &cbStateInfo; pipelineInfo.pDepthStencilState = &dsStateInfo; pipelineInfo.pMultisampleState = &msStateInfo; pipelineInfo.pTessellationState = &tessStateInfo; pipelineInfo.pDynamicState = &dynStateInfo; pipelineInfo.stageCount = shaderCount; pipelineInfo.pStages = shaderStages; pipelineInfo.renderPass = vk().mainRenderTarget()->clearRenderPass(); pipelineInfo.subpass = 0; pipelineInfo.layout = mPipelineLayout; result = vkCreateGraphicsPipelines(device(), VK_NULL_HANDLE, 1, &pipelineInfo, NULL, &mPipeline); CHECK_VK_RESULT(); mMesh.UpdateDescriptorSet(vk()); }