src/ngfx/porting/vulkan/VKGraphicsPipeline.cpp

Attributes

Name
std::map< VertexFormat, uint32_t > strideMap

Attributes Documentation

variable strideMap

static std::map< VertexFormat, uint32_t > strideMap = {{VERTEXFORMAT_FLOAT, 4},
                                                     {VERTEXFORMAT_FLOAT2, 8},
                                                     {VERTEXFORMAT_FLOAT3, 12},
                                                     {VERTEXFORMAT_FLOAT4, 16}};

Source code

/*
 * Copyright 2020 GoPro Inc.
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
#include "ngfx/porting/vulkan/VKGraphicsPipeline.h"
#include "ngfx/graphics/CommandBuffer.h"
#include "ngfx/graphics/GraphicsContext.h"
#include "ngfx/porting/vulkan/VKDebugUtil.h"
#include "ngfx/porting/vulkan/VKGraphicsContext.h"
#include "ngfx/porting/vulkan/VKShaderModule.h"
#include <vector>
using namespace ngfx;

void VKGraphicsPipeline::create(
    VKGraphicsContext *ctx, const State &state,
    const std::vector<VKPipeline::Descriptor> &descriptors,
    const std::vector<VkVertexInputBindingDescription> &vertexInputBindings,
    const std::vector<VkVertexInputAttributeDescription> &vertexInputAttributes,
    const std::vector<VKPipeline::ShaderStage> &shaderStages,
    VkFormat colorFormat) {
  this->device = vk(ctx->device)->v;
  VkResult vkResult;

  inputAssemblyState = {
      VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0,
      state.primitiveTopology, VK_FALSE};

  rasterizationState = {
      VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
      nullptr,
      0,
      VK_FALSE,
      VK_FALSE,
      state.polygonMode,
      state.cullModeFlags,
      state.frontFace,
      VK_FALSE,
      0.0f,
      0.0f,
      0.0f,
      state.lineWidth};
  blendAttachmentState.resize(state.numColorAttachments);
  for (auto &pState : blendAttachmentState)
    pState = {state.blendEnable,         state.srcColorBlendFactor,
              state.dstColorBlendFactor, state.colorBlendOp,
              state.srcColorBlendFactor, state.dstColorBlendFactor,
              state.alphaBlendOp,        state.colorWriteMask};
  colorBlendState = {VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
                     nullptr,
                     0,
                     VK_FALSE,
                     VK_LOGIC_OP_CLEAR,
                     uint32_t(blendAttachmentState.size()),
                     blendAttachmentState.data(),
                     {0.0f, 0.0f, 0.0f, 0.0f}};
  viewportState = {VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
                   nullptr,
                   0,
                   1,
                   nullptr,
                   1,
                   nullptr};
  dynamicStateEnables = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
  dynamicState = {VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, nullptr,
                  0, uint32_t(dynamicStateEnables.size()),
                  dynamicStateEnables.data()};

  depthStencilState = {
      VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
      nullptr,
      0,
      state.depthTestEnable,
      state.depthWriteEnable,
      VK_COMPARE_OP_LESS,
      VK_FALSE,
      VK_FALSE,
      {VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP,
       VK_COMPARE_OP_NEVER, 0, 0, 0},
      {VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP,
       VK_COMPARE_OP_NEVER, 0, 0, 0},
      0.0f,
      0.0f};

  multisampleState = {VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
                      nullptr,
                      0,
                      VkSampleCountFlagBits(state.numSamples),
                      VK_FALSE,
                      0.0f,
                      nullptr,
                      VK_FALSE,
                      VK_FALSE};

  vertexInputState = {VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
                      nullptr,
                      0,
                      uint32_t(vertexInputBindings.size()),
                      vertexInputBindings.data(),
                      uint32_t(vertexInputAttributes.size()),
                      vertexInputAttributes.data()};

  vkShaderStages.resize(shaderStages.size());
  for (int j = 0; j < shaderStages.size(); j++) {
    auto &shaderStage = shaderStages[j];
    vkShaderStages[j] = {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
                         nullptr,
                         0,
                         shaderStage.stage,
                         shaderStage.module->v,
                         "main",
                         nullptr};
  }
  descriptorSetLayouts.resize(descriptors.size());
  for (int j = 0; j < descriptors.size(); j++) {
    auto &descriptor = descriptors[j];
    descriptorSetLayouts[j] = ctx->vkDescriptorSetLayoutCache.get(
        descriptor.type, descriptor.stageFlags);
  }
  pipelineLayoutCreateInfo = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
                              nullptr,
                              0,
                              uint32_t(descriptorSetLayouts.size()),
                              descriptorSetLayouts.data(),
                              0,
                              nullptr};
  V(vkCreatePipelineLayout(device, &pipelineLayoutCreateInfo, nullptr,
                           &pipelineLayout));

  createInfo = {VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
                nullptr,
                0,
                static_cast<uint32_t>(vkShaderStages.size()),
                vkShaderStages.data(),
                &vertexInputState,
                &inputAssemblyState,
                nullptr,
                &viewportState,
                &rasterizationState,
                &multisampleState,
                &depthStencilState,
                &colorBlendState,
                &dynamicState,
                pipelineLayout,
                state.renderPass,
                0,
                0,
                0};
  V(vkCreateGraphicsPipelines(device, ctx->vkPipelineCache.v, 1, &createInfo,
                              nullptr, &v));
}

static std::map<VertexFormat, uint32_t> strideMap = {{VERTEXFORMAT_FLOAT, 4},
                                                     {VERTEXFORMAT_FLOAT2, 8},
                                                     {VERTEXFORMAT_FLOAT3, 12},
                                                     {VERTEXFORMAT_FLOAT4, 16}};
GraphicsPipeline *
GraphicsPipeline::create(GraphicsContext *graphicsContext, const State &state,
                         VertexShaderModule *vs, FragmentShaderModule *fs,
                         PixelFormat colorFormat, PixelFormat depthFormat,
                         std::set<std::string> instanceAttributes) {
  VKGraphicsPipeline *vkGraphicsPipeline = new VKGraphicsPipeline();
  VKGraphicsPipeline::State vkState = {
      VkPrimitiveTopology(state.primitiveTopology),
      VkPolygonMode(state.polygonMode),
      state.blendEnable,
      VkBlendFactor(state.srcColorBlendFactor),
      VkBlendFactor(state.dstColorBlendFactor),
      VkBlendFactor(state.srcAlphaBlendFactor),
      VkBlendFactor(state.dstAlphaBlendFactor),
      VkBlendOp(state.colorBlendOp),
      VkBlendOp(state.alphaBlendOp),
      VkColorComponentFlags(state.colorWriteMask),
      VkCullModeFlags(state.cullModeFlags),
      VkFrontFace(state.frontFace),
      state.lineWidth,
      state.depthTestEnable,
      state.depthWriteEnable,
      vk(state.renderPass)->v,
      state.numSamples,
      state.numColorAttachments};
  auto &descriptorBindings = vkGraphicsPipeline->descriptorBindings;

  uint32_t numDescriptors =
      glm::max(vs->descriptors.empty() ? 0 : vs->descriptors.back().set + 1,
               fs->descriptors.empty() ? 0 : fs->descriptors.back().set + 1);
  descriptorBindings.resize(numDescriptors);
  std::vector<VKPipeline::Descriptor> vkDescriptors(numDescriptors);
  VKPipelineUtil::parseDescriptors(vs->descriptors, VK_SHADER_STAGE_VERTEX_BIT,
                                   vkDescriptors, descriptorBindings);
  VKPipelineUtil::parseDescriptors(fs->descriptors,
                                   VK_SHADER_STAGE_FRAGMENT_BIT, vkDescriptors,
                                   descriptorBindings);

  std::vector<VkVertexInputAttributeDescription> vkVertexInputAttributes;
  auto &vertexAttributeBindings = vkGraphicsPipeline->vertexAttributeBindings;
  vertexAttributeBindings.resize(vs->attributes.size());
  // TODO: support interleaved vertex bindings
  for (uint32_t j = 0; j < vs->attributes.size(); j++) {
    auto &va = vs->attributes[j];
    uint32_t binding = va.location, offset = 0;
    for (uint32_t k = 0; k < va.count; k++) {
      vkVertexInputAttributes.push_back(
          {va.location + k, binding, VkFormat(va.format), offset});
      offset += va.elementSize;
    }
    vertexAttributeBindings[j] = j;
  }
  std::vector<VKPipeline::ShaderStage> vkShaderStages = {
      {VK_SHADER_STAGE_VERTEX_BIT, (VKVertexShaderModule *)vs},
      {VK_SHADER_STAGE_FRAGMENT_BIT, (VKFragmentShaderModule *)fs}};
  std::vector<VkVertexInputBindingDescription> vkVertexInputBindings(
      vs->attributes.size());
  for (uint32_t j = 0; j < vs->attributes.size(); j++) {
    auto &attr = vs->attributes[j];
    uint32_t binding = attr.location;
    VkVertexInputRate inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
    if (instanceAttributes.find(attr.name) != instanceAttributes.end())
      inputRate = VK_VERTEX_INPUT_RATE_INSTANCE;
    vkVertexInputBindings[j] = {binding, attr.elementSize * attr.count,
                                inputRate};
  }
  vkGraphicsPipeline->create(vk(graphicsContext), vkState, vkDescriptors,
                             vkVertexInputBindings, vkVertexInputAttributes,
                             vkShaderStages, VkFormat(colorFormat));
  return vkGraphicsPipeline;
}

Updated on 3 April 2021 at 20:21:52 PDT