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