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 10 #include "GrGeometryProcessor.h" 11 #include "GrPipeline.h" 12 #include "GrVkCommandBuffer.h" 13 #include "GrVkGpu.h" 14 #include "GrVkRenderTarget.h" 15 #include "GrVkUtil.h" 16 17 static inline VkFormat attrib_type_to_vkformat(GrVertexAttribType type) { 18 switch (type) { 19 case kFloat_GrVertexAttribType: 20 return VK_FORMAT_R32_SFLOAT; 21 case kVec2f_GrVertexAttribType: 22 return VK_FORMAT_R32G32_SFLOAT; 23 case kVec3f_GrVertexAttribType: 24 return VK_FORMAT_R32G32B32_SFLOAT; 25 case kVec4f_GrVertexAttribType: 26 return VK_FORMAT_R32G32B32A32_SFLOAT; 27 case kVec2i_GrVertexAttribType: 28 return VK_FORMAT_R32G32_SINT; 29 case kVec3i_GrVertexAttribType: 30 return VK_FORMAT_R32G32B32_SINT; 31 case kVec4i_GrVertexAttribType: 32 return VK_FORMAT_R32G32B32A32_SINT; 33 case kUByte_GrVertexAttribType: 34 return VK_FORMAT_R8_UNORM; 35 case kVec4ub_GrVertexAttribType: 36 return VK_FORMAT_R8G8B8A8_UNORM; 37 case kVec2us_GrVertexAttribType: 38 return VK_FORMAT_R16G16_UNORM; 39 case kInt_GrVertexAttribType: 40 return VK_FORMAT_R32_SINT; 41 case kUint_GrVertexAttribType: 42 return VK_FORMAT_R32_UINT; 43 } 44 SkFAIL("Unknown vertex attrib type"); 45 return VK_FORMAT_UNDEFINED; 46 } 47 48 static void setup_vertex_input_state(const GrPrimitiveProcessor& primProc, 49 VkPipelineVertexInputStateCreateInfo* vertexInputInfo, 50 SkSTArray<2, VkVertexInputBindingDescription, true>* bindingDescs, 51 VkVertexInputAttributeDescription* attributeDesc) { 52 uint32_t vertexBinding, instanceBinding; 53 54 if (primProc.hasVertexAttribs()) { 55 vertexBinding = bindingDescs->count(); 56 bindingDescs->push_back() = { 57 vertexBinding, 58 (uint32_t) primProc.getVertexStride(), 59 VK_VERTEX_INPUT_RATE_VERTEX 60 }; 61 } 62 63 if (primProc.hasInstanceAttribs()) { 64 instanceBinding = bindingDescs->count(); 65 bindingDescs->push_back() = { 66 instanceBinding, 67 (uint32_t) primProc.getInstanceStride(), 68 VK_VERTEX_INPUT_RATE_INSTANCE 69 }; 70 } 71 72 // setup attribute descriptions 73 int vaCount = primProc.numAttribs(); 74 if (vaCount > 0) { 75 for (int attribIndex = 0; attribIndex < vaCount; attribIndex++) { 76 using InputRate = GrPrimitiveProcessor::Attribute::InputRate; 77 const GrGeometryProcessor::Attribute& attrib = primProc.getAttrib(attribIndex); 78 VkVertexInputAttributeDescription& vkAttrib = attributeDesc[attribIndex]; 79 vkAttrib.location = attribIndex; // for now assume location = attribIndex 80 vkAttrib.binding = InputRate::kPerInstance == attrib.fInputRate ? instanceBinding 81 : vertexBinding; 82 vkAttrib.format = attrib_type_to_vkformat(attrib.fType); 83 vkAttrib.offset = attrib.fOffsetInRecord; 84 } 85 } 86 87 memset(vertexInputInfo, 0, sizeof(VkPipelineVertexInputStateCreateInfo)); 88 vertexInputInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; 89 vertexInputInfo->pNext = nullptr; 90 vertexInputInfo->flags = 0; 91 vertexInputInfo->vertexBindingDescriptionCount = bindingDescs->count(); 92 vertexInputInfo->pVertexBindingDescriptions = bindingDescs->begin(); 93 vertexInputInfo->vertexAttributeDescriptionCount = vaCount; 94 vertexInputInfo->pVertexAttributeDescriptions = attributeDesc; 95 } 96 97 static VkPrimitiveTopology gr_primitive_type_to_vk_topology(GrPrimitiveType primitiveType) { 98 switch (primitiveType) { 99 case GrPrimitiveType::kTriangles: 100 return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; 101 case GrPrimitiveType::kTriangleStrip: 102 return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; 103 case GrPrimitiveType::kTriangleFan: 104 return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN; 105 case GrPrimitiveType::kPoints: 106 return VK_PRIMITIVE_TOPOLOGY_POINT_LIST; 107 case GrPrimitiveType::kLines: 108 return VK_PRIMITIVE_TOPOLOGY_LINE_LIST; 109 case GrPrimitiveType::kLineStrip: 110 return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP; 111 case GrPrimitiveType::kLinesAdjacency: 112 return VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY; 113 } 114 SkFAIL("invalid GrPrimitiveType"); 115 return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; 116 } 117 118 static void setup_input_assembly_state(GrPrimitiveType primitiveType, 119 VkPipelineInputAssemblyStateCreateInfo* inputAssemblyInfo) { 120 memset(inputAssemblyInfo, 0, sizeof(VkPipelineInputAssemblyStateCreateInfo)); 121 inputAssemblyInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; 122 inputAssemblyInfo->pNext = nullptr; 123 inputAssemblyInfo->flags = 0; 124 inputAssemblyInfo->primitiveRestartEnable = false; 125 inputAssemblyInfo->topology = gr_primitive_type_to_vk_topology(primitiveType); 126 } 127 128 129 static VkStencilOp stencil_op_to_vk_stencil_op(GrStencilOp op) { 130 static const VkStencilOp gTable[] = { 131 VK_STENCIL_OP_KEEP, // kKeep 132 VK_STENCIL_OP_ZERO, // kZero 133 VK_STENCIL_OP_REPLACE, // kReplace 134 VK_STENCIL_OP_INVERT, // kInvert 135 VK_STENCIL_OP_INCREMENT_AND_WRAP, // kIncWrap 136 VK_STENCIL_OP_DECREMENT_AND_WRAP, // kDecWrap 137 VK_STENCIL_OP_INCREMENT_AND_CLAMP, // kIncClamp 138 VK_STENCIL_OP_DECREMENT_AND_CLAMP, // kDecClamp 139 }; 140 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gTable) == kGrStencilOpCount); 141 GR_STATIC_ASSERT(0 == (int)GrStencilOp::kKeep); 142 GR_STATIC_ASSERT(1 == (int)GrStencilOp::kZero); 143 GR_STATIC_ASSERT(2 == (int)GrStencilOp::kReplace); 144 GR_STATIC_ASSERT(3 == (int)GrStencilOp::kInvert); 145 GR_STATIC_ASSERT(4 == (int)GrStencilOp::kIncWrap); 146 GR_STATIC_ASSERT(5 == (int)GrStencilOp::kDecWrap); 147 GR_STATIC_ASSERT(6 == (int)GrStencilOp::kIncClamp); 148 GR_STATIC_ASSERT(7 == (int)GrStencilOp::kDecClamp); 149 SkASSERT(op < (GrStencilOp)kGrStencilOpCount); 150 return gTable[(int)op]; 151 } 152 153 static VkCompareOp stencil_func_to_vk_compare_op(GrStencilTest test) { 154 static const VkCompareOp gTable[] = { 155 VK_COMPARE_OP_ALWAYS, // kAlways 156 VK_COMPARE_OP_NEVER, // kNever 157 VK_COMPARE_OP_GREATER, // kGreater 158 VK_COMPARE_OP_GREATER_OR_EQUAL, // kGEqual 159 VK_COMPARE_OP_LESS, // kLess 160 VK_COMPARE_OP_LESS_OR_EQUAL, // kLEqual 161 VK_COMPARE_OP_EQUAL, // kEqual 162 VK_COMPARE_OP_NOT_EQUAL, // kNotEqual 163 }; 164 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gTable) == kGrStencilTestCount); 165 GR_STATIC_ASSERT(0 == (int)GrStencilTest::kAlways); 166 GR_STATIC_ASSERT(1 == (int)GrStencilTest::kNever); 167 GR_STATIC_ASSERT(2 == (int)GrStencilTest::kGreater); 168 GR_STATIC_ASSERT(3 == (int)GrStencilTest::kGEqual); 169 GR_STATIC_ASSERT(4 == (int)GrStencilTest::kLess); 170 GR_STATIC_ASSERT(5 == (int)GrStencilTest::kLEqual); 171 GR_STATIC_ASSERT(6 == (int)GrStencilTest::kEqual); 172 GR_STATIC_ASSERT(7 == (int)GrStencilTest::kNotEqual); 173 SkASSERT(test < (GrStencilTest)kGrStencilTestCount); 174 175 return gTable[(int)test]; 176 } 177 178 static void setup_depth_stencil_state(const GrStencilSettings& stencilSettings, 179 VkPipelineDepthStencilStateCreateInfo* stencilInfo) { 180 memset(stencilInfo, 0, sizeof(VkPipelineDepthStencilStateCreateInfo)); 181 stencilInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; 182 stencilInfo->pNext = nullptr; 183 stencilInfo->flags = 0; 184 // set depth testing defaults 185 stencilInfo->depthTestEnable = VK_FALSE; 186 stencilInfo->depthWriteEnable = VK_FALSE; 187 stencilInfo->depthCompareOp = VK_COMPARE_OP_ALWAYS; 188 stencilInfo->depthBoundsTestEnable = VK_FALSE; 189 stencilInfo->stencilTestEnable = !stencilSettings.isDisabled(); 190 if (!stencilSettings.isDisabled()) { 191 // Set front face 192 const GrStencilSettings::Face& front = stencilSettings.front(); 193 stencilInfo->front.failOp = stencil_op_to_vk_stencil_op(front.fFailOp); 194 stencilInfo->front.passOp = stencil_op_to_vk_stencil_op(front.fPassOp); 195 stencilInfo->front.depthFailOp = stencilInfo->front.failOp; 196 stencilInfo->front.compareOp = stencil_func_to_vk_compare_op(front.fTest); 197 stencilInfo->front.compareMask = front.fTestMask; 198 stencilInfo->front.writeMask = front.fWriteMask; 199 stencilInfo->front.reference = front.fRef; 200 201 // Set back face 202 if (!stencilSettings.isTwoSided()) { 203 stencilInfo->back = stencilInfo->front; 204 } else { 205 const GrStencilSettings::Face& back = stencilSettings.back(); 206 stencilInfo->back.failOp = stencil_op_to_vk_stencil_op(back.fFailOp); 207 stencilInfo->back.passOp = stencil_op_to_vk_stencil_op(back.fPassOp); 208 stencilInfo->back.depthFailOp = stencilInfo->front.failOp; 209 stencilInfo->back.compareOp = stencil_func_to_vk_compare_op(back.fTest); 210 stencilInfo->back.compareMask = back.fTestMask; 211 stencilInfo->back.writeMask = back.fWriteMask; 212 stencilInfo->back.reference = back.fRef; 213 } 214 } 215 stencilInfo->minDepthBounds = 0.0f; 216 stencilInfo->maxDepthBounds = 1.0f; 217 } 218 219 static void setup_viewport_scissor_state(VkPipelineViewportStateCreateInfo* viewportInfo) { 220 memset(viewportInfo, 0, sizeof(VkPipelineViewportStateCreateInfo)); 221 viewportInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; 222 viewportInfo->pNext = nullptr; 223 viewportInfo->flags = 0; 224 225 viewportInfo->viewportCount = 1; 226 viewportInfo->pViewports = nullptr; // This is set dynamically 227 228 viewportInfo->scissorCount = 1; 229 viewportInfo->pScissors = nullptr; // This is set dynamically 230 231 SkASSERT(viewportInfo->viewportCount == viewportInfo->scissorCount); 232 } 233 234 static void setup_multisample_state(const GrPipeline& pipeline, 235 const GrPrimitiveProcessor& primProc, 236 const GrCaps* caps, 237 VkPipelineMultisampleStateCreateInfo* multisampleInfo) { 238 memset(multisampleInfo, 0, sizeof(VkPipelineMultisampleStateCreateInfo)); 239 multisampleInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; 240 multisampleInfo->pNext = nullptr; 241 multisampleInfo->flags = 0; 242 int numSamples = pipeline.getRenderTarget()->numColorSamples(); 243 SkAssertResult(GrSampleCountToVkSampleCount(numSamples, 244 &multisampleInfo->rasterizationSamples)); 245 float sampleShading = primProc.getSampleShading(); 246 SkASSERT(sampleShading == 0.0f || caps->sampleShadingSupport()); 247 multisampleInfo->sampleShadingEnable = sampleShading > 0.0f; 248 multisampleInfo->minSampleShading = sampleShading; 249 multisampleInfo->pSampleMask = nullptr; 250 multisampleInfo->alphaToCoverageEnable = VK_FALSE; 251 multisampleInfo->alphaToOneEnable = VK_FALSE; 252 } 253 254 static VkBlendFactor blend_coeff_to_vk_blend(GrBlendCoeff coeff) { 255 static const VkBlendFactor gTable[] = { 256 VK_BLEND_FACTOR_ZERO, // kZero_GrBlendCoeff 257 VK_BLEND_FACTOR_ONE, // kOne_GrBlendCoeff 258 VK_BLEND_FACTOR_SRC_COLOR, // kSC_GrBlendCoeff 259 VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, // kISC_GrBlendCoeff 260 VK_BLEND_FACTOR_DST_COLOR, // kDC_GrBlendCoeff 261 VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR, // kIDC_GrBlendCoeff 262 VK_BLEND_FACTOR_SRC_ALPHA, // kSA_GrBlendCoeff 263 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // kISA_GrBlendCoeff 264 VK_BLEND_FACTOR_DST_ALPHA, // kDA_GrBlendCoeff 265 VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA, // kIDA_GrBlendCoeff 266 VK_BLEND_FACTOR_CONSTANT_COLOR, // kConstC_GrBlendCoeff 267 VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR, // kIConstC_GrBlendCoeff 268 VK_BLEND_FACTOR_CONSTANT_ALPHA, // kConstA_GrBlendCoeff 269 VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA, // kIConstA_GrBlendCoeff 270 VK_BLEND_FACTOR_SRC1_COLOR, // kS2C_GrBlendCoeff 271 VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, // kIS2C_GrBlendCoeff 272 VK_BLEND_FACTOR_SRC1_ALPHA, // kS2A_GrBlendCoeff 273 VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA, // kIS2A_GrBlendCoeff 274 275 }; 276 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gTable) == kGrBlendCoeffCnt); 277 GR_STATIC_ASSERT(0 == kZero_GrBlendCoeff); 278 GR_STATIC_ASSERT(1 == kOne_GrBlendCoeff); 279 GR_STATIC_ASSERT(2 == kSC_GrBlendCoeff); 280 GR_STATIC_ASSERT(3 == kISC_GrBlendCoeff); 281 GR_STATIC_ASSERT(4 == kDC_GrBlendCoeff); 282 GR_STATIC_ASSERT(5 == kIDC_GrBlendCoeff); 283 GR_STATIC_ASSERT(6 == kSA_GrBlendCoeff); 284 GR_STATIC_ASSERT(7 == kISA_GrBlendCoeff); 285 GR_STATIC_ASSERT(8 == kDA_GrBlendCoeff); 286 GR_STATIC_ASSERT(9 == kIDA_GrBlendCoeff); 287 GR_STATIC_ASSERT(10 == kConstC_GrBlendCoeff); 288 GR_STATIC_ASSERT(11 == kIConstC_GrBlendCoeff); 289 GR_STATIC_ASSERT(12 == kConstA_GrBlendCoeff); 290 GR_STATIC_ASSERT(13 == kIConstA_GrBlendCoeff); 291 GR_STATIC_ASSERT(14 == kS2C_GrBlendCoeff); 292 GR_STATIC_ASSERT(15 == kIS2C_GrBlendCoeff); 293 GR_STATIC_ASSERT(16 == kS2A_GrBlendCoeff); 294 GR_STATIC_ASSERT(17 == kIS2A_GrBlendCoeff); 295 296 SkASSERT((unsigned)coeff < kGrBlendCoeffCnt); 297 return gTable[coeff]; 298 } 299 300 301 static VkBlendOp blend_equation_to_vk_blend_op(GrBlendEquation equation) { 302 static const VkBlendOp gTable[] = { 303 VK_BLEND_OP_ADD, // kAdd_GrBlendEquation 304 VK_BLEND_OP_SUBTRACT, // kSubtract_GrBlendEquation 305 VK_BLEND_OP_REVERSE_SUBTRACT, // kReverseSubtract_GrBlendEquation 306 }; 307 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gTable) == kFirstAdvancedGrBlendEquation); 308 GR_STATIC_ASSERT(0 == kAdd_GrBlendEquation); 309 GR_STATIC_ASSERT(1 == kSubtract_GrBlendEquation); 310 GR_STATIC_ASSERT(2 == kReverseSubtract_GrBlendEquation); 311 312 SkASSERT((unsigned)equation < kGrBlendCoeffCnt); 313 return gTable[equation]; 314 } 315 316 static bool blend_coeff_refs_constant(GrBlendCoeff coeff) { 317 static const bool gCoeffReferencesBlendConst[] = { 318 false, 319 false, 320 false, 321 false, 322 false, 323 false, 324 false, 325 false, 326 false, 327 false, 328 true, 329 true, 330 true, 331 true, 332 333 // extended blend coeffs 334 false, 335 false, 336 false, 337 false, 338 }; 339 return gCoeffReferencesBlendConst[coeff]; 340 GR_STATIC_ASSERT(kGrBlendCoeffCnt == SK_ARRAY_COUNT(gCoeffReferencesBlendConst)); 341 // Individual enum asserts already made in blend_coeff_to_vk_blend 342 } 343 344 static void setup_color_blend_state(const GrPipeline& pipeline, 345 VkPipelineColorBlendStateCreateInfo* colorBlendInfo, 346 VkPipelineColorBlendAttachmentState* attachmentState) { 347 GrXferProcessor::BlendInfo blendInfo; 348 pipeline.getXferProcessor().getBlendInfo(&blendInfo); 349 350 GrBlendEquation equation = blendInfo.fEquation; 351 GrBlendCoeff srcCoeff = blendInfo.fSrcBlend; 352 GrBlendCoeff dstCoeff = blendInfo.fDstBlend; 353 bool blendOff = (kAdd_GrBlendEquation == equation || kSubtract_GrBlendEquation == equation) && 354 kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff; 355 356 memset(attachmentState, 0, sizeof(VkPipelineColorBlendAttachmentState)); 357 attachmentState->blendEnable = !blendOff; 358 if (!blendOff) { 359 attachmentState->srcColorBlendFactor = blend_coeff_to_vk_blend(srcCoeff); 360 attachmentState->dstColorBlendFactor = blend_coeff_to_vk_blend(dstCoeff); 361 attachmentState->colorBlendOp = blend_equation_to_vk_blend_op(equation); 362 attachmentState->srcAlphaBlendFactor = blend_coeff_to_vk_blend(srcCoeff); 363 attachmentState->dstAlphaBlendFactor = blend_coeff_to_vk_blend(dstCoeff); 364 attachmentState->alphaBlendOp = blend_equation_to_vk_blend_op(equation); 365 } 366 367 if (!blendInfo.fWriteColor) { 368 attachmentState->colorWriteMask = 0; 369 } else { 370 attachmentState->colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | 371 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; 372 } 373 374 memset(colorBlendInfo, 0, sizeof(VkPipelineColorBlendStateCreateInfo)); 375 colorBlendInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; 376 colorBlendInfo->pNext = nullptr; 377 colorBlendInfo->flags = 0; 378 colorBlendInfo->logicOpEnable = VK_FALSE; 379 colorBlendInfo->attachmentCount = 1; 380 colorBlendInfo->pAttachments = attachmentState; 381 // colorBlendInfo->blendConstants is set dynamically 382 } 383 384 static void setup_raster_state(const GrPipeline& pipeline, 385 const GrCaps* caps, 386 VkPipelineRasterizationStateCreateInfo* rasterInfo) { 387 memset(rasterInfo, 0, sizeof(VkPipelineRasterizationStateCreateInfo)); 388 rasterInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; 389 rasterInfo->pNext = nullptr; 390 rasterInfo->flags = 0; 391 rasterInfo->depthClampEnable = VK_FALSE; 392 rasterInfo->rasterizerDiscardEnable = VK_FALSE; 393 rasterInfo->polygonMode = caps->wireframeMode() ? VK_POLYGON_MODE_LINE 394 : VK_POLYGON_MODE_FILL; 395 rasterInfo->cullMode = VK_CULL_MODE_NONE; 396 rasterInfo->frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; 397 rasterInfo->depthBiasEnable = VK_FALSE; 398 rasterInfo->depthBiasConstantFactor = 0.0f; 399 rasterInfo->depthBiasClamp = 0.0f; 400 rasterInfo->depthBiasSlopeFactor = 0.0f; 401 rasterInfo->lineWidth = 1.0f; 402 } 403 404 static void setup_dynamic_state(VkPipelineDynamicStateCreateInfo* dynamicInfo, 405 VkDynamicState* dynamicStates) { 406 memset(dynamicInfo, 0, sizeof(VkPipelineDynamicStateCreateInfo)); 407 dynamicInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; 408 dynamicInfo->pNext = VK_NULL_HANDLE; 409 dynamicInfo->flags = 0; 410 dynamicStates[0] = VK_DYNAMIC_STATE_VIEWPORT; 411 dynamicStates[1] = VK_DYNAMIC_STATE_SCISSOR; 412 dynamicStates[2] = VK_DYNAMIC_STATE_BLEND_CONSTANTS; 413 dynamicInfo->dynamicStateCount = 3; 414 dynamicInfo->pDynamicStates = dynamicStates; 415 } 416 417 GrVkPipeline* GrVkPipeline::Create(GrVkGpu* gpu, const GrPipeline& pipeline, 418 const GrStencilSettings& stencil, 419 const GrPrimitiveProcessor& primProc, 420 VkPipelineShaderStageCreateInfo* shaderStageInfo, 421 int shaderStageCount, 422 GrPrimitiveType primitiveType, 423 const GrVkRenderPass& renderPass, 424 VkPipelineLayout layout, 425 VkPipelineCache cache) { 426 VkPipelineVertexInputStateCreateInfo vertexInputInfo; 427 SkSTArray<2, VkVertexInputBindingDescription, true> bindingDescs; 428 SkSTArray<16, VkVertexInputAttributeDescription> attributeDesc; 429 SkASSERT(primProc.numAttribs() <= gpu->vkCaps().maxVertexAttributes()); 430 VkVertexInputAttributeDescription* pAttribs = attributeDesc.push_back_n(primProc.numAttribs()); 431 setup_vertex_input_state(primProc, &vertexInputInfo, &bindingDescs, pAttribs); 432 433 VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo; 434 setup_input_assembly_state(primitiveType, &inputAssemblyInfo); 435 436 VkPipelineDepthStencilStateCreateInfo depthStencilInfo; 437 setup_depth_stencil_state(stencil, &depthStencilInfo); 438 439 VkPipelineViewportStateCreateInfo viewportInfo; 440 setup_viewport_scissor_state(&viewportInfo); 441 442 VkPipelineMultisampleStateCreateInfo multisampleInfo; 443 setup_multisample_state(pipeline, primProc, gpu->caps(), &multisampleInfo); 444 445 // We will only have one color attachment per pipeline. 446 VkPipelineColorBlendAttachmentState attachmentStates[1]; 447 VkPipelineColorBlendStateCreateInfo colorBlendInfo; 448 setup_color_blend_state(pipeline, &colorBlendInfo, attachmentStates); 449 450 VkPipelineRasterizationStateCreateInfo rasterInfo; 451 setup_raster_state(pipeline, gpu->caps(), &rasterInfo); 452 453 VkDynamicState dynamicStates[3]; 454 VkPipelineDynamicStateCreateInfo dynamicInfo; 455 setup_dynamic_state(&dynamicInfo, dynamicStates); 456 457 VkGraphicsPipelineCreateInfo pipelineCreateInfo; 458 memset(&pipelineCreateInfo, 0, sizeof(VkGraphicsPipelineCreateInfo)); 459 pipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; 460 pipelineCreateInfo.pNext = nullptr; 461 pipelineCreateInfo.flags = 0; 462 pipelineCreateInfo.stageCount = shaderStageCount; 463 pipelineCreateInfo.pStages = shaderStageInfo; 464 pipelineCreateInfo.pVertexInputState = &vertexInputInfo; 465 pipelineCreateInfo.pInputAssemblyState = &inputAssemblyInfo; 466 pipelineCreateInfo.pTessellationState = nullptr; 467 pipelineCreateInfo.pViewportState = &viewportInfo; 468 pipelineCreateInfo.pRasterizationState = &rasterInfo; 469 pipelineCreateInfo.pMultisampleState = &multisampleInfo; 470 pipelineCreateInfo.pDepthStencilState = &depthStencilInfo; 471 pipelineCreateInfo.pColorBlendState = &colorBlendInfo; 472 pipelineCreateInfo.pDynamicState = &dynamicInfo; 473 pipelineCreateInfo.layout = layout; 474 pipelineCreateInfo.renderPass = renderPass.vkRenderPass(); 475 pipelineCreateInfo.subpass = 0; 476 pipelineCreateInfo.basePipelineHandle = VK_NULL_HANDLE; 477 pipelineCreateInfo.basePipelineIndex = -1; 478 479 VkPipeline vkPipeline; 480 VkResult err = GR_VK_CALL(gpu->vkInterface(), CreateGraphicsPipelines(gpu->device(), 481 cache, 1, 482 &pipelineCreateInfo, 483 nullptr, &vkPipeline)); 484 if (err) { 485 return nullptr; 486 } 487 488 return new GrVkPipeline(vkPipeline); 489 } 490 491 void GrVkPipeline::freeGPUData(const GrVkGpu* gpu) const { 492 GR_VK_CALL(gpu->vkInterface(), DestroyPipeline(gpu->device(), fPipeline, nullptr)); 493 } 494 495 void GrVkPipeline::SetDynamicScissorRectState(GrVkGpu* gpu, 496 GrVkCommandBuffer* cmdBuffer, 497 const GrRenderTarget* renderTarget, 498 SkIRect scissorRect) { 499 if (!scissorRect.intersect(SkIRect::MakeWH(renderTarget->width(), renderTarget->height()))) { 500 scissorRect.setEmpty(); 501 } 502 503 VkRect2D scissor; 504 scissor.offset.x = scissorRect.fLeft; 505 scissor.extent.width = scissorRect.width(); 506 if (kTopLeft_GrSurfaceOrigin == renderTarget->origin()) { 507 scissor.offset.y = scissorRect.fTop; 508 } else { 509 SkASSERT(kBottomLeft_GrSurfaceOrigin == renderTarget->origin()); 510 scissor.offset.y = renderTarget->height() - scissorRect.fBottom; 511 } 512 scissor.extent.height = scissorRect.height(); 513 514 SkASSERT(scissor.offset.x >= 0); 515 SkASSERT(scissor.offset.y >= 0); 516 cmdBuffer->setScissor(gpu, 0, 1, &scissor); 517 } 518 519 void GrVkPipeline::SetDynamicViewportState(GrVkGpu* gpu, 520 GrVkCommandBuffer* cmdBuffer, 521 const GrRenderTarget* renderTarget) { 522 // We always use one viewport the size of the RT 523 VkViewport viewport; 524 viewport.x = 0.0f; 525 viewport.y = 0.0f; 526 viewport.width = SkIntToScalar(renderTarget->width()); 527 viewport.height = SkIntToScalar(renderTarget->height()); 528 viewport.minDepth = 0.0f; 529 viewport.maxDepth = 1.0f; 530 cmdBuffer->setViewport(gpu, 0, 1, &viewport); 531 } 532 533 void GrVkPipeline::SetDynamicBlendConstantState(GrVkGpu* gpu, 534 GrVkCommandBuffer* cmdBuffer, 535 GrPixelConfig pixelConfig, 536 const GrXferProcessor& xferProcessor) { 537 GrXferProcessor::BlendInfo blendInfo; 538 xferProcessor.getBlendInfo(&blendInfo); 539 GrBlendCoeff srcCoeff = blendInfo.fSrcBlend; 540 GrBlendCoeff dstCoeff = blendInfo.fDstBlend; 541 float floatColors[4]; 542 if (blend_coeff_refs_constant(srcCoeff) || blend_coeff_refs_constant(dstCoeff)) { 543 // Swizzle the blend to match what the shader will output. 544 const GrSwizzle& swizzle = gpu->caps()->shaderCaps()->configOutputSwizzle(pixelConfig); 545 GrColor blendConst = swizzle.applyTo(blendInfo.fBlendConstant); 546 GrColorToRGBAFloat(blendConst, floatColors); 547 } else { 548 memset(floatColors, 0, 4 * sizeof(float)); 549 } 550 cmdBuffer->setBlendConstants(gpu, floatColors); 551 } 552