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