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