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