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