1 /* 2 * Copyright 2016 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "GrVkCopyPipeline.h" 9 10 #include "GrVkGpu.h" 11 #include "GrVkUtil.h" 12 #include "SkOnce.h" 13 14 #if defined(SK_ENABLE_SCOPED_LSAN_SUPPRESSIONS) 15 #include <sanitizer/lsan_interface.h> 16 #endif 17 18 static void setup_multisample_state(int numSamples, 19 VkPipelineMultisampleStateCreateInfo* multisampleInfo) { 20 memset(multisampleInfo, 0, sizeof(VkPipelineMultisampleStateCreateInfo)); 21 multisampleInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; 22 multisampleInfo->pNext = nullptr; 23 multisampleInfo->flags = 0; 24 SkAssertResult(GrSampleCountToVkSampleCount(numSamples, 25 &multisampleInfo->rasterizationSamples)); 26 multisampleInfo->sampleShadingEnable = VK_FALSE; 27 multisampleInfo->minSampleShading = 0.0f; 28 multisampleInfo->pSampleMask = nullptr; 29 multisampleInfo->alphaToCoverageEnable = VK_FALSE; 30 multisampleInfo->alphaToOneEnable = VK_FALSE; 31 } 32 33 GrVkCopyPipeline* GrVkCopyPipeline::Create(GrVkGpu* gpu, 34 VkPipelineShaderStageCreateInfo* shaderStageInfo, 35 VkPipelineLayout pipelineLayout, 36 int numSamples, 37 const GrVkRenderPass& renderPass, 38 VkPipelineCache cache) { 39 40 static const VkVertexInputAttributeDescription attributeDesc = { 41 0, // location 42 0, // binding 43 VK_FORMAT_R32G32_SFLOAT, // format 44 0, // offset 45 }; 46 47 static const VkVertexInputBindingDescription bindingDesc = { 48 0, // binding 49 2 * sizeof(float), // stride 50 VK_VERTEX_INPUT_RATE_VERTEX // inputRate 51 }; 52 53 static const VkPipelineVertexInputStateCreateInfo vertexInputInfo = { 54 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // sType 55 nullptr, // pNext 56 0, // flags 57 1, // vertexBindingDescriptionCount 58 &bindingDesc, // pVertexBindingDescriptions 59 1, // vertexAttributeDescriptionCnt 60 &attributeDesc, // pVertexAttributeDescriptions 61 }; 62 63 static const VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo = { 64 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // sType 65 nullptr, // pNext 66 0, // flags 67 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // topology 68 VK_FALSE // primitiveRestartEnable 69 }; 70 71 static const VkStencilOpState dummyStencilState = { 72 VK_STENCIL_OP_KEEP, // failOp 73 VK_STENCIL_OP_KEEP, // passOp 74 VK_STENCIL_OP_KEEP, // depthFailOp 75 VK_COMPARE_OP_NEVER, // compareOp 76 0, // compareMask 77 0, // writeMask 78 0 // reference 79 }; 80 81 static const VkPipelineDepthStencilStateCreateInfo stencilInfo = { 82 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // sType 83 nullptr, // pNext 84 0, // flags 85 VK_FALSE, // depthTestEnable 86 VK_FALSE, // depthWriteEnable 87 VK_COMPARE_OP_ALWAYS, // depthCompareOp 88 VK_FALSE, // depthBoundsTestEnable 89 VK_FALSE, // stencilTestEnable 90 dummyStencilState, // front 91 dummyStencilState, // bakc 92 0.0f, // minDepthBounds 93 1.0f // maxDepthBounds 94 }; 95 96 static const VkPipelineViewportStateCreateInfo viewportInfo = { 97 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // sType 98 nullptr, // pNext 99 0, // flags 100 1, // viewportCount 101 nullptr, // pViewports 102 1, // scissorCount 103 nullptr // pScissors 104 }; 105 106 static const VkPipelineColorBlendAttachmentState attachmentState = { 107 VK_FALSE, // blendEnable 108 VK_BLEND_FACTOR_ONE, // srcColorBlendFactor 109 VK_BLEND_FACTOR_ZERO, // dstColorBlendFactor 110 VK_BLEND_OP_ADD, // colorBlendOp 111 VK_BLEND_FACTOR_ONE, // srcAlphaBlendFactor 112 VK_BLEND_FACTOR_ZERO, // dstAlphaBlendFactor 113 VK_BLEND_OP_ADD, // alphaBlendOp 114 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | // colorWriteMask 115 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT // colorWriteMask 116 }; 117 118 static const VkPipelineColorBlendStateCreateInfo colorBlendInfo = { 119 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // sType 120 nullptr, // pNext 121 0, // flags 122 VK_FALSE, // logicOpEnable 123 VK_LOGIC_OP_CLEAR, // logicOp 124 1, // attachmentCount 125 &attachmentState, // pAttachments 126 { 0.f, 0.f, 0.f, 0.f } // blendConstants[4] 127 }; 128 129 static const VkPipelineRasterizationStateCreateInfo rasterInfo = { 130 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // sType 131 nullptr, // pNext 132 0, // flags 133 VK_FALSE, // depthClampEnable 134 VK_FALSE, // rasterizerDiscardEnabled 135 VK_POLYGON_MODE_FILL, // polygonMode 136 VK_CULL_MODE_NONE, // cullMode 137 VK_FRONT_FACE_COUNTER_CLOCKWISE, // frontFace 138 VK_FALSE, // depthBiasEnable 139 0.0f, // depthBiasConstantFactor 140 0.0f, // depthBiasClamp 141 0.0f, // depthBiasSlopeFactor 142 1.0f // lineWidth 143 }; 144 145 static const VkDynamicState dynamicStates[2] = { VK_DYNAMIC_STATE_VIEWPORT, 146 VK_DYNAMIC_STATE_SCISSOR }; 147 static const VkPipelineDynamicStateCreateInfo dynamicInfo = { 148 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // sType 149 nullptr, // pNext 150 0, // flags 151 2, // dynamicStateCount 152 dynamicStates // pDynamicStates 153 }; 154 155 VkPipelineMultisampleStateCreateInfo multisampleInfo; 156 setup_multisample_state(numSamples, &multisampleInfo); 157 158 VkGraphicsPipelineCreateInfo pipelineCreateInfo; 159 memset(&pipelineCreateInfo, 0, sizeof(VkGraphicsPipelineCreateInfo)); 160 pipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; 161 pipelineCreateInfo.pNext = nullptr; 162 pipelineCreateInfo.flags = 0; 163 pipelineCreateInfo.stageCount = 2; 164 pipelineCreateInfo.pStages = shaderStageInfo; 165 pipelineCreateInfo.pVertexInputState = &vertexInputInfo; 166 pipelineCreateInfo.pInputAssemblyState = &inputAssemblyInfo; 167 pipelineCreateInfo.pTessellationState = nullptr; 168 pipelineCreateInfo.pViewportState = &viewportInfo; 169 pipelineCreateInfo.pRasterizationState = &rasterInfo; 170 pipelineCreateInfo.pMultisampleState = &multisampleInfo; 171 pipelineCreateInfo.pDepthStencilState = &stencilInfo; 172 pipelineCreateInfo.pColorBlendState = &colorBlendInfo; 173 pipelineCreateInfo.pDynamicState = &dynamicInfo; 174 pipelineCreateInfo.layout = pipelineLayout; 175 pipelineCreateInfo.renderPass = renderPass.vkRenderPass(); 176 pipelineCreateInfo.subpass = 0; 177 pipelineCreateInfo.basePipelineHandle = VK_NULL_HANDLE; 178 pipelineCreateInfo.basePipelineIndex = -1; 179 180 VkPipeline vkPipeline; 181 VkResult err; 182 { 183 #if defined(SK_ENABLE_SCOPED_LSAN_SUPPRESSIONS) 184 // skia:8712 185 __lsan::ScopedDisabler lsanDisabler; 186 #endif 187 err = GR_VK_CALL(gpu->vkInterface(), CreateGraphicsPipelines(gpu->device(), 188 cache, 1, 189 &pipelineCreateInfo, 190 nullptr, &vkPipeline)); 191 } 192 if (err) { 193 SkDebugf("Failed to create copy pipeline. Error: %d\n", err); 194 return nullptr; 195 } 196 197 return new GrVkCopyPipeline(vkPipeline, &renderPass); 198 } 199 200 bool GrVkCopyPipeline::isCompatible(const GrVkRenderPass& rp) const { 201 return rp.isCompatible(*fRenderPass); 202 } 203