• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
attrib_type_to_vkformat(GrVertexAttribType type)23 static 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 
setup_vertex_input_state(const GrGeometryProcessor::AttributeSet & vertexAttribs,const GrGeometryProcessor::AttributeSet & instanceAttribs,VkPipelineVertexInputStateCreateInfo * vertexInputInfo,SkSTArray<2,VkVertexInputBindingDescription,true> * bindingDescs,VkVertexInputAttributeDescription * attributeDesc)81 static 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 
gr_primitive_type_to_vk_topology(GrPrimitiveType primitiveType)150 static 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 
setup_input_assembly_state(GrPrimitiveType primitiveType,VkPipelineInputAssemblyStateCreateInfo * inputAssemblyInfo)169 static 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 
stencil_op_to_vk_stencil_op(GrStencilOp op)179 static 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 
stencil_func_to_vk_compare_op(GrStencilTest test)203 static 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 
setup_stencil_op_state(VkStencilOpState * opState,const GrStencilSettings::Face & stencilFace)228 static 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 
setup_depth_stencil_state(const GrStencilSettings & stencilSettings,GrSurfaceOrigin origin,VkPipelineDepthStencilStateCreateInfo * stencilInfo)239 static 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 
setup_viewport_scissor_state(VkPipelineViewportStateCreateInfo * viewportInfo)267 static 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 
setup_multisample_state(int numSamples,const GrCaps * caps,VkPipelineMultisampleStateCreateInfo * multisampleInfo)282 static 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 
blend_coeff_to_vk_blend(GrBlendCoeff coeff)298 static 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 
blend_equation_to_vk_blend_op(GrBlendEquation equation)338 static 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 
setup_color_blend_state(const GrXferProcessor::BlendInfo & blendInfo,VkPipelineColorBlendStateCreateInfo * colorBlendInfo,VkPipelineColorBlendAttachmentState * attachmentState)389 static 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 
setup_raster_state(bool isWireframe,const GrCaps * caps,VkPipelineRasterizationStateCreateInfo * rasterInfo)425 static 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 
setup_conservative_raster_info(VkPipelineRasterizationConservativeStateCreateInfoEXT * conservativeRasterInfo)445 static 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 
setup_dynamic_state(VkPipelineDynamicStateCreateInfo * dynamicInfo,VkDynamicState * dynamicStates)458 static 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 
Make(GrVkGpu * gpu,const GrGeometryProcessor::AttributeSet & vertexAttribs,const GrGeometryProcessor::AttributeSet & instanceAttribs,GrPrimitiveType primitiveType,GrSurfaceOrigin origin,const GrStencilSettings & stencilSettings,int numSamples,bool isHWAntialiasState,const GrXferProcessor::BlendInfo & blendInfo,bool isWireframe,bool useConservativeRaster,uint32_t subpass,VkPipelineShaderStageCreateInfo * shaderStageInfo,int shaderStageCount,VkRenderPass compatibleRenderPass,VkPipelineLayout layout,bool ownsLayout,VkPipelineCache cache)471 sk_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 
Make(GrVkGpu * gpu,const GrProgramInfo & programInfo,VkPipelineShaderStageCreateInfo * shaderStageInfo,int shaderStageCount,VkRenderPass compatibleRenderPass,VkPipelineLayout layout,VkPipelineCache cache,uint32_t subpass)575 sk_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 
freeGPUData() const606 void 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 
SetDynamicScissorRectState(GrVkGpu * gpu,GrVkCommandBuffer * cmdBuffer,SkISize colorAttachmentDimensions,GrSurfaceOrigin rtOrigin,const SkIRect & scissorRect)614 void 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 
SetDynamicViewportState(GrVkGpu * gpu,GrVkCommandBuffer * cmdBuffer,SkISize colorAttachmentDimensions)638 void 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 
SetDynamicBlendConstantState(GrVkGpu * gpu,GrVkCommandBuffer * cmdBuffer,const GrSwizzle & swizzle,const GrXferProcessor & xferProcessor)652 void 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