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 13 #include "GrVkGpu.h" 14 #include "GrVkProgramDesc.h" 15 #include "GrVkRenderTarget.h" 16 #include "GrVkUtil.h" 17 18 static inline const VkFormat& attrib_type_to_vkformat(GrVertexAttribType type) { 19 SkASSERT(type >= 0 && type < kGrVertexAttribTypeCount); 20 static const VkFormat kFormats[kGrVertexAttribTypeCount] = { 21 VK_FORMAT_R32_SFLOAT, // kFloat_GrVertexAttribType 22 VK_FORMAT_R32G32_SFLOAT, // kVec2f_GrVertexAttribType 23 VK_FORMAT_R32G32B32_SFLOAT, // kVec3f_GrVertexAttribType 24 VK_FORMAT_R32G32B32A32_SFLOAT, // kVec4f_GrVertexAttribType 25 VK_FORMAT_R8_UNORM, // kUByte_GrVertexAttribType 26 VK_FORMAT_R8G8B8A8_UNORM, // kVec4ub_GrVertexAttribType 27 VK_FORMAT_R16G16_UNORM, // kVec2us_GrVertexAttribType 28 }; 29 GR_STATIC_ASSERT(0 == kFloat_GrVertexAttribType); 30 GR_STATIC_ASSERT(1 == kVec2f_GrVertexAttribType); 31 GR_STATIC_ASSERT(2 == kVec3f_GrVertexAttribType); 32 GR_STATIC_ASSERT(3 == kVec4f_GrVertexAttribType); 33 GR_STATIC_ASSERT(4 == kUByte_GrVertexAttribType); 34 GR_STATIC_ASSERT(5 == kVec4ub_GrVertexAttribType); 35 GR_STATIC_ASSERT(6 == kVec2us_GrVertexAttribType); 36 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kFormats) == kGrVertexAttribTypeCount); 37 return kFormats[type]; 38 } 39 40 static void setup_vertex_input_state(const GrPrimitiveProcessor& primProc, 41 VkPipelineVertexInputStateCreateInfo* vertexInputInfo, 42 VkVertexInputBindingDescription* bindingDesc, 43 int maxBindingDescCount, 44 VkVertexInputAttributeDescription* attributeDesc, 45 int maxAttributeDescCount) { 46 // for now we have only one vertex buffer and one binding 47 memset(bindingDesc, 0, sizeof(VkVertexInputBindingDescription)); 48 bindingDesc->binding = 0; 49 bindingDesc->stride = (uint32_t)primProc.getVertexStride(); 50 bindingDesc->inputRate = VK_VERTEX_INPUT_RATE_VERTEX; 51 52 // setup attribute descriptions 53 int vaCount = primProc.numAttribs(); 54 SkASSERT(vaCount < maxAttributeDescCount); 55 if (vaCount > 0) { 56 size_t offset = 0; 57 for (int attribIndex = 0; attribIndex < vaCount; attribIndex++) { 58 const GrGeometryProcessor::Attribute& attrib = primProc.getAttrib(attribIndex); 59 GrVertexAttribType attribType = attrib.fType; 60 61 VkVertexInputAttributeDescription& vkAttrib = attributeDesc[attribIndex]; 62 vkAttrib.location = attribIndex; // for now assume location = attribIndex 63 vkAttrib.binding = 0; // for now only one vertex buffer & binding 64 vkAttrib.format = attrib_type_to_vkformat(attribType); 65 vkAttrib.offset = static_cast<uint32_t>(offset); 66 offset += attrib.fOffset; 67 } 68 } 69 70 memset(vertexInputInfo, 0, sizeof(VkPipelineVertexInputStateCreateInfo)); 71 vertexInputInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; 72 vertexInputInfo->pNext = nullptr; 73 vertexInputInfo->flags = 0; 74 vertexInputInfo->vertexBindingDescriptionCount = 1; 75 vertexInputInfo->pVertexBindingDescriptions = bindingDesc; 76 vertexInputInfo->vertexAttributeDescriptionCount = vaCount; 77 vertexInputInfo->pVertexAttributeDescriptions = attributeDesc; 78 } 79 80 81 static void setup_input_assembly_state(GrPrimitiveType primitiveType, 82 VkPipelineInputAssemblyStateCreateInfo* inputAssemblyInfo) { 83 static const VkPrimitiveTopology gPrimitiveType2VkTopology[] = { 84 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 85 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, 86 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, 87 VK_PRIMITIVE_TOPOLOGY_POINT_LIST, 88 VK_PRIMITIVE_TOPOLOGY_LINE_LIST, 89 VK_PRIMITIVE_TOPOLOGY_LINE_STRIP 90 }; 91 92 memset(inputAssemblyInfo, 0, sizeof(VkPipelineInputAssemblyStateCreateInfo)); 93 inputAssemblyInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; 94 inputAssemblyInfo->pNext = nullptr; 95 inputAssemblyInfo->flags = 0; 96 inputAssemblyInfo->primitiveRestartEnable = false; 97 inputAssemblyInfo->topology = gPrimitiveType2VkTopology[primitiveType]; 98 } 99 100 101 VkStencilOp stencil_op_to_vk_stencil_op(GrStencilOp op) { 102 static const VkStencilOp gTable[] = { 103 VK_STENCIL_OP_KEEP, // kKeep_StencilOp 104 VK_STENCIL_OP_REPLACE, // kReplace_StencilOp 105 VK_STENCIL_OP_INCREMENT_AND_WRAP, // kIncWrap_StencilOp 106 VK_STENCIL_OP_INCREMENT_AND_CLAMP, // kIncClamp_StencilOp 107 VK_STENCIL_OP_DECREMENT_AND_WRAP, // kDecWrap_StencilOp 108 VK_STENCIL_OP_DECREMENT_AND_CLAMP, // kDecClamp_StencilOp 109 VK_STENCIL_OP_ZERO, // kZero_StencilOp 110 VK_STENCIL_OP_INVERT, // kInvert_StencilOp 111 }; 112 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gTable) == kStencilOpCount); 113 GR_STATIC_ASSERT(0 == kKeep_StencilOp); 114 GR_STATIC_ASSERT(1 == kReplace_StencilOp); 115 GR_STATIC_ASSERT(2 == kIncWrap_StencilOp); 116 GR_STATIC_ASSERT(3 == kIncClamp_StencilOp); 117 GR_STATIC_ASSERT(4 == kDecWrap_StencilOp); 118 GR_STATIC_ASSERT(5 == kDecClamp_StencilOp); 119 GR_STATIC_ASSERT(6 == kZero_StencilOp); 120 GR_STATIC_ASSERT(7 == kInvert_StencilOp); 121 SkASSERT((unsigned)op < kStencilOpCount); 122 return gTable[op]; 123 } 124 125 VkCompareOp stencil_func_to_vk_compare_op(GrStencilFunc basicFunc) { 126 static const VkCompareOp gTable[] = { 127 VK_COMPARE_OP_ALWAYS, // kAlways_StencilFunc 128 VK_COMPARE_OP_NEVER, // kNever_StencilFunc 129 VK_COMPARE_OP_GREATER, // kGreater_StencilFunc 130 VK_COMPARE_OP_GREATER_OR_EQUAL, // kGEqual_StencilFunc 131 VK_COMPARE_OP_LESS, // kLess_StencilFunc 132 VK_COMPARE_OP_LESS_OR_EQUAL, // kLEqual_StencilFunc, 133 VK_COMPARE_OP_EQUAL, // kEqual_StencilFunc, 134 VK_COMPARE_OP_NOT_EQUAL, // kNotEqual_StencilFunc, 135 }; 136 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gTable) == kBasicStencilFuncCount); 137 GR_STATIC_ASSERT(0 == kAlways_StencilFunc); 138 GR_STATIC_ASSERT(1 == kNever_StencilFunc); 139 GR_STATIC_ASSERT(2 == kGreater_StencilFunc); 140 GR_STATIC_ASSERT(3 == kGEqual_StencilFunc); 141 GR_STATIC_ASSERT(4 == kLess_StencilFunc); 142 GR_STATIC_ASSERT(5 == kLEqual_StencilFunc); 143 GR_STATIC_ASSERT(6 == kEqual_StencilFunc); 144 GR_STATIC_ASSERT(7 == kNotEqual_StencilFunc); 145 SkASSERT((unsigned)basicFunc < kBasicStencilFuncCount); 146 147 return gTable[basicFunc]; 148 } 149 150 void setup_depth_stencil_state(const GrVkGpu* gpu, 151 const GrStencilSettings& stencilSettings, 152 VkPipelineDepthStencilStateCreateInfo* stencilInfo) { 153 memset(stencilInfo, 0, sizeof(VkPipelineDepthStencilStateCreateInfo)); 154 stencilInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; 155 stencilInfo->pNext = nullptr; 156 stencilInfo->flags = 0; 157 // set depth testing defaults 158 stencilInfo->depthTestEnable = VK_FALSE; 159 stencilInfo->depthWriteEnable = VK_FALSE; 160 stencilInfo->depthCompareOp = VK_COMPARE_OP_ALWAYS; 161 stencilInfo->depthBoundsTestEnable = VK_FALSE; 162 stencilInfo->stencilTestEnable = !stencilSettings.isDisabled(); 163 if (!stencilSettings.isDisabled()) { 164 // Set front face 165 GrStencilSettings::Face face = GrStencilSettings::kFront_Face; 166 stencilInfo->front.failOp = stencil_op_to_vk_stencil_op(stencilSettings.failOp(face)); 167 stencilInfo->front.passOp = stencil_op_to_vk_stencil_op(stencilSettings.passOp(face)); 168 stencilInfo->front.depthFailOp = stencilInfo->front.failOp; 169 stencilInfo->front.compareOp = stencil_func_to_vk_compare_op(stencilSettings.func(face)); 170 stencilInfo->front.compareMask = stencilSettings.funcMask(face); 171 stencilInfo->front.writeMask = 0; 172 stencilInfo->front.reference = 0; 173 174 // Set back face 175 face = GrStencilSettings::kBack_Face; 176 stencilInfo->back.failOp = stencil_op_to_vk_stencil_op(stencilSettings.failOp(face)); 177 stencilInfo->back.passOp = stencil_op_to_vk_stencil_op(stencilSettings.passOp(face)); 178 stencilInfo->back.depthFailOp = stencilInfo->front.failOp; 179 stencilInfo->back.compareOp = stencil_func_to_vk_compare_op(stencilSettings.func(face)); 180 stencilInfo->back.compareMask = stencilSettings.funcMask(face); 181 stencilInfo->back.writeMask = 0; 182 stencilInfo->back.reference = 0; 183 } 184 stencilInfo->minDepthBounds = 0.0f; 185 stencilInfo->maxDepthBounds = 1.0f; 186 } 187 188 void setup_viewport_scissor_state(const GrVkGpu* gpu, 189 const GrPipeline& pipeline, 190 const GrVkRenderTarget* vkRT, 191 VkPipelineViewportStateCreateInfo* viewportInfo, 192 VkViewport* viewport, 193 VkRect2D* scissor) { 194 memset(viewportInfo, 0, sizeof(VkPipelineViewportStateCreateInfo)); 195 viewportInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; 196 viewportInfo->pNext = nullptr; 197 viewportInfo->flags = 0; 198 199 viewport->x = 0.0f; 200 viewport->y = 0.0f; 201 viewport->width = SkIntToScalar(vkRT->width()); 202 viewport->height = SkIntToScalar(vkRT->height()); 203 viewport->minDepth = 0.0f; 204 viewport->maxDepth = 1.0f; 205 viewportInfo->viewportCount = 1; 206 viewportInfo->pViewports = viewport; 207 208 const GrScissorState& scissorState = pipeline.getScissorState(); 209 if (scissorState.enabled() && 210 !scissorState.rect().contains(0, 0, vkRT->width(), vkRT->height())) { 211 // This all assumes the scissorState has previously been clipped to the device space render 212 // target. 213 scissor->offset.x = scissorState.rect().fLeft; 214 scissor->extent.width = scissorState.rect().width(); 215 if (kTopLeft_GrSurfaceOrigin == vkRT->origin()) { 216 scissor->offset.y = scissorState.rect().fTop; 217 } else { 218 SkASSERT(kBottomLeft_GrSurfaceOrigin == vkRT->origin()); 219 scissor->offset.y = vkRT->height() - scissorState.rect().fBottom; 220 } 221 scissor->extent.height = scissorState.rect().height(); 222 223 viewportInfo->scissorCount = 1; 224 viewportInfo->pScissors = scissor; 225 SkASSERT(scissor->offset.x >= 0); 226 SkASSERT(scissor->offset.x + scissor->extent.width <= (uint32_t)vkRT->width()); 227 SkASSERT(scissor->offset.y >= 0); 228 SkASSERT(scissor->offset.y + scissor->extent.height <= (uint32_t)vkRT->height()); 229 } else { 230 scissor->extent.width = vkRT->width(); 231 scissor->extent.height = vkRT->height(); 232 scissor->offset.x = 0; 233 scissor->offset.y = 0; 234 viewportInfo->scissorCount = 1; 235 viewportInfo->pScissors = scissor; 236 } 237 SkASSERT(viewportInfo->viewportCount == viewportInfo->scissorCount); 238 } 239 240 void setup_multisample_state(const GrPipeline& pipeline, 241 VkPipelineMultisampleStateCreateInfo* multisampleInfo) { 242 memset(multisampleInfo, 0, sizeof(VkPipelineMultisampleStateCreateInfo)); 243 multisampleInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; 244 multisampleInfo->pNext = nullptr; 245 multisampleInfo->flags = 0; 246 int numSamples = pipeline.getRenderTarget()->numColorSamples(); 247 SkAssertResult(GrSampleCountToVkSampleCount(numSamples, 248 &multisampleInfo->rasterizationSamples)); 249 multisampleInfo->sampleShadingEnable = VK_FALSE; 250 multisampleInfo->minSampleShading = 0; 251 multisampleInfo->pSampleMask = nullptr; 252 multisampleInfo->alphaToCoverageEnable = VK_FALSE; 253 multisampleInfo->alphaToOneEnable = VK_FALSE; 254 } 255 256 static VkBlendFactor blend_coeff_to_vk_blend(GrBlendCoeff coeff) { 257 static const VkBlendFactor gTable[] = { 258 VK_BLEND_FACTOR_ZERO, // kZero_GrBlendCoeff 259 VK_BLEND_FACTOR_ONE, // kOne_GrBlendCoeff 260 VK_BLEND_FACTOR_SRC_COLOR, // kSC_GrBlendCoeff 261 VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, // kISC_GrBlendCoeff 262 VK_BLEND_FACTOR_DST_COLOR, // kDC_GrBlendCoeff 263 VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR, // kIDC_GrBlendCoeff 264 VK_BLEND_FACTOR_SRC_ALPHA, // kSA_GrBlendCoeff 265 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // kISA_GrBlendCoeff 266 VK_BLEND_FACTOR_DST_ALPHA, // kDA_GrBlendCoeff 267 VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA, // kIDA_GrBlendCoeff 268 VK_BLEND_FACTOR_CONSTANT_COLOR, // kConstC_GrBlendCoeff 269 VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR, // kIConstC_GrBlendCoeff 270 VK_BLEND_FACTOR_CONSTANT_ALPHA, // kConstA_GrBlendCoeff 271 VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA, // kIConstA_GrBlendCoeff 272 VK_BLEND_FACTOR_SRC1_COLOR, // kS2C_GrBlendCoeff 273 VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, // kIS2C_GrBlendCoeff 274 VK_BLEND_FACTOR_SRC1_ALPHA, // kS2A_GrBlendCoeff 275 VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA, // kIS2A_GrBlendCoeff 276 277 }; 278 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gTable) == kGrBlendCoeffCnt); 279 GR_STATIC_ASSERT(0 == kZero_GrBlendCoeff); 280 GR_STATIC_ASSERT(1 == kOne_GrBlendCoeff); 281 GR_STATIC_ASSERT(2 == kSC_GrBlendCoeff); 282 GR_STATIC_ASSERT(3 == kISC_GrBlendCoeff); 283 GR_STATIC_ASSERT(4 == kDC_GrBlendCoeff); 284 GR_STATIC_ASSERT(5 == kIDC_GrBlendCoeff); 285 GR_STATIC_ASSERT(6 == kSA_GrBlendCoeff); 286 GR_STATIC_ASSERT(7 == kISA_GrBlendCoeff); 287 GR_STATIC_ASSERT(8 == kDA_GrBlendCoeff); 288 GR_STATIC_ASSERT(9 == kIDA_GrBlendCoeff); 289 GR_STATIC_ASSERT(10 == kConstC_GrBlendCoeff); 290 GR_STATIC_ASSERT(11 == kIConstC_GrBlendCoeff); 291 GR_STATIC_ASSERT(12 == kConstA_GrBlendCoeff); 292 GR_STATIC_ASSERT(13 == kIConstA_GrBlendCoeff); 293 GR_STATIC_ASSERT(14 == kS2C_GrBlendCoeff); 294 GR_STATIC_ASSERT(15 == kIS2C_GrBlendCoeff); 295 GR_STATIC_ASSERT(16 == kS2A_GrBlendCoeff); 296 GR_STATIC_ASSERT(17 == kIS2A_GrBlendCoeff); 297 298 SkASSERT((unsigned)coeff < kGrBlendCoeffCnt); 299 return gTable[coeff]; 300 } 301 302 303 static VkBlendOp blend_equation_to_vk_blend_op(GrBlendEquation equation) { 304 static const VkBlendOp gTable[] = { 305 VK_BLEND_OP_ADD, // kAdd_GrBlendEquation 306 VK_BLEND_OP_SUBTRACT, // kSubtract_GrBlendEquation 307 VK_BLEND_OP_REVERSE_SUBTRACT, // kReverseSubtract_GrBlendEquation 308 }; 309 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gTable) == kFirstAdvancedGrBlendEquation); 310 GR_STATIC_ASSERT(0 == kAdd_GrBlendEquation); 311 GR_STATIC_ASSERT(1 == kSubtract_GrBlendEquation); 312 GR_STATIC_ASSERT(2 == kReverseSubtract_GrBlendEquation); 313 314 SkASSERT((unsigned)equation < kGrBlendCoeffCnt); 315 return gTable[equation]; 316 } 317 318 bool blend_coeff_refs_constant(GrBlendCoeff coeff) { 319 static const bool gCoeffReferencesBlendConst[] = { 320 false, 321 false, 322 false, 323 false, 324 false, 325 false, 326 false, 327 false, 328 false, 329 false, 330 true, 331 true, 332 true, 333 true, 334 335 // extended blend coeffs 336 false, 337 false, 338 false, 339 false, 340 }; 341 return gCoeffReferencesBlendConst[coeff]; 342 GR_STATIC_ASSERT(kGrBlendCoeffCnt == SK_ARRAY_COUNT(gCoeffReferencesBlendConst)); 343 // Individual enum asserts already made in blend_coeff_to_vk_blend 344 } 345 346 void setup_color_blend_state(const GrVkGpu* gpu, 347 const GrPipeline& pipeline, 348 VkPipelineColorBlendStateCreateInfo* colorBlendInfo, 349 VkPipelineColorBlendAttachmentState* attachmentState) { 350 GrXferProcessor::BlendInfo blendInfo; 351 pipeline.getXferProcessor().getBlendInfo(&blendInfo); 352 353 GrBlendEquation equation = blendInfo.fEquation; 354 GrBlendCoeff srcCoeff = blendInfo.fSrcBlend; 355 GrBlendCoeff dstCoeff = blendInfo.fDstBlend; 356 bool blendOff = (kAdd_GrBlendEquation == equation || kSubtract_GrBlendEquation == equation) && 357 kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff; 358 359 memset(attachmentState, 0, sizeof(VkPipelineColorBlendAttachmentState)); 360 attachmentState->blendEnable = !blendOff; 361 if (!blendOff) { 362 attachmentState->srcColorBlendFactor = blend_coeff_to_vk_blend(srcCoeff); 363 attachmentState->dstColorBlendFactor = blend_coeff_to_vk_blend(dstCoeff); 364 attachmentState->colorBlendOp = blend_equation_to_vk_blend_op(equation); 365 attachmentState->srcAlphaBlendFactor = blend_coeff_to_vk_blend(srcCoeff); 366 attachmentState->dstAlphaBlendFactor = blend_coeff_to_vk_blend(dstCoeff); 367 attachmentState->alphaBlendOp = blend_equation_to_vk_blend_op(equation); 368 } 369 attachmentState->colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | 370 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; 371 372 memset(colorBlendInfo, 0, sizeof(VkPipelineColorBlendStateCreateInfo)); 373 colorBlendInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; 374 colorBlendInfo->pNext = nullptr; 375 colorBlendInfo->flags = 0; 376 colorBlendInfo->logicOpEnable = VK_FALSE; 377 colorBlendInfo->attachmentCount = 1; 378 colorBlendInfo->pAttachments = attachmentState; 379 if (blend_coeff_refs_constant(srcCoeff) || blend_coeff_refs_constant(dstCoeff)) { 380 GrColorToRGBAFloat(blendInfo.fBlendConstant, colorBlendInfo->blendConstants); 381 } 382 } 383 384 VkCullModeFlags draw_face_to_vk_cull_mode(GrPipelineBuilder::DrawFace drawFace) { 385 // Assumes that we've set the front face to be ccw 386 static const VkCullModeFlags gTable[] = { 387 VK_CULL_MODE_NONE, // kBoth_DrawFace 388 VK_CULL_MODE_BACK_BIT, // kCCW_DrawFace, cull back face 389 VK_CULL_MODE_FRONT_BIT, // kCW_DrawFace, cull front face 390 }; 391 GR_STATIC_ASSERT(0 == GrPipelineBuilder::kBoth_DrawFace); 392 GR_STATIC_ASSERT(1 == GrPipelineBuilder::kCCW_DrawFace); 393 GR_STATIC_ASSERT(2 == GrPipelineBuilder::kCW_DrawFace); 394 SkASSERT((unsigned)drawFace <= 2); 395 396 return gTable[drawFace]; 397 } 398 399 void setup_raster_state(const GrVkGpu* gpu, 400 const GrPipeline& pipeline, 401 VkPipelineRasterizationStateCreateInfo* rasterInfo) { 402 memset(rasterInfo, 0, sizeof(VkPipelineRasterizationStateCreateInfo)); 403 rasterInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; 404 rasterInfo->pNext = nullptr; 405 rasterInfo->flags = 0; 406 rasterInfo->depthClampEnable = VK_FALSE; 407 rasterInfo->rasterizerDiscardEnable = VK_FALSE; 408 rasterInfo->polygonMode = VK_POLYGON_MODE_FILL; 409 rasterInfo->cullMode = draw_face_to_vk_cull_mode(pipeline.getDrawFace()); 410 rasterInfo->frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; 411 rasterInfo->depthBiasEnable = VK_FALSE; 412 rasterInfo->depthBiasConstantFactor = 0.0f; 413 rasterInfo->depthBiasClamp = 0.0f; 414 rasterInfo->depthBiasSlopeFactor = 0.0f; 415 rasterInfo->lineWidth = 1.0f; 416 } 417 418 void setup_dynamic_state(const GrVkGpu* gpu, 419 const GrPipeline& pipeline, 420 VkPipelineDynamicStateCreateInfo* dynamicInfo) { 421 memset(dynamicInfo, 0, sizeof(VkPipelineDynamicStateCreateInfo)); 422 dynamicInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; 423 // TODO: mask out any state we might want to set dynamically 424 dynamicInfo->dynamicStateCount = 0; 425 } 426 427 GrVkPipeline* GrVkPipeline::Create(GrVkGpu* gpu, const GrPipeline& pipeline, 428 const GrPrimitiveProcessor& primProc, 429 VkPipelineShaderStageCreateInfo* shaderStageInfo, 430 int shaderStageCount, 431 GrPrimitiveType primitiveType, 432 const GrVkRenderPass& renderPass, 433 VkPipelineLayout layout) { 434 VkPipelineVertexInputStateCreateInfo vertexInputInfo; 435 VkVertexInputBindingDescription bindingDesc; 436 // TODO: allocate this based on VkPhysicalDeviceLimits::maxVertexInputAttributes 437 static const int kMaxVertexAttributes = 16; 438 static VkVertexInputAttributeDescription attributeDesc[kMaxVertexAttributes]; 439 setup_vertex_input_state(primProc, &vertexInputInfo, &bindingDesc, 1, 440 attributeDesc, kMaxVertexAttributes); 441 442 VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo; 443 setup_input_assembly_state(primitiveType, &inputAssemblyInfo); 444 445 VkPipelineDepthStencilStateCreateInfo depthStencilInfo; 446 setup_depth_stencil_state(gpu, pipeline.getStencil(), &depthStencilInfo); 447 448 GrRenderTarget* rt = pipeline.getRenderTarget(); 449 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(rt); 450 VkPipelineViewportStateCreateInfo viewportInfo; 451 VkViewport viewport; 452 VkRect2D scissor; 453 setup_viewport_scissor_state(gpu, pipeline, vkRT, &viewportInfo, &viewport, &scissor); 454 455 VkPipelineMultisampleStateCreateInfo multisampleInfo; 456 setup_multisample_state(pipeline, &multisampleInfo); 457 458 // We will only have one color attachment per pipeline. 459 VkPipelineColorBlendAttachmentState attachmentStates[1]; 460 VkPipelineColorBlendStateCreateInfo colorBlendInfo; 461 setup_color_blend_state(gpu, pipeline, &colorBlendInfo, attachmentStates); 462 463 VkPipelineRasterizationStateCreateInfo rasterInfo; 464 setup_raster_state(gpu, pipeline, &rasterInfo); 465 466 VkPipelineDynamicStateCreateInfo dynamicInfo; 467 setup_dynamic_state(gpu, pipeline, &dynamicInfo); 468 469 VkGraphicsPipelineCreateInfo pipelineCreateInfo; 470 memset(&pipelineCreateInfo, 0, sizeof(VkGraphicsPipelineCreateInfo)); 471 pipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; 472 pipelineCreateInfo.pNext = nullptr; 473 pipelineCreateInfo.flags = 0; 474 pipelineCreateInfo.stageCount = shaderStageCount; 475 pipelineCreateInfo.pStages = shaderStageInfo; 476 pipelineCreateInfo.pVertexInputState = &vertexInputInfo; 477 pipelineCreateInfo.pInputAssemblyState = &inputAssemblyInfo; 478 pipelineCreateInfo.pTessellationState = nullptr; 479 pipelineCreateInfo.pViewportState = &viewportInfo; 480 pipelineCreateInfo.pRasterizationState = &rasterInfo; 481 pipelineCreateInfo.pMultisampleState = &multisampleInfo; 482 pipelineCreateInfo.pDepthStencilState = &depthStencilInfo; 483 pipelineCreateInfo.pColorBlendState = &colorBlendInfo; 484 pipelineCreateInfo.pDynamicState = &dynamicInfo; 485 pipelineCreateInfo.layout = layout; 486 pipelineCreateInfo.renderPass = renderPass.vkRenderPass(); 487 pipelineCreateInfo.subpass = 0; 488 pipelineCreateInfo.basePipelineHandle = VK_NULL_HANDLE; 489 pipelineCreateInfo.basePipelineIndex = -1; 490 491 VkPipeline vkPipeline; 492 VkResult err = GR_VK_CALL(gpu->vkInterface(), CreateGraphicsPipelines(gpu->device(), 493 nullptr, 1, 494 &pipelineCreateInfo, 495 nullptr, &vkPipeline)); 496 if (err) { 497 return nullptr; 498 } 499 500 return new GrVkPipeline(vkPipeline); 501 } 502 503 void GrVkPipeline::freeGPUData(const GrVkGpu* gpu) const { 504 GR_VK_CALL(gpu->vkInterface(), DestroyPipeline(gpu->device(), fPipeline, nullptr)); 505 } 506 507 508