xref: /third_party/skia/src/gpu/vk/GrVkPipeline.cpp (revision cb93a386)
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