/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "GrVkCopyPipeline.h"
#include "GrVkGpu.h"
#include "GrVkUtil.h"
#include "SkOnce.h"
static void setup_multisample_state(int numSamples,
VkPipelineMultisampleStateCreateInfo* multisampleInfo) {
memset(multisampleInfo, 0, sizeof(VkPipelineMultisampleStateCreateInfo));
multisampleInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
multisampleInfo->pNext = nullptr;
multisampleInfo->flags = 0;
SkAssertResult(GrSampleCountToVkSampleCount(numSamples,
&multisampleInfo->rasterizationSamples));
multisampleInfo->sampleShadingEnable = VK_FALSE;
multisampleInfo->minSampleShading = 0.0f;
multisampleInfo->pSampleMask = nullptr;
multisampleInfo->alphaToCoverageEnable = VK_FALSE;
multisampleInfo->alphaToOneEnable = VK_FALSE;
}
GrVkCopyPipeline* GrVkCopyPipeline::Create(GrVkGpu* gpu,
VkPipelineShaderStageCreateInfo* shaderStageInfo,
VkPipelineLayout pipelineLayout,
int numSamples,
const GrVkRenderPass& renderPass,
VkPipelineCache cache) {
static const VkVertexInputAttributeDescription attributeDesc = {
0, // location
0, // binding
VK_FORMAT_R32G32_SFLOAT, // format
0, // offset
};
static const VkVertexInputBindingDescription bindingDesc = {
0, // binding
2 * sizeof(float), // stride
VK_VERTEX_INPUT_RATE_VERTEX // inputRate
};
static const VkPipelineVertexInputStateCreateInfo vertexInputInfo = {
VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // sType
nullptr, // pNext
0, // flags
1, // vertexBindingDescriptionCount
&bindingDesc, // pVertexBindingDescriptions
1, // vertexAttributeDescriptionCnt
&attributeDesc, // pVertexAttributeDescriptions
};
static const VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo = {
VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // sType
nullptr, // pNext
0, // flags
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // topology
VK_FALSE // primitiveRestartEnable
};
static const VkStencilOpState dummyStencilState = {
VK_STENCIL_OP_KEEP, // failOp
VK_STENCIL_OP_KEEP, // passOp
VK_STENCIL_OP_KEEP, // depthFailOp
VK_COMPARE_OP_NEVER, // compareOp
0, // compareMask
0, // writeMask
0 // reference
};
static const VkPipelineDepthStencilStateCreateInfo stencilInfo = {
VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // sType
nullptr, // pNext
0, // flags
VK_FALSE, // depthTestEnable
VK_FALSE, // depthWriteEnable
VK_COMPARE_OP_ALWAYS, // depthCompareOp
VK_FALSE, // depthBoundsTestEnable
VK_FALSE, // stencilTestEnable
dummyStencilState, // front
dummyStencilState, // bakc
0.0f, // minDepthBounds
1.0f // maxDepthBounds
};
static const VkPipelineViewportStateCreateInfo viewportInfo = {
VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // sType
nullptr, // pNext
0, // flags
1, // viewportCount
nullptr, // pViewports
1, // scissorCount
nullptr // pScissors
};
static const VkPipelineColorBlendAttachmentState attachmentState = {
VK_TRUE, // belndEnable
VK_BLEND_FACTOR_ONE, // srcColorBlendFactor
VK_BLEND_FACTOR_ZERO, // dstColorBlendFactor
VK_BLEND_OP_ADD, // colorBlendOp
VK_BLEND_FACTOR_ONE, // srcAlphaBlendFactor
VK_BLEND_FACTOR_ZERO, // dstAlphaBlendFactor
VK_BLEND_OP_ADD, // alphaBlendOp
VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | // colorWriteMask
VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT // colorWriteMask
};
static const VkPipelineColorBlendStateCreateInfo colorBlendInfo = {
VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // sType
nullptr, // pNext
0, // flags
VK_FALSE, // logicOpEnable
VK_LOGIC_OP_CLEAR, // logicOp
1, // attachmentCount
&attachmentState, // pAttachments
{ 0.f, 0.f, 0.f, 0.f } // blendConstants[4]
};
static const VkPipelineRasterizationStateCreateInfo rasterInfo = {
VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // sType
nullptr, // pNext
0, // flags
VK_FALSE, // depthClampEnable
VK_FALSE, // rasterizerDiscardEnabled
VK_POLYGON_MODE_FILL, // polygonMode
VK_CULL_MODE_NONE, // cullMode
VK_FRONT_FACE_COUNTER_CLOCKWISE, // frontFace
VK_FALSE, // depthBiasEnable
0.0f, // depthBiasConstantFactor
0.0f, // depthBiasClamp
0.0f, // depthBiasSlopeFactor
1.0f // lineWidth
};
static const VkDynamicState dynamicStates[2] = { VK_DYNAMIC_STATE_VIEWPORT,
VK_DYNAMIC_STATE_SCISSOR };
static const VkPipelineDynamicStateCreateInfo dynamicInfo = {
VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // sType
nullptr, // pNext
0, // flags
2, // dynamicStateCount
dynamicStates // pDynamicStates
};
VkPipelineMultisampleStateCreateInfo multisampleInfo;
setup_multisample_state(numSamples, &multisampleInfo);
VkGraphicsPipelineCreateInfo pipelineCreateInfo;
memset(&pipelineCreateInfo, 0, sizeof(VkGraphicsPipelineCreateInfo));
pipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
pipelineCreateInfo.pNext = nullptr;
pipelineCreateInfo.flags = 0;
pipelineCreateInfo.stageCount = 2;
pipelineCreateInfo.pStages = shaderStageInfo;
pipelineCreateInfo.pVertexInputState = &vertexInputInfo;
pipelineCreateInfo.pInputAssemblyState = &inputAssemblyInfo;
pipelineCreateInfo.pTessellationState = nullptr;
pipelineCreateInfo.pViewportState = &viewportInfo;
pipelineCreateInfo.pRasterizationState = &rasterInfo;
pipelineCreateInfo.pMultisampleState = &multisampleInfo;
pipelineCreateInfo.pDepthStencilState = &stencilInfo;
pipelineCreateInfo.pColorBlendState = &colorBlendInfo;
pipelineCreateInfo.pDynamicState = &dynamicInfo;
pipelineCreateInfo.layout = pipelineLayout;
pipelineCreateInfo.renderPass = renderPass.vkRenderPass();
pipelineCreateInfo.subpass = 0;
pipelineCreateInfo.basePipelineHandle = VK_NULL_HANDLE;
pipelineCreateInfo.basePipelineIndex = -1;
VkPipeline vkPipeline;
VkResult err = GR_VK_CALL(gpu->vkInterface(), CreateGraphicsPipelines(gpu->device(),
cache, 1,
&pipelineCreateInfo,
nullptr, &vkPipeline));
if (err) {
return nullptr;
}
return new GrVkCopyPipeline(vkPipeline, &renderPass);
}
bool GrVkCopyPipeline::isCompatible(const GrVkRenderPass& rp) const {
return rp.isCompatible(*fRenderPass);
}