1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci* Copyright 2016 Google Inc. 3cb93a386Sopenharmony_ci* 4cb93a386Sopenharmony_ci* Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci* found in the LICENSE file. 6cb93a386Sopenharmony_ci*/ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkPipeline.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include "src/core/SkTraceEvent.h" 11cb93a386Sopenharmony_ci#include "src/gpu/GrGeometryProcessor.h" 12cb93a386Sopenharmony_ci#include "src/gpu/GrPipeline.h" 13cb93a386Sopenharmony_ci#include "src/gpu/GrStencilSettings.h" 14cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkCommandBuffer.h" 15cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkGpu.h" 16cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkRenderTarget.h" 17cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkUtil.h" 18cb93a386Sopenharmony_ci 19cb93a386Sopenharmony_ci#if defined(SK_ENABLE_SCOPED_LSAN_SUPPRESSIONS) 20cb93a386Sopenharmony_ci#include <sanitizer/lsan_interface.h> 21cb93a386Sopenharmony_ci#endif 22cb93a386Sopenharmony_ci 23cb93a386Sopenharmony_cistatic inline VkFormat attrib_type_to_vkformat(GrVertexAttribType type) { 24cb93a386Sopenharmony_ci switch (type) { 25cb93a386Sopenharmony_ci case kFloat_GrVertexAttribType: 26cb93a386Sopenharmony_ci return VK_FORMAT_R32_SFLOAT; 27cb93a386Sopenharmony_ci case kFloat2_GrVertexAttribType: 28cb93a386Sopenharmony_ci return VK_FORMAT_R32G32_SFLOAT; 29cb93a386Sopenharmony_ci case kFloat3_GrVertexAttribType: 30cb93a386Sopenharmony_ci return VK_FORMAT_R32G32B32_SFLOAT; 31cb93a386Sopenharmony_ci case kFloat4_GrVertexAttribType: 32cb93a386Sopenharmony_ci return VK_FORMAT_R32G32B32A32_SFLOAT; 33cb93a386Sopenharmony_ci case kHalf_GrVertexAttribType: 34cb93a386Sopenharmony_ci return VK_FORMAT_R16_SFLOAT; 35cb93a386Sopenharmony_ci case kHalf2_GrVertexAttribType: 36cb93a386Sopenharmony_ci return VK_FORMAT_R16G16_SFLOAT; 37cb93a386Sopenharmony_ci case kHalf4_GrVertexAttribType: 38cb93a386Sopenharmony_ci return VK_FORMAT_R16G16B16A16_SFLOAT; 39cb93a386Sopenharmony_ci case kInt2_GrVertexAttribType: 40cb93a386Sopenharmony_ci return VK_FORMAT_R32G32_SINT; 41cb93a386Sopenharmony_ci case kInt3_GrVertexAttribType: 42cb93a386Sopenharmony_ci return VK_FORMAT_R32G32B32_SINT; 43cb93a386Sopenharmony_ci case kInt4_GrVertexAttribType: 44cb93a386Sopenharmony_ci return VK_FORMAT_R32G32B32A32_SINT; 45cb93a386Sopenharmony_ci case kByte_GrVertexAttribType: 46cb93a386Sopenharmony_ci return VK_FORMAT_R8_SINT; 47cb93a386Sopenharmony_ci case kByte2_GrVertexAttribType: 48cb93a386Sopenharmony_ci return VK_FORMAT_R8G8_SINT; 49cb93a386Sopenharmony_ci case kByte4_GrVertexAttribType: 50cb93a386Sopenharmony_ci return VK_FORMAT_R8G8B8A8_SINT; 51cb93a386Sopenharmony_ci case kUByte_GrVertexAttribType: 52cb93a386Sopenharmony_ci return VK_FORMAT_R8_UINT; 53cb93a386Sopenharmony_ci case kUByte2_GrVertexAttribType: 54cb93a386Sopenharmony_ci return VK_FORMAT_R8G8_UINT; 55cb93a386Sopenharmony_ci case kUByte4_GrVertexAttribType: 56cb93a386Sopenharmony_ci return VK_FORMAT_R8G8B8A8_UINT; 57cb93a386Sopenharmony_ci case kUByte_norm_GrVertexAttribType: 58cb93a386Sopenharmony_ci return VK_FORMAT_R8_UNORM; 59cb93a386Sopenharmony_ci case kUByte4_norm_GrVertexAttribType: 60cb93a386Sopenharmony_ci return VK_FORMAT_R8G8B8A8_UNORM; 61cb93a386Sopenharmony_ci case kShort2_GrVertexAttribType: 62cb93a386Sopenharmony_ci return VK_FORMAT_R16G16_SINT; 63cb93a386Sopenharmony_ci case kShort4_GrVertexAttribType: 64cb93a386Sopenharmony_ci return VK_FORMAT_R16G16B16A16_SINT; 65cb93a386Sopenharmony_ci case kUShort2_GrVertexAttribType: 66cb93a386Sopenharmony_ci return VK_FORMAT_R16G16_UINT; 67cb93a386Sopenharmony_ci case kUShort2_norm_GrVertexAttribType: 68cb93a386Sopenharmony_ci return VK_FORMAT_R16G16_UNORM; 69cb93a386Sopenharmony_ci case kInt_GrVertexAttribType: 70cb93a386Sopenharmony_ci return VK_FORMAT_R32_SINT; 71cb93a386Sopenharmony_ci case kUInt_GrVertexAttribType: 72cb93a386Sopenharmony_ci return VK_FORMAT_R32_UINT; 73cb93a386Sopenharmony_ci case kUShort_norm_GrVertexAttribType: 74cb93a386Sopenharmony_ci return VK_FORMAT_R16_UNORM; 75cb93a386Sopenharmony_ci case kUShort4_norm_GrVertexAttribType: 76cb93a386Sopenharmony_ci return VK_FORMAT_R16G16B16A16_UNORM; 77cb93a386Sopenharmony_ci } 78cb93a386Sopenharmony_ci SK_ABORT("Unknown vertex attrib type"); 79cb93a386Sopenharmony_ci} 80cb93a386Sopenharmony_ci 81cb93a386Sopenharmony_cistatic void setup_vertex_input_state( 82cb93a386Sopenharmony_ci const GrGeometryProcessor::AttributeSet& vertexAttribs, 83cb93a386Sopenharmony_ci const GrGeometryProcessor::AttributeSet& instanceAttribs, 84cb93a386Sopenharmony_ci VkPipelineVertexInputStateCreateInfo* vertexInputInfo, 85cb93a386Sopenharmony_ci SkSTArray<2, VkVertexInputBindingDescription, true>* bindingDescs, 86cb93a386Sopenharmony_ci VkVertexInputAttributeDescription* attributeDesc) { 87cb93a386Sopenharmony_ci int vaCount = vertexAttribs.count(); 88cb93a386Sopenharmony_ci int iaCount = instanceAttribs.count(); 89cb93a386Sopenharmony_ci 90cb93a386Sopenharmony_ci uint32_t vertexBinding = 0, instanceBinding = 0; 91cb93a386Sopenharmony_ci 92cb93a386Sopenharmony_ci int nextBinding = bindingDescs->count(); 93cb93a386Sopenharmony_ci if (vaCount) { 94cb93a386Sopenharmony_ci vertexBinding = nextBinding++; 95cb93a386Sopenharmony_ci } 96cb93a386Sopenharmony_ci 97cb93a386Sopenharmony_ci if (iaCount) { 98cb93a386Sopenharmony_ci instanceBinding = nextBinding; 99cb93a386Sopenharmony_ci } 100cb93a386Sopenharmony_ci 101cb93a386Sopenharmony_ci // setup attribute descriptions 102cb93a386Sopenharmony_ci int attribIndex = 0; 103cb93a386Sopenharmony_ci size_t vertexAttributeOffset = 0; 104cb93a386Sopenharmony_ci for (const auto& attrib : vertexAttribs) { 105cb93a386Sopenharmony_ci VkVertexInputAttributeDescription& vkAttrib = attributeDesc[attribIndex]; 106cb93a386Sopenharmony_ci vkAttrib.location = attribIndex++; // for now assume location = attribIndex 107cb93a386Sopenharmony_ci vkAttrib.binding = vertexBinding; 108cb93a386Sopenharmony_ci vkAttrib.format = attrib_type_to_vkformat(attrib.cpuType()); 109cb93a386Sopenharmony_ci vkAttrib.offset = vertexAttributeOffset; 110cb93a386Sopenharmony_ci vertexAttributeOffset += attrib.sizeAlign4(); 111cb93a386Sopenharmony_ci } 112cb93a386Sopenharmony_ci SkASSERT(vertexAttributeOffset == vertexAttribs.stride()); 113cb93a386Sopenharmony_ci 114cb93a386Sopenharmony_ci size_t instanceAttributeOffset = 0; 115cb93a386Sopenharmony_ci for (const auto& attrib : instanceAttribs) { 116cb93a386Sopenharmony_ci VkVertexInputAttributeDescription& vkAttrib = attributeDesc[attribIndex]; 117cb93a386Sopenharmony_ci vkAttrib.location = attribIndex++; // for now assume location = attribIndex 118cb93a386Sopenharmony_ci vkAttrib.binding = instanceBinding; 119cb93a386Sopenharmony_ci vkAttrib.format = attrib_type_to_vkformat(attrib.cpuType()); 120cb93a386Sopenharmony_ci vkAttrib.offset = instanceAttributeOffset; 121cb93a386Sopenharmony_ci instanceAttributeOffset += attrib.sizeAlign4(); 122cb93a386Sopenharmony_ci } 123cb93a386Sopenharmony_ci SkASSERT(instanceAttributeOffset == instanceAttribs.stride()); 124cb93a386Sopenharmony_ci 125cb93a386Sopenharmony_ci if (vaCount) { 126cb93a386Sopenharmony_ci bindingDescs->push_back() = { 127cb93a386Sopenharmony_ci vertexBinding, 128cb93a386Sopenharmony_ci (uint32_t) vertexAttributeOffset, 129cb93a386Sopenharmony_ci VK_VERTEX_INPUT_RATE_VERTEX 130cb93a386Sopenharmony_ci }; 131cb93a386Sopenharmony_ci } 132cb93a386Sopenharmony_ci if (iaCount) { 133cb93a386Sopenharmony_ci bindingDescs->push_back() = { 134cb93a386Sopenharmony_ci instanceBinding, 135cb93a386Sopenharmony_ci (uint32_t) instanceAttributeOffset, 136cb93a386Sopenharmony_ci VK_VERTEX_INPUT_RATE_INSTANCE 137cb93a386Sopenharmony_ci }; 138cb93a386Sopenharmony_ci } 139cb93a386Sopenharmony_ci 140cb93a386Sopenharmony_ci memset(vertexInputInfo, 0, sizeof(VkPipelineVertexInputStateCreateInfo)); 141cb93a386Sopenharmony_ci vertexInputInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; 142cb93a386Sopenharmony_ci vertexInputInfo->pNext = nullptr; 143cb93a386Sopenharmony_ci vertexInputInfo->flags = 0; 144cb93a386Sopenharmony_ci vertexInputInfo->vertexBindingDescriptionCount = bindingDescs->count(); 145cb93a386Sopenharmony_ci vertexInputInfo->pVertexBindingDescriptions = bindingDescs->begin(); 146cb93a386Sopenharmony_ci vertexInputInfo->vertexAttributeDescriptionCount = vaCount + iaCount; 147cb93a386Sopenharmony_ci vertexInputInfo->pVertexAttributeDescriptions = attributeDesc; 148cb93a386Sopenharmony_ci} 149cb93a386Sopenharmony_ci 150cb93a386Sopenharmony_cistatic VkPrimitiveTopology gr_primitive_type_to_vk_topology(GrPrimitiveType primitiveType) { 151cb93a386Sopenharmony_ci switch (primitiveType) { 152cb93a386Sopenharmony_ci case GrPrimitiveType::kTriangles: 153cb93a386Sopenharmony_ci return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; 154cb93a386Sopenharmony_ci case GrPrimitiveType::kTriangleStrip: 155cb93a386Sopenharmony_ci return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; 156cb93a386Sopenharmony_ci case GrPrimitiveType::kPoints: 157cb93a386Sopenharmony_ci return VK_PRIMITIVE_TOPOLOGY_POINT_LIST; 158cb93a386Sopenharmony_ci case GrPrimitiveType::kLines: 159cb93a386Sopenharmony_ci return VK_PRIMITIVE_TOPOLOGY_LINE_LIST; 160cb93a386Sopenharmony_ci case GrPrimitiveType::kLineStrip: 161cb93a386Sopenharmony_ci return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP; 162cb93a386Sopenharmony_ci case GrPrimitiveType::kPatches: 163cb93a386Sopenharmony_ci case GrPrimitiveType::kPath: 164cb93a386Sopenharmony_ci SK_ABORT("Unsupported primitive type"); 165cb93a386Sopenharmony_ci } 166cb93a386Sopenharmony_ci SkUNREACHABLE; 167cb93a386Sopenharmony_ci} 168cb93a386Sopenharmony_ci 169cb93a386Sopenharmony_cistatic void setup_input_assembly_state(GrPrimitiveType primitiveType, 170cb93a386Sopenharmony_ci VkPipelineInputAssemblyStateCreateInfo* inputAssemblyInfo) { 171cb93a386Sopenharmony_ci memset(inputAssemblyInfo, 0, sizeof(VkPipelineInputAssemblyStateCreateInfo)); 172cb93a386Sopenharmony_ci inputAssemblyInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; 173cb93a386Sopenharmony_ci inputAssemblyInfo->pNext = nullptr; 174cb93a386Sopenharmony_ci inputAssemblyInfo->flags = 0; 175cb93a386Sopenharmony_ci inputAssemblyInfo->primitiveRestartEnable = false; 176cb93a386Sopenharmony_ci inputAssemblyInfo->topology = gr_primitive_type_to_vk_topology(primitiveType); 177cb93a386Sopenharmony_ci} 178cb93a386Sopenharmony_ci 179cb93a386Sopenharmony_cistatic VkStencilOp stencil_op_to_vk_stencil_op(GrStencilOp op) { 180cb93a386Sopenharmony_ci static const VkStencilOp gTable[] = { 181cb93a386Sopenharmony_ci VK_STENCIL_OP_KEEP, // kKeep 182cb93a386Sopenharmony_ci VK_STENCIL_OP_ZERO, // kZero 183cb93a386Sopenharmony_ci VK_STENCIL_OP_REPLACE, // kReplace 184cb93a386Sopenharmony_ci VK_STENCIL_OP_INVERT, // kInvert 185cb93a386Sopenharmony_ci VK_STENCIL_OP_INCREMENT_AND_WRAP, // kIncWrap 186cb93a386Sopenharmony_ci VK_STENCIL_OP_DECREMENT_AND_WRAP, // kDecWrap 187cb93a386Sopenharmony_ci VK_STENCIL_OP_INCREMENT_AND_CLAMP, // kIncClamp 188cb93a386Sopenharmony_ci VK_STENCIL_OP_DECREMENT_AND_CLAMP, // kDecClamp 189cb93a386Sopenharmony_ci }; 190cb93a386Sopenharmony_ci static_assert(SK_ARRAY_COUNT(gTable) == kGrStencilOpCount); 191cb93a386Sopenharmony_ci static_assert(0 == (int)GrStencilOp::kKeep); 192cb93a386Sopenharmony_ci static_assert(1 == (int)GrStencilOp::kZero); 193cb93a386Sopenharmony_ci static_assert(2 == (int)GrStencilOp::kReplace); 194cb93a386Sopenharmony_ci static_assert(3 == (int)GrStencilOp::kInvert); 195cb93a386Sopenharmony_ci static_assert(4 == (int)GrStencilOp::kIncWrap); 196cb93a386Sopenharmony_ci static_assert(5 == (int)GrStencilOp::kDecWrap); 197cb93a386Sopenharmony_ci static_assert(6 == (int)GrStencilOp::kIncClamp); 198cb93a386Sopenharmony_ci static_assert(7 == (int)GrStencilOp::kDecClamp); 199cb93a386Sopenharmony_ci SkASSERT(op < (GrStencilOp)kGrStencilOpCount); 200cb93a386Sopenharmony_ci return gTable[(int)op]; 201cb93a386Sopenharmony_ci} 202cb93a386Sopenharmony_ci 203cb93a386Sopenharmony_cistatic VkCompareOp stencil_func_to_vk_compare_op(GrStencilTest test) { 204cb93a386Sopenharmony_ci static const VkCompareOp gTable[] = { 205cb93a386Sopenharmony_ci VK_COMPARE_OP_ALWAYS, // kAlways 206cb93a386Sopenharmony_ci VK_COMPARE_OP_NEVER, // kNever 207cb93a386Sopenharmony_ci VK_COMPARE_OP_GREATER, // kGreater 208cb93a386Sopenharmony_ci VK_COMPARE_OP_GREATER_OR_EQUAL, // kGEqual 209cb93a386Sopenharmony_ci VK_COMPARE_OP_LESS, // kLess 210cb93a386Sopenharmony_ci VK_COMPARE_OP_LESS_OR_EQUAL, // kLEqual 211cb93a386Sopenharmony_ci VK_COMPARE_OP_EQUAL, // kEqual 212cb93a386Sopenharmony_ci VK_COMPARE_OP_NOT_EQUAL, // kNotEqual 213cb93a386Sopenharmony_ci }; 214cb93a386Sopenharmony_ci static_assert(SK_ARRAY_COUNT(gTable) == kGrStencilTestCount); 215cb93a386Sopenharmony_ci static_assert(0 == (int)GrStencilTest::kAlways); 216cb93a386Sopenharmony_ci static_assert(1 == (int)GrStencilTest::kNever); 217cb93a386Sopenharmony_ci static_assert(2 == (int)GrStencilTest::kGreater); 218cb93a386Sopenharmony_ci static_assert(3 == (int)GrStencilTest::kGEqual); 219cb93a386Sopenharmony_ci static_assert(4 == (int)GrStencilTest::kLess); 220cb93a386Sopenharmony_ci static_assert(5 == (int)GrStencilTest::kLEqual); 221cb93a386Sopenharmony_ci static_assert(6 == (int)GrStencilTest::kEqual); 222cb93a386Sopenharmony_ci static_assert(7 == (int)GrStencilTest::kNotEqual); 223cb93a386Sopenharmony_ci SkASSERT(test < (GrStencilTest)kGrStencilTestCount); 224cb93a386Sopenharmony_ci 225cb93a386Sopenharmony_ci return gTable[(int)test]; 226cb93a386Sopenharmony_ci} 227cb93a386Sopenharmony_ci 228cb93a386Sopenharmony_cistatic void setup_stencil_op_state( 229cb93a386Sopenharmony_ci VkStencilOpState* opState, const GrStencilSettings::Face& stencilFace) { 230cb93a386Sopenharmony_ci opState->failOp = stencil_op_to_vk_stencil_op(stencilFace.fFailOp); 231cb93a386Sopenharmony_ci opState->passOp = stencil_op_to_vk_stencil_op(stencilFace.fPassOp); 232cb93a386Sopenharmony_ci opState->depthFailOp = opState->failOp; 233cb93a386Sopenharmony_ci opState->compareOp = stencil_func_to_vk_compare_op(stencilFace.fTest); 234cb93a386Sopenharmony_ci opState->compareMask = stencilFace.fTestMask; 235cb93a386Sopenharmony_ci opState->writeMask = stencilFace.fWriteMask; 236cb93a386Sopenharmony_ci opState->reference = stencilFace.fRef; 237cb93a386Sopenharmony_ci} 238cb93a386Sopenharmony_ci 239cb93a386Sopenharmony_cistatic void setup_depth_stencil_state( 240cb93a386Sopenharmony_ci const GrStencilSettings& stencilSettings, 241cb93a386Sopenharmony_ci GrSurfaceOrigin origin, 242cb93a386Sopenharmony_ci VkPipelineDepthStencilStateCreateInfo* stencilInfo) { 243cb93a386Sopenharmony_ci 244cb93a386Sopenharmony_ci memset(stencilInfo, 0, sizeof(VkPipelineDepthStencilStateCreateInfo)); 245cb93a386Sopenharmony_ci stencilInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; 246cb93a386Sopenharmony_ci stencilInfo->pNext = nullptr; 247cb93a386Sopenharmony_ci stencilInfo->flags = 0; 248cb93a386Sopenharmony_ci // set depth testing defaults 249cb93a386Sopenharmony_ci stencilInfo->depthTestEnable = VK_FALSE; 250cb93a386Sopenharmony_ci stencilInfo->depthWriteEnable = VK_FALSE; 251cb93a386Sopenharmony_ci stencilInfo->depthCompareOp = VK_COMPARE_OP_ALWAYS; 252cb93a386Sopenharmony_ci stencilInfo->depthBoundsTestEnable = VK_FALSE; 253cb93a386Sopenharmony_ci stencilInfo->stencilTestEnable = !stencilSettings.isDisabled(); 254cb93a386Sopenharmony_ci if (!stencilSettings.isDisabled()) { 255cb93a386Sopenharmony_ci if (!stencilSettings.isTwoSided()) { 256cb93a386Sopenharmony_ci setup_stencil_op_state(&stencilInfo->front, stencilSettings.singleSidedFace()); 257cb93a386Sopenharmony_ci stencilInfo->back = stencilInfo->front; 258cb93a386Sopenharmony_ci } else { 259cb93a386Sopenharmony_ci setup_stencil_op_state(&stencilInfo->front, stencilSettings.postOriginCCWFace(origin)); 260cb93a386Sopenharmony_ci setup_stencil_op_state(&stencilInfo->back, stencilSettings.postOriginCWFace(origin)); 261cb93a386Sopenharmony_ci } 262cb93a386Sopenharmony_ci } 263cb93a386Sopenharmony_ci stencilInfo->minDepthBounds = 0.0f; 264cb93a386Sopenharmony_ci stencilInfo->maxDepthBounds = 1.0f; 265cb93a386Sopenharmony_ci} 266cb93a386Sopenharmony_ci 267cb93a386Sopenharmony_cistatic void setup_viewport_scissor_state(VkPipelineViewportStateCreateInfo* viewportInfo) { 268cb93a386Sopenharmony_ci memset(viewportInfo, 0, sizeof(VkPipelineViewportStateCreateInfo)); 269cb93a386Sopenharmony_ci viewportInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; 270cb93a386Sopenharmony_ci viewportInfo->pNext = nullptr; 271cb93a386Sopenharmony_ci viewportInfo->flags = 0; 272cb93a386Sopenharmony_ci 273cb93a386Sopenharmony_ci viewportInfo->viewportCount = 1; 274cb93a386Sopenharmony_ci viewportInfo->pViewports = nullptr; // This is set dynamically 275cb93a386Sopenharmony_ci 276cb93a386Sopenharmony_ci viewportInfo->scissorCount = 1; 277cb93a386Sopenharmony_ci viewportInfo->pScissors = nullptr; // This is set dynamically 278cb93a386Sopenharmony_ci 279cb93a386Sopenharmony_ci SkASSERT(viewportInfo->viewportCount == viewportInfo->scissorCount); 280cb93a386Sopenharmony_ci} 281cb93a386Sopenharmony_ci 282cb93a386Sopenharmony_cistatic void setup_multisample_state(int numSamples, 283cb93a386Sopenharmony_ci const GrCaps* caps, 284cb93a386Sopenharmony_ci VkPipelineMultisampleStateCreateInfo* multisampleInfo) { 285cb93a386Sopenharmony_ci memset(multisampleInfo, 0, sizeof(VkPipelineMultisampleStateCreateInfo)); 286cb93a386Sopenharmony_ci multisampleInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; 287cb93a386Sopenharmony_ci multisampleInfo->pNext = nullptr; 288cb93a386Sopenharmony_ci multisampleInfo->flags = 0; 289cb93a386Sopenharmony_ci SkAssertResult(GrSampleCountToVkSampleCount(numSamples, 290cb93a386Sopenharmony_ci &multisampleInfo->rasterizationSamples)); 291cb93a386Sopenharmony_ci multisampleInfo->sampleShadingEnable = VK_FALSE; 292cb93a386Sopenharmony_ci multisampleInfo->minSampleShading = 0.0f; 293cb93a386Sopenharmony_ci multisampleInfo->pSampleMask = nullptr; 294cb93a386Sopenharmony_ci multisampleInfo->alphaToCoverageEnable = VK_FALSE; 295cb93a386Sopenharmony_ci multisampleInfo->alphaToOneEnable = VK_FALSE; 296cb93a386Sopenharmony_ci} 297cb93a386Sopenharmony_ci 298cb93a386Sopenharmony_cistatic VkBlendFactor blend_coeff_to_vk_blend(GrBlendCoeff coeff) { 299cb93a386Sopenharmony_ci switch (coeff) { 300cb93a386Sopenharmony_ci case kZero_GrBlendCoeff: 301cb93a386Sopenharmony_ci return VK_BLEND_FACTOR_ZERO; 302cb93a386Sopenharmony_ci case kOne_GrBlendCoeff: 303cb93a386Sopenharmony_ci return VK_BLEND_FACTOR_ONE; 304cb93a386Sopenharmony_ci case kSC_GrBlendCoeff: 305cb93a386Sopenharmony_ci return VK_BLEND_FACTOR_SRC_COLOR; 306cb93a386Sopenharmony_ci case kISC_GrBlendCoeff: 307cb93a386Sopenharmony_ci return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR; 308cb93a386Sopenharmony_ci case kDC_GrBlendCoeff: 309cb93a386Sopenharmony_ci return VK_BLEND_FACTOR_DST_COLOR; 310cb93a386Sopenharmony_ci case kIDC_GrBlendCoeff: 311cb93a386Sopenharmony_ci return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR; 312cb93a386Sopenharmony_ci case kSA_GrBlendCoeff: 313cb93a386Sopenharmony_ci return VK_BLEND_FACTOR_SRC_ALPHA; 314cb93a386Sopenharmony_ci case kISA_GrBlendCoeff: 315cb93a386Sopenharmony_ci return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; 316cb93a386Sopenharmony_ci case kDA_GrBlendCoeff: 317cb93a386Sopenharmony_ci return VK_BLEND_FACTOR_DST_ALPHA; 318cb93a386Sopenharmony_ci case kIDA_GrBlendCoeff: 319cb93a386Sopenharmony_ci return VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA; 320cb93a386Sopenharmony_ci case kConstC_GrBlendCoeff: 321cb93a386Sopenharmony_ci return VK_BLEND_FACTOR_CONSTANT_COLOR; 322cb93a386Sopenharmony_ci case kIConstC_GrBlendCoeff: 323cb93a386Sopenharmony_ci return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR; 324cb93a386Sopenharmony_ci case kS2C_GrBlendCoeff: 325cb93a386Sopenharmony_ci return VK_BLEND_FACTOR_SRC1_COLOR; 326cb93a386Sopenharmony_ci case kIS2C_GrBlendCoeff: 327cb93a386Sopenharmony_ci return VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR; 328cb93a386Sopenharmony_ci case kS2A_GrBlendCoeff: 329cb93a386Sopenharmony_ci return VK_BLEND_FACTOR_SRC1_ALPHA; 330cb93a386Sopenharmony_ci case kIS2A_GrBlendCoeff: 331cb93a386Sopenharmony_ci return VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA; 332cb93a386Sopenharmony_ci case kIllegal_GrBlendCoeff: 333cb93a386Sopenharmony_ci return VK_BLEND_FACTOR_ZERO; 334cb93a386Sopenharmony_ci } 335cb93a386Sopenharmony_ci SkUNREACHABLE; 336cb93a386Sopenharmony_ci} 337cb93a386Sopenharmony_ci 338cb93a386Sopenharmony_cistatic VkBlendOp blend_equation_to_vk_blend_op(GrBlendEquation equation) { 339cb93a386Sopenharmony_ci static const VkBlendOp gTable[] = { 340cb93a386Sopenharmony_ci // Basic blend ops 341cb93a386Sopenharmony_ci VK_BLEND_OP_ADD, 342cb93a386Sopenharmony_ci VK_BLEND_OP_SUBTRACT, 343cb93a386Sopenharmony_ci VK_BLEND_OP_REVERSE_SUBTRACT, 344cb93a386Sopenharmony_ci 345cb93a386Sopenharmony_ci // Advanced blend ops 346cb93a386Sopenharmony_ci VK_BLEND_OP_SCREEN_EXT, 347cb93a386Sopenharmony_ci VK_BLEND_OP_OVERLAY_EXT, 348cb93a386Sopenharmony_ci VK_BLEND_OP_DARKEN_EXT, 349cb93a386Sopenharmony_ci VK_BLEND_OP_LIGHTEN_EXT, 350cb93a386Sopenharmony_ci VK_BLEND_OP_COLORDODGE_EXT, 351cb93a386Sopenharmony_ci VK_BLEND_OP_COLORBURN_EXT, 352cb93a386Sopenharmony_ci VK_BLEND_OP_HARDLIGHT_EXT, 353cb93a386Sopenharmony_ci VK_BLEND_OP_SOFTLIGHT_EXT, 354cb93a386Sopenharmony_ci VK_BLEND_OP_DIFFERENCE_EXT, 355cb93a386Sopenharmony_ci VK_BLEND_OP_EXCLUSION_EXT, 356cb93a386Sopenharmony_ci VK_BLEND_OP_MULTIPLY_EXT, 357cb93a386Sopenharmony_ci VK_BLEND_OP_HSL_HUE_EXT, 358cb93a386Sopenharmony_ci VK_BLEND_OP_HSL_SATURATION_EXT, 359cb93a386Sopenharmony_ci VK_BLEND_OP_HSL_COLOR_EXT, 360cb93a386Sopenharmony_ci VK_BLEND_OP_HSL_LUMINOSITY_EXT, 361cb93a386Sopenharmony_ci 362cb93a386Sopenharmony_ci // Illegal. 363cb93a386Sopenharmony_ci VK_BLEND_OP_ADD, 364cb93a386Sopenharmony_ci }; 365cb93a386Sopenharmony_ci static_assert(0 == kAdd_GrBlendEquation); 366cb93a386Sopenharmony_ci static_assert(1 == kSubtract_GrBlendEquation); 367cb93a386Sopenharmony_ci static_assert(2 == kReverseSubtract_GrBlendEquation); 368cb93a386Sopenharmony_ci static_assert(3 == kScreen_GrBlendEquation); 369cb93a386Sopenharmony_ci static_assert(4 == kOverlay_GrBlendEquation); 370cb93a386Sopenharmony_ci static_assert(5 == kDarken_GrBlendEquation); 371cb93a386Sopenharmony_ci static_assert(6 == kLighten_GrBlendEquation); 372cb93a386Sopenharmony_ci static_assert(7 == kColorDodge_GrBlendEquation); 373cb93a386Sopenharmony_ci static_assert(8 == kColorBurn_GrBlendEquation); 374cb93a386Sopenharmony_ci static_assert(9 == kHardLight_GrBlendEquation); 375cb93a386Sopenharmony_ci static_assert(10 == kSoftLight_GrBlendEquation); 376cb93a386Sopenharmony_ci static_assert(11 == kDifference_GrBlendEquation); 377cb93a386Sopenharmony_ci static_assert(12 == kExclusion_GrBlendEquation); 378cb93a386Sopenharmony_ci static_assert(13 == kMultiply_GrBlendEquation); 379cb93a386Sopenharmony_ci static_assert(14 == kHSLHue_GrBlendEquation); 380cb93a386Sopenharmony_ci static_assert(15 == kHSLSaturation_GrBlendEquation); 381cb93a386Sopenharmony_ci static_assert(16 == kHSLColor_GrBlendEquation); 382cb93a386Sopenharmony_ci static_assert(17 == kHSLLuminosity_GrBlendEquation); 383cb93a386Sopenharmony_ci static_assert(SK_ARRAY_COUNT(gTable) == kGrBlendEquationCnt); 384cb93a386Sopenharmony_ci 385cb93a386Sopenharmony_ci SkASSERT((unsigned)equation < kGrBlendEquationCnt); 386cb93a386Sopenharmony_ci return gTable[equation]; 387cb93a386Sopenharmony_ci} 388cb93a386Sopenharmony_ci 389cb93a386Sopenharmony_cistatic void setup_color_blend_state(const GrXferProcessor::BlendInfo& blendInfo, 390cb93a386Sopenharmony_ci VkPipelineColorBlendStateCreateInfo* colorBlendInfo, 391cb93a386Sopenharmony_ci VkPipelineColorBlendAttachmentState* attachmentState) { 392cb93a386Sopenharmony_ci GrBlendEquation equation = blendInfo.fEquation; 393cb93a386Sopenharmony_ci GrBlendCoeff srcCoeff = blendInfo.fSrcBlend; 394cb93a386Sopenharmony_ci GrBlendCoeff dstCoeff = blendInfo.fDstBlend; 395cb93a386Sopenharmony_ci bool blendOff = GrBlendShouldDisable(equation, srcCoeff, dstCoeff); 396cb93a386Sopenharmony_ci 397cb93a386Sopenharmony_ci memset(attachmentState, 0, sizeof(VkPipelineColorBlendAttachmentState)); 398cb93a386Sopenharmony_ci attachmentState->blendEnable = !blendOff; 399cb93a386Sopenharmony_ci if (!blendOff) { 400cb93a386Sopenharmony_ci attachmentState->srcColorBlendFactor = blend_coeff_to_vk_blend(srcCoeff); 401cb93a386Sopenharmony_ci attachmentState->dstColorBlendFactor = blend_coeff_to_vk_blend(dstCoeff); 402cb93a386Sopenharmony_ci attachmentState->colorBlendOp = blend_equation_to_vk_blend_op(equation); 403cb93a386Sopenharmony_ci attachmentState->srcAlphaBlendFactor = blend_coeff_to_vk_blend(srcCoeff); 404cb93a386Sopenharmony_ci attachmentState->dstAlphaBlendFactor = blend_coeff_to_vk_blend(dstCoeff); 405cb93a386Sopenharmony_ci attachmentState->alphaBlendOp = blend_equation_to_vk_blend_op(equation); 406cb93a386Sopenharmony_ci } 407cb93a386Sopenharmony_ci 408cb93a386Sopenharmony_ci if (!blendInfo.fWriteColor) { 409cb93a386Sopenharmony_ci attachmentState->colorWriteMask = 0; 410cb93a386Sopenharmony_ci } else { 411cb93a386Sopenharmony_ci attachmentState->colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | 412cb93a386Sopenharmony_ci VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; 413cb93a386Sopenharmony_ci } 414cb93a386Sopenharmony_ci 415cb93a386Sopenharmony_ci memset(colorBlendInfo, 0, sizeof(VkPipelineColorBlendStateCreateInfo)); 416cb93a386Sopenharmony_ci colorBlendInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; 417cb93a386Sopenharmony_ci colorBlendInfo->pNext = nullptr; 418cb93a386Sopenharmony_ci colorBlendInfo->flags = 0; 419cb93a386Sopenharmony_ci colorBlendInfo->logicOpEnable = VK_FALSE; 420cb93a386Sopenharmony_ci colorBlendInfo->attachmentCount = 1; 421cb93a386Sopenharmony_ci colorBlendInfo->pAttachments = attachmentState; 422cb93a386Sopenharmony_ci // colorBlendInfo->blendConstants is set dynamically 423cb93a386Sopenharmony_ci} 424cb93a386Sopenharmony_ci 425cb93a386Sopenharmony_cistatic void setup_raster_state(bool isWireframe, 426cb93a386Sopenharmony_ci const GrCaps* caps, 427cb93a386Sopenharmony_ci VkPipelineRasterizationStateCreateInfo* rasterInfo) { 428cb93a386Sopenharmony_ci memset(rasterInfo, 0, sizeof(VkPipelineRasterizationStateCreateInfo)); 429cb93a386Sopenharmony_ci rasterInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; 430cb93a386Sopenharmony_ci rasterInfo->pNext = nullptr; 431cb93a386Sopenharmony_ci rasterInfo->flags = 0; 432cb93a386Sopenharmony_ci rasterInfo->depthClampEnable = VK_FALSE; 433cb93a386Sopenharmony_ci rasterInfo->rasterizerDiscardEnable = VK_FALSE; 434cb93a386Sopenharmony_ci rasterInfo->polygonMode = (caps->wireframeMode() || isWireframe) ? 435cb93a386Sopenharmony_ci VK_POLYGON_MODE_LINE : VK_POLYGON_MODE_FILL; 436cb93a386Sopenharmony_ci rasterInfo->cullMode = VK_CULL_MODE_NONE; 437cb93a386Sopenharmony_ci rasterInfo->frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; 438cb93a386Sopenharmony_ci rasterInfo->depthBiasEnable = VK_FALSE; 439cb93a386Sopenharmony_ci rasterInfo->depthBiasConstantFactor = 0.0f; 440cb93a386Sopenharmony_ci rasterInfo->depthBiasClamp = 0.0f; 441cb93a386Sopenharmony_ci rasterInfo->depthBiasSlopeFactor = 0.0f; 442cb93a386Sopenharmony_ci rasterInfo->lineWidth = 1.0f; 443cb93a386Sopenharmony_ci} 444cb93a386Sopenharmony_ci 445cb93a386Sopenharmony_cistatic void setup_conservative_raster_info( 446cb93a386Sopenharmony_ci VkPipelineRasterizationConservativeStateCreateInfoEXT* conservativeRasterInfo) { 447cb93a386Sopenharmony_ci memset(conservativeRasterInfo, 0, 448cb93a386Sopenharmony_ci sizeof(VkPipelineRasterizationConservativeStateCreateInfoEXT)); 449cb93a386Sopenharmony_ci conservativeRasterInfo->sType = 450cb93a386Sopenharmony_ci VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT; 451cb93a386Sopenharmony_ci conservativeRasterInfo->pNext = nullptr; 452cb93a386Sopenharmony_ci conservativeRasterInfo->flags = 0; 453cb93a386Sopenharmony_ci conservativeRasterInfo->conservativeRasterizationMode = 454cb93a386Sopenharmony_ci VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT; 455cb93a386Sopenharmony_ci conservativeRasterInfo->extraPrimitiveOverestimationSize = 0; 456cb93a386Sopenharmony_ci} 457cb93a386Sopenharmony_ci 458cb93a386Sopenharmony_cistatic void setup_dynamic_state(VkPipelineDynamicStateCreateInfo* dynamicInfo, 459cb93a386Sopenharmony_ci VkDynamicState* dynamicStates) { 460cb93a386Sopenharmony_ci memset(dynamicInfo, 0, sizeof(VkPipelineDynamicStateCreateInfo)); 461cb93a386Sopenharmony_ci dynamicInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; 462cb93a386Sopenharmony_ci dynamicInfo->pNext = VK_NULL_HANDLE; 463cb93a386Sopenharmony_ci dynamicInfo->flags = 0; 464cb93a386Sopenharmony_ci dynamicStates[0] = VK_DYNAMIC_STATE_VIEWPORT; 465cb93a386Sopenharmony_ci dynamicStates[1] = VK_DYNAMIC_STATE_SCISSOR; 466cb93a386Sopenharmony_ci dynamicStates[2] = VK_DYNAMIC_STATE_BLEND_CONSTANTS; 467cb93a386Sopenharmony_ci dynamicInfo->dynamicStateCount = 3; 468cb93a386Sopenharmony_ci dynamicInfo->pDynamicStates = dynamicStates; 469cb93a386Sopenharmony_ci} 470cb93a386Sopenharmony_ci 471cb93a386Sopenharmony_cisk_sp<GrVkPipeline> GrVkPipeline::Make(GrVkGpu* gpu, 472cb93a386Sopenharmony_ci const GrGeometryProcessor::AttributeSet& vertexAttribs, 473cb93a386Sopenharmony_ci const GrGeometryProcessor::AttributeSet& instanceAttribs, 474cb93a386Sopenharmony_ci GrPrimitiveType primitiveType, 475cb93a386Sopenharmony_ci GrSurfaceOrigin origin, 476cb93a386Sopenharmony_ci const GrStencilSettings& stencilSettings, 477cb93a386Sopenharmony_ci int numSamples, 478cb93a386Sopenharmony_ci bool isHWAntialiasState, 479cb93a386Sopenharmony_ci const GrXferProcessor::BlendInfo& blendInfo, 480cb93a386Sopenharmony_ci bool isWireframe, 481cb93a386Sopenharmony_ci bool useConservativeRaster, 482cb93a386Sopenharmony_ci uint32_t subpass, 483cb93a386Sopenharmony_ci VkPipelineShaderStageCreateInfo* shaderStageInfo, 484cb93a386Sopenharmony_ci int shaderStageCount, 485cb93a386Sopenharmony_ci VkRenderPass compatibleRenderPass, 486cb93a386Sopenharmony_ci VkPipelineLayout layout, 487cb93a386Sopenharmony_ci bool ownsLayout, 488cb93a386Sopenharmony_ci VkPipelineCache cache) { 489cb93a386Sopenharmony_ci VkPipelineVertexInputStateCreateInfo vertexInputInfo; 490cb93a386Sopenharmony_ci SkSTArray<2, VkVertexInputBindingDescription, true> bindingDescs; 491cb93a386Sopenharmony_ci SkSTArray<16, VkVertexInputAttributeDescription> attributeDesc; 492cb93a386Sopenharmony_ci int totalAttributeCnt = vertexAttribs.count() + instanceAttribs.count(); 493cb93a386Sopenharmony_ci SkASSERT(totalAttributeCnt <= gpu->vkCaps().maxVertexAttributes()); 494cb93a386Sopenharmony_ci VkVertexInputAttributeDescription* pAttribs = attributeDesc.push_back_n(totalAttributeCnt); 495cb93a386Sopenharmony_ci setup_vertex_input_state(vertexAttribs, instanceAttribs, &vertexInputInfo, &bindingDescs, 496cb93a386Sopenharmony_ci pAttribs); 497cb93a386Sopenharmony_ci 498cb93a386Sopenharmony_ci VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo; 499cb93a386Sopenharmony_ci setup_input_assembly_state(primitiveType, &inputAssemblyInfo); 500cb93a386Sopenharmony_ci 501cb93a386Sopenharmony_ci VkPipelineDepthStencilStateCreateInfo depthStencilInfo; 502cb93a386Sopenharmony_ci setup_depth_stencil_state(stencilSettings, origin, &depthStencilInfo); 503cb93a386Sopenharmony_ci 504cb93a386Sopenharmony_ci VkPipelineViewportStateCreateInfo viewportInfo; 505cb93a386Sopenharmony_ci setup_viewport_scissor_state(&viewportInfo); 506cb93a386Sopenharmony_ci 507cb93a386Sopenharmony_ci VkPipelineMultisampleStateCreateInfo multisampleInfo; 508cb93a386Sopenharmony_ci setup_multisample_state(numSamples, gpu->caps(), &multisampleInfo); 509cb93a386Sopenharmony_ci 510cb93a386Sopenharmony_ci // We will only have one color attachment per pipeline. 511cb93a386Sopenharmony_ci VkPipelineColorBlendAttachmentState attachmentStates[1]; 512cb93a386Sopenharmony_ci VkPipelineColorBlendStateCreateInfo colorBlendInfo; 513cb93a386Sopenharmony_ci setup_color_blend_state(blendInfo, &colorBlendInfo, attachmentStates); 514cb93a386Sopenharmony_ci 515cb93a386Sopenharmony_ci VkPipelineRasterizationStateCreateInfo rasterInfo; 516cb93a386Sopenharmony_ci setup_raster_state(isWireframe, gpu->caps(), &rasterInfo); 517cb93a386Sopenharmony_ci 518cb93a386Sopenharmony_ci VkPipelineRasterizationConservativeStateCreateInfoEXT conservativeRasterInfo; 519cb93a386Sopenharmony_ci if (useConservativeRaster) { 520cb93a386Sopenharmony_ci SkASSERT(gpu->caps()->conservativeRasterSupport()); 521cb93a386Sopenharmony_ci setup_conservative_raster_info(&conservativeRasterInfo); 522cb93a386Sopenharmony_ci conservativeRasterInfo.pNext = rasterInfo.pNext; 523cb93a386Sopenharmony_ci rasterInfo.pNext = &conservativeRasterInfo; 524cb93a386Sopenharmony_ci } 525cb93a386Sopenharmony_ci 526cb93a386Sopenharmony_ci VkDynamicState dynamicStates[3]; 527cb93a386Sopenharmony_ci VkPipelineDynamicStateCreateInfo dynamicInfo; 528cb93a386Sopenharmony_ci setup_dynamic_state(&dynamicInfo, dynamicStates); 529cb93a386Sopenharmony_ci 530cb93a386Sopenharmony_ci VkGraphicsPipelineCreateInfo pipelineCreateInfo; 531cb93a386Sopenharmony_ci memset(&pipelineCreateInfo, 0, sizeof(VkGraphicsPipelineCreateInfo)); 532cb93a386Sopenharmony_ci pipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; 533cb93a386Sopenharmony_ci pipelineCreateInfo.pNext = nullptr; 534cb93a386Sopenharmony_ci pipelineCreateInfo.flags = 0; 535cb93a386Sopenharmony_ci pipelineCreateInfo.stageCount = shaderStageCount; 536cb93a386Sopenharmony_ci pipelineCreateInfo.pStages = shaderStageInfo; 537cb93a386Sopenharmony_ci pipelineCreateInfo.pVertexInputState = &vertexInputInfo; 538cb93a386Sopenharmony_ci pipelineCreateInfo.pInputAssemblyState = &inputAssemblyInfo; 539cb93a386Sopenharmony_ci pipelineCreateInfo.pTessellationState = nullptr; 540cb93a386Sopenharmony_ci pipelineCreateInfo.pViewportState = &viewportInfo; 541cb93a386Sopenharmony_ci pipelineCreateInfo.pRasterizationState = &rasterInfo; 542cb93a386Sopenharmony_ci pipelineCreateInfo.pMultisampleState = &multisampleInfo; 543cb93a386Sopenharmony_ci pipelineCreateInfo.pDepthStencilState = &depthStencilInfo; 544cb93a386Sopenharmony_ci pipelineCreateInfo.pColorBlendState = &colorBlendInfo; 545cb93a386Sopenharmony_ci pipelineCreateInfo.pDynamicState = &dynamicInfo; 546cb93a386Sopenharmony_ci pipelineCreateInfo.layout = layout; 547cb93a386Sopenharmony_ci pipelineCreateInfo.renderPass = compatibleRenderPass; 548cb93a386Sopenharmony_ci pipelineCreateInfo.subpass = subpass; 549cb93a386Sopenharmony_ci pipelineCreateInfo.basePipelineHandle = VK_NULL_HANDLE; 550cb93a386Sopenharmony_ci pipelineCreateInfo.basePipelineIndex = -1; 551cb93a386Sopenharmony_ci 552cb93a386Sopenharmony_ci VkPipeline vkPipeline; 553cb93a386Sopenharmony_ci VkResult err; 554cb93a386Sopenharmony_ci { 555cb93a386Sopenharmony_ci TRACE_EVENT0("skia.shaders", "CreateGraphicsPipeline"); 556cb93a386Sopenharmony_ci#if defined(SK_ENABLE_SCOPED_LSAN_SUPPRESSIONS) 557cb93a386Sopenharmony_ci // skia:8712 558cb93a386Sopenharmony_ci __lsan::ScopedDisabler lsanDisabler; 559cb93a386Sopenharmony_ci#endif 560cb93a386Sopenharmony_ci GR_VK_CALL_RESULT(gpu, err, CreateGraphicsPipelines(gpu->device(), cache, 1, 561cb93a386Sopenharmony_ci &pipelineCreateInfo, nullptr, 562cb93a386Sopenharmony_ci &vkPipeline)); 563cb93a386Sopenharmony_ci } 564cb93a386Sopenharmony_ci if (err) { 565cb93a386Sopenharmony_ci SkDebugf("Failed to create pipeline. Error: %d\n", err); 566cb93a386Sopenharmony_ci return nullptr; 567cb93a386Sopenharmony_ci } 568cb93a386Sopenharmony_ci 569cb93a386Sopenharmony_ci if (!ownsLayout) { 570cb93a386Sopenharmony_ci layout = VK_NULL_HANDLE; 571cb93a386Sopenharmony_ci } 572cb93a386Sopenharmony_ci return sk_sp<GrVkPipeline>(new GrVkPipeline(gpu, vkPipeline, layout)); 573cb93a386Sopenharmony_ci} 574cb93a386Sopenharmony_ci 575cb93a386Sopenharmony_cisk_sp<GrVkPipeline> GrVkPipeline::Make(GrVkGpu* gpu, 576cb93a386Sopenharmony_ci const GrProgramInfo& programInfo, 577cb93a386Sopenharmony_ci VkPipelineShaderStageCreateInfo* shaderStageInfo, 578cb93a386Sopenharmony_ci int shaderStageCount, 579cb93a386Sopenharmony_ci VkRenderPass compatibleRenderPass, 580cb93a386Sopenharmony_ci VkPipelineLayout layout, 581cb93a386Sopenharmony_ci VkPipelineCache cache, 582cb93a386Sopenharmony_ci uint32_t subpass) { 583cb93a386Sopenharmony_ci const GrGeometryProcessor& geomProc = programInfo.geomProc(); 584cb93a386Sopenharmony_ci const GrPipeline& pipeline = programInfo.pipeline(); 585cb93a386Sopenharmony_ci 586cb93a386Sopenharmony_ci return Make(gpu, 587cb93a386Sopenharmony_ci geomProc.vertexAttributes(), 588cb93a386Sopenharmony_ci geomProc.instanceAttributes(), 589cb93a386Sopenharmony_ci programInfo.primitiveType(), 590cb93a386Sopenharmony_ci programInfo.origin(), 591cb93a386Sopenharmony_ci programInfo.nonGLStencilSettings(), 592cb93a386Sopenharmony_ci programInfo.numSamples(), 593cb93a386Sopenharmony_ci programInfo.numSamples() > 1, 594cb93a386Sopenharmony_ci pipeline.getXferProcessor().getBlendInfo(), 595cb93a386Sopenharmony_ci pipeline.isWireframe(), 596cb93a386Sopenharmony_ci pipeline.usesConservativeRaster(), 597cb93a386Sopenharmony_ci subpass, 598cb93a386Sopenharmony_ci shaderStageInfo, 599cb93a386Sopenharmony_ci shaderStageCount, 600cb93a386Sopenharmony_ci compatibleRenderPass, 601cb93a386Sopenharmony_ci layout, 602cb93a386Sopenharmony_ci /*ownsLayout=*/true, 603cb93a386Sopenharmony_ci cache); 604cb93a386Sopenharmony_ci} 605cb93a386Sopenharmony_ci 606cb93a386Sopenharmony_civoid GrVkPipeline::freeGPUData() const { 607cb93a386Sopenharmony_ci GR_VK_CALL(fGpu->vkInterface(), DestroyPipeline(fGpu->device(), fPipeline, nullptr)); 608cb93a386Sopenharmony_ci if (fPipelineLayout != VK_NULL_HANDLE) { 609cb93a386Sopenharmony_ci GR_VK_CALL(fGpu->vkInterface(), 610cb93a386Sopenharmony_ci DestroyPipelineLayout(fGpu->device(), fPipelineLayout, nullptr)); 611cb93a386Sopenharmony_ci } 612cb93a386Sopenharmony_ci} 613cb93a386Sopenharmony_ci 614cb93a386Sopenharmony_civoid GrVkPipeline::SetDynamicScissorRectState(GrVkGpu* gpu, 615cb93a386Sopenharmony_ci GrVkCommandBuffer* cmdBuffer, 616cb93a386Sopenharmony_ci SkISize colorAttachmentDimensions, 617cb93a386Sopenharmony_ci GrSurfaceOrigin rtOrigin, 618cb93a386Sopenharmony_ci const SkIRect& scissorRect) { 619cb93a386Sopenharmony_ci SkASSERT(scissorRect.isEmpty() || 620cb93a386Sopenharmony_ci SkIRect::MakeSize(colorAttachmentDimensions).contains(scissorRect)); 621cb93a386Sopenharmony_ci 622cb93a386Sopenharmony_ci VkRect2D scissor; 623cb93a386Sopenharmony_ci scissor.offset.x = scissorRect.fLeft; 624cb93a386Sopenharmony_ci scissor.extent.width = scissorRect.width(); 625cb93a386Sopenharmony_ci if (kTopLeft_GrSurfaceOrigin == rtOrigin) { 626cb93a386Sopenharmony_ci scissor.offset.y = scissorRect.fTop; 627cb93a386Sopenharmony_ci } else { 628cb93a386Sopenharmony_ci SkASSERT(kBottomLeft_GrSurfaceOrigin == rtOrigin); 629cb93a386Sopenharmony_ci scissor.offset.y = colorAttachmentDimensions.height() - scissorRect.fBottom; 630cb93a386Sopenharmony_ci } 631cb93a386Sopenharmony_ci scissor.extent.height = scissorRect.height(); 632cb93a386Sopenharmony_ci 633cb93a386Sopenharmony_ci SkASSERT(scissor.offset.x >= 0); 634cb93a386Sopenharmony_ci SkASSERT(scissor.offset.y >= 0); 635cb93a386Sopenharmony_ci cmdBuffer->setScissor(gpu, 0, 1, &scissor); 636cb93a386Sopenharmony_ci} 637cb93a386Sopenharmony_ci 638cb93a386Sopenharmony_civoid GrVkPipeline::SetDynamicViewportState(GrVkGpu* gpu, 639cb93a386Sopenharmony_ci GrVkCommandBuffer* cmdBuffer, 640cb93a386Sopenharmony_ci SkISize colorAttachmentDimensions) { 641cb93a386Sopenharmony_ci // We always use one viewport the size of the RT 642cb93a386Sopenharmony_ci VkViewport viewport; 643cb93a386Sopenharmony_ci viewport.x = 0.0f; 644cb93a386Sopenharmony_ci viewport.y = 0.0f; 645cb93a386Sopenharmony_ci viewport.width = SkIntToScalar(colorAttachmentDimensions.width()); 646cb93a386Sopenharmony_ci viewport.height = SkIntToScalar(colorAttachmentDimensions.height()); 647cb93a386Sopenharmony_ci viewport.minDepth = 0.0f; 648cb93a386Sopenharmony_ci viewport.maxDepth = 1.0f; 649cb93a386Sopenharmony_ci cmdBuffer->setViewport(gpu, 0, 1, &viewport); 650cb93a386Sopenharmony_ci} 651cb93a386Sopenharmony_ci 652cb93a386Sopenharmony_civoid GrVkPipeline::SetDynamicBlendConstantState(GrVkGpu* gpu, 653cb93a386Sopenharmony_ci GrVkCommandBuffer* cmdBuffer, 654cb93a386Sopenharmony_ci const GrSwizzle& swizzle, 655cb93a386Sopenharmony_ci const GrXferProcessor& xferProcessor) { 656cb93a386Sopenharmony_ci const GrXferProcessor::BlendInfo& blendInfo = xferProcessor.getBlendInfo(); 657cb93a386Sopenharmony_ci GrBlendCoeff srcCoeff = blendInfo.fSrcBlend; 658cb93a386Sopenharmony_ci GrBlendCoeff dstCoeff = blendInfo.fDstBlend; 659cb93a386Sopenharmony_ci float floatColors[4]; 660cb93a386Sopenharmony_ci if (GrBlendCoeffRefsConstant(srcCoeff) || GrBlendCoeffRefsConstant(dstCoeff)) { 661cb93a386Sopenharmony_ci // Swizzle the blend to match what the shader will output. 662cb93a386Sopenharmony_ci SkPMColor4f blendConst = swizzle.applyTo(blendInfo.fBlendConstant); 663cb93a386Sopenharmony_ci floatColors[0] = blendConst.fR; 664cb93a386Sopenharmony_ci floatColors[1] = blendConst.fG; 665cb93a386Sopenharmony_ci floatColors[2] = blendConst.fB; 666cb93a386Sopenharmony_ci floatColors[3] = blendConst.fA; 667cb93a386Sopenharmony_ci cmdBuffer->setBlendConstants(gpu, floatColors); 668cb93a386Sopenharmony_ci } 669cb93a386Sopenharmony_ci} 670