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