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