OLD | NEW |
| (Empty) |
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 "GrVkPipeline.h" | |
9 | |
10 #include "GrGeometryProcessor.h" | |
11 #include "GrPipeline.h" | |
12 | |
13 #include "GrVkGpu.h" | |
14 #include "GrVkProgramDesc.h" | |
15 #include "GrVkRenderTarget.h" | |
16 #include "GrVkUtil.h" | |
17 | |
18 static inline const VkFormat& attrib_type_to_vkformat(GrVertexAttribType type) { | |
19 SkASSERT(type >= 0 && type < kGrVertexAttribTypeCount); | |
20 static const VkFormat kFormats[kGrVertexAttribTypeCount] = { | |
21 VK_FORMAT_R32_SFLOAT, // kFloat_GrVertexAttribType | |
22 VK_FORMAT_R32G32_SFLOAT, // kVec2f_GrVertexAttribType | |
23 VK_FORMAT_R32G32B32_SFLOAT, // kVec3f_GrVertexAttribType | |
24 VK_FORMAT_R32G32B32A32_SFLOAT, // kVec4f_GrVertexAttribType | |
25 VK_FORMAT_R8_UNORM, // kUByte_GrVertexAttribType | |
26 VK_FORMAT_R8G8B8A8_UNORM, // kVec4ub_GrVertexAttribType | |
27 VK_FORMAT_R16G16_SSCALED, // kVec2s_GrVertexAttribType | |
28 }; | |
29 GR_STATIC_ASSERT(0 == kFloat_GrVertexAttribType); | |
30 GR_STATIC_ASSERT(1 == kVec2f_GrVertexAttribType); | |
31 GR_STATIC_ASSERT(2 == kVec3f_GrVertexAttribType); | |
32 GR_STATIC_ASSERT(3 == kVec4f_GrVertexAttribType); | |
33 GR_STATIC_ASSERT(4 == kUByte_GrVertexAttribType); | |
34 GR_STATIC_ASSERT(5 == kVec4ub_GrVertexAttribType); | |
35 GR_STATIC_ASSERT(6 == kVec2s_GrVertexAttribType); | |
36 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kFormats) == kGrVertexAttribTypeCount); | |
37 return kFormats[type]; | |
38 } | |
39 | |
40 static void setup_vertex_input_state(const GrPrimitiveProcessor& primProc, | |
41 VkPipelineVertexInputStateCreateInfo* verte
xInputInfo, | |
42 VkVertexInputBindingDescription* bindingDes
c, | |
43 int maxBindingDescCount, | |
44 VkVertexInputAttributeDescription* attribut
eDesc, | |
45 int maxAttributeDescCount) { | |
46 // for now we have only one vertex buffer and one binding | |
47 memset(bindingDesc, 0, sizeof(VkVertexInputBindingDescription)); | |
48 bindingDesc->binding = 0; | |
49 bindingDesc->stride = (uint32_t)primProc.getVertexStride(); | |
50 bindingDesc->inputRate = VK_VERTEX_INPUT_RATE_VERTEX; | |
51 | |
52 // setup attribute descriptions | |
53 int vaCount = primProc.numAttribs(); | |
54 SkASSERT(vaCount < maxAttributeDescCount); | |
55 if (vaCount > 0) { | |
56 size_t offset = 0; | |
57 for (int attribIndex = 0; attribIndex < vaCount; attribIndex++) { | |
58 const GrGeometryProcessor::Attribute& attrib = primProc.getAttrib(at
tribIndex); | |
59 GrVertexAttribType attribType = attrib.fType; | |
60 | |
61 VkVertexInputAttributeDescription& vkAttrib = attributeDesc[attribIn
dex]; | |
62 vkAttrib.location = attribIndex; // for now assume location = attrib
Index | |
63 vkAttrib.binding = 0; // for now only one vertex buffer & binding | |
64 vkAttrib.format = attrib_type_to_vkformat(attribType); | |
65 vkAttrib.offset = static_cast<uint32_t>(offset); | |
66 offset += attrib.fOffset; | |
67 } | |
68 } | |
69 | |
70 memset(vertexInputInfo, 0, sizeof(VkPipelineVertexInputStateCreateInfo)); | |
71 vertexInputInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREAT
E_INFO; | |
72 vertexInputInfo->pNext = nullptr; | |
73 vertexInputInfo->flags = 0; | |
74 vertexInputInfo->vertexBindingDescriptionCount = 1; | |
75 vertexInputInfo->pVertexBindingDescriptions = bindingDesc; | |
76 vertexInputInfo->vertexAttributeDescriptionCount = vaCount; | |
77 vertexInputInfo->pVertexAttributeDescriptions = attributeDesc; | |
78 } | |
79 | |
80 | |
81 static void setup_input_assembly_state(GrPrimitiveType primitiveType, | |
82 VkPipelineInputAssemblyStateCreateInfo* i
nputAssemblyInfo) { | |
83 static const VkPrimitiveTopology gPrimitiveType2VkTopology[] = { | |
84 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, | |
85 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, | |
86 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, | |
87 VK_PRIMITIVE_TOPOLOGY_POINT_LIST, | |
88 VK_PRIMITIVE_TOPOLOGY_LINE_LIST, | |
89 VK_PRIMITIVE_TOPOLOGY_LINE_STRIP | |
90 }; | |
91 | |
92 memset(inputAssemblyInfo, 0, sizeof(VkPipelineInputAssemblyStateCreateInfo))
; | |
93 inputAssemblyInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_C
REATE_INFO; | |
94 inputAssemblyInfo->pNext = nullptr; | |
95 inputAssemblyInfo->flags = 0; | |
96 inputAssemblyInfo->primitiveRestartEnable = false; | |
97 inputAssemblyInfo->topology = gPrimitiveType2VkTopology[primitiveType]; | |
98 } | |
99 | |
100 | |
101 VkStencilOp stencil_op_to_vk_stencil_op(GrStencilOp op) { | |
102 static const VkStencilOp gTable[] = { | |
103 VK_STENCIL_OP_KEEP, // kKeep_StencilOp | |
104 VK_STENCIL_OP_REPLACE, // kReplace_StencilOp | |
105 VK_STENCIL_OP_INCREMENT_AND_WRAP, // kIncWrap_StencilOp | |
106 VK_STENCIL_OP_INCREMENT_AND_CLAMP, // kIncClamp_StencilOp | |
107 VK_STENCIL_OP_DECREMENT_AND_WRAP, // kDecWrap_StencilOp | |
108 VK_STENCIL_OP_DECREMENT_AND_CLAMP, // kDecClamp_StencilOp | |
109 VK_STENCIL_OP_ZERO, // kZero_StencilOp | |
110 VK_STENCIL_OP_INVERT, // kInvert_StencilOp | |
111 }; | |
112 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gTable) == kStencilOpCount); | |
113 GR_STATIC_ASSERT(0 == kKeep_StencilOp); | |
114 GR_STATIC_ASSERT(1 == kReplace_StencilOp); | |
115 GR_STATIC_ASSERT(2 == kIncWrap_StencilOp); | |
116 GR_STATIC_ASSERT(3 == kIncClamp_StencilOp); | |
117 GR_STATIC_ASSERT(4 == kDecWrap_StencilOp); | |
118 GR_STATIC_ASSERT(5 == kDecClamp_StencilOp); | |
119 GR_STATIC_ASSERT(6 == kZero_StencilOp); | |
120 GR_STATIC_ASSERT(7 == kInvert_StencilOp); | |
121 SkASSERT((unsigned)op < kStencilOpCount); | |
122 return gTable[op]; | |
123 } | |
124 | |
125 VkCompareOp stencil_func_to_vk_compare_op(GrStencilFunc basicFunc) { | |
126 static const VkCompareOp gTable[] = { | |
127 VK_COMPARE_OP_ALWAYS, // kAlways_StencilFunc | |
128 VK_COMPARE_OP_NEVER, // kNever_StencilFunc | |
129 VK_COMPARE_OP_GREATER, // kGreater_StencilFunc | |
130 VK_COMPARE_OP_GREATER_OR_EQUAL, // kGEqual_StencilFunc | |
131 VK_COMPARE_OP_LESS, // kLess_StencilFunc | |
132 VK_COMPARE_OP_LESS_OR_EQUAL, // kLEqual_StencilFunc, | |
133 VK_COMPARE_OP_EQUAL, // kEqual_StencilFunc, | |
134 VK_COMPARE_OP_NOT_EQUAL, // kNotEqual_StencilFunc, | |
135 }; | |
136 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gTable) == kBasicStencilFuncCount); | |
137 GR_STATIC_ASSERT(0 == kAlways_StencilFunc); | |
138 GR_STATIC_ASSERT(1 == kNever_StencilFunc); | |
139 GR_STATIC_ASSERT(2 == kGreater_StencilFunc); | |
140 GR_STATIC_ASSERT(3 == kGEqual_StencilFunc); | |
141 GR_STATIC_ASSERT(4 == kLess_StencilFunc); | |
142 GR_STATIC_ASSERT(5 == kLEqual_StencilFunc); | |
143 GR_STATIC_ASSERT(6 == kEqual_StencilFunc); | |
144 GR_STATIC_ASSERT(7 == kNotEqual_StencilFunc); | |
145 SkASSERT((unsigned)basicFunc < kBasicStencilFuncCount); | |
146 | |
147 return gTable[basicFunc]; | |
148 } | |
149 | |
150 void setup_depth_stencil_state(const GrVkGpu* gpu, | |
151 const GrStencilSettings& stencilSettings, | |
152 VkPipelineDepthStencilStateCreateInfo* stencilInf
o) { | |
153 memset(stencilInfo, 0, sizeof(VkPipelineDepthStencilStateCreateInfo)); | |
154 stencilInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_I
NFO; | |
155 stencilInfo->pNext = nullptr; | |
156 stencilInfo->flags = 0; | |
157 // set depth testing defaults | |
158 stencilInfo->depthTestEnable = VK_FALSE; | |
159 stencilInfo->depthWriteEnable = VK_FALSE; | |
160 stencilInfo->depthCompareOp = VK_COMPARE_OP_ALWAYS; | |
161 stencilInfo->depthBoundsTestEnable = VK_FALSE; | |
162 stencilInfo->stencilTestEnable = !stencilSettings.isDisabled(); | |
163 if (!stencilSettings.isDisabled()) { | |
164 // Set front face | |
165 GrStencilSettings::Face face = GrStencilSettings::kFront_Face; | |
166 stencilInfo->front.failOp = stencil_op_to_vk_stencil_op(stencilSettings.
failOp(face)); | |
167 stencilInfo->front.passOp = stencil_op_to_vk_stencil_op(stencilSettings.
passOp(face)); | |
168 stencilInfo->front.depthFailOp = stencilInfo->front.failOp; | |
169 stencilInfo->front.compareOp = stencil_func_to_vk_compare_op(stencilSett
ings.func(face)); | |
170 stencilInfo->front.compareMask = stencilSettings.funcMask(face); | |
171 stencilInfo->front.writeMask = 0; | |
172 stencilInfo->front.reference = 0; | |
173 | |
174 // Set back face | |
175 face = GrStencilSettings::kBack_Face; | |
176 stencilInfo->back.failOp = stencil_op_to_vk_stencil_op(stencilSettings.f
ailOp(face)); | |
177 stencilInfo->back.passOp = stencil_op_to_vk_stencil_op(stencilSettings.p
assOp(face)); | |
178 stencilInfo->back.depthFailOp = stencilInfo->front.failOp; | |
179 stencilInfo->back.compareOp = stencil_func_to_vk_compare_op(stencilSetti
ngs.func(face)); | |
180 stencilInfo->back.compareMask = stencilSettings.funcMask(face); | |
181 stencilInfo->back.writeMask = 0; | |
182 stencilInfo->back.reference = 0; | |
183 } | |
184 stencilInfo->minDepthBounds = 0.0f; | |
185 stencilInfo->maxDepthBounds = 1.0f; | |
186 } | |
187 | |
188 void setup_viewport_scissor_state(const GrVkGpu* gpu, | |
189 const GrPipeline& pipeline, | |
190 const GrVkRenderTarget* vkRT, | |
191 VkPipelineViewportStateCreateInfo* viewportInf
o, | |
192 VkViewport* viewport, | |
193 VkRect2D* scissor) { | |
194 memset(viewportInfo, 0, sizeof(VkPipelineViewportStateCreateInfo)); | |
195 viewportInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; | |
196 viewportInfo->pNext = nullptr; | |
197 viewportInfo->flags = 0; | |
198 | |
199 viewport->x = 0.0f; | |
200 viewport->y = 0.0f; | |
201 viewport->width = SkIntToScalar(vkRT->width()); | |
202 viewport->height = SkIntToScalar(vkRT->height()); | |
203 viewport->minDepth = 0.0f; | |
204 viewport->maxDepth = 1.0f; | |
205 viewportInfo->viewportCount = 1; | |
206 viewportInfo->pViewports = viewport; | |
207 | |
208 const GrScissorState& scissorState = pipeline.getScissorState(); | |
209 if (scissorState.enabled() && | |
210 !scissorState.rect().contains(0, 0, vkRT->width(), vkRT->height())) { | |
211 // This all assumes the scissorState has previously been clipped to the
device space render | |
212 // target. | |
213 scissor->offset.x = scissorState.rect().fLeft; | |
214 scissor->extent.width = scissorState.rect().width(); | |
215 if (kTopLeft_GrSurfaceOrigin == vkRT->origin()) { | |
216 scissor->offset.y = scissorState.rect().fTop; | |
217 } else { | |
218 SkASSERT(kBottomLeft_GrSurfaceOrigin == vkRT->origin()); | |
219 scissor->offset.y = vkRT->height() - scissorState.rect().fBottom; | |
220 } | |
221 scissor->extent.height = scissorState.rect().height(); | |
222 | |
223 viewportInfo->scissorCount = 1; | |
224 viewportInfo->pScissors = scissor; | |
225 SkASSERT(scissor->offset.x >= 0); | |
226 SkASSERT(scissor->offset.x + scissor->extent.width <= (uint32_t)vkRT->wi
dth()); | |
227 SkASSERT(scissor->offset.y >= 0); | |
228 SkASSERT(scissor->offset.y + scissor->extent.height <= (uint32_t)vkRT->h
eight()); | |
229 } else { | |
230 scissor->extent.width = vkRT->width(); | |
231 scissor->extent.height = vkRT->height(); | |
232 scissor->offset.x = 0; | |
233 scissor->offset.y = 0; | |
234 viewportInfo->scissorCount = 1; | |
235 viewportInfo->pScissors = scissor; | |
236 } | |
237 SkASSERT(viewportInfo->viewportCount == viewportInfo->scissorCount); | |
238 } | |
239 | |
240 void setup_multisample_state(const GrPipeline& pipeline, | |
241 VkPipelineMultisampleStateCreateInfo* multisampleIn
fo) { | |
242 memset(multisampleInfo, 0, sizeof(VkPipelineMultisampleStateCreateInfo)); | |
243 multisampleInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE
_INFO; | |
244 multisampleInfo->pNext = nullptr; | |
245 multisampleInfo->flags = 0; | |
246 int numSamples = pipeline.getRenderTarget()->numColorSamples(); | |
247 SkAssertResult(GrSampleCountToVkSampleCount(numSamples, | |
248 &multisampleInfo->rasterizationSamples)); | |
249 multisampleInfo->sampleShadingEnable = VK_FALSE; | |
250 multisampleInfo->minSampleShading = 0; | |
251 multisampleInfo->pSampleMask = nullptr; | |
252 multisampleInfo->alphaToCoverageEnable = VK_FALSE; | |
253 multisampleInfo->alphaToOneEnable = VK_FALSE; | |
254 } | |
255 | |
256 static VkBlendFactor blend_coeff_to_vk_blend(GrBlendCoeff coeff) { | |
257 static const VkBlendFactor gTable[] = { | |
258 VK_BLEND_FACTOR_ZERO, // kZero_GrBlendCoeff | |
259 VK_BLEND_FACTOR_ONE, // kOne_GrBlendCoeff | |
260 VK_BLEND_FACTOR_SRC_COLOR, // kSC_GrBlendCoeff | |
261 VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, // kISC_GrBlendCoeff | |
262 VK_BLEND_FACTOR_DST_COLOR, // kDC_GrBlendCoeff | |
263 VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR, // kIDC_GrBlendCoeff | |
264 VK_BLEND_FACTOR_SRC_ALPHA, // kSA_GrBlendCoeff | |
265 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // kISA_GrBlendCoeff | |
266 VK_BLEND_FACTOR_DST_ALPHA, // kDA_GrBlendCoeff | |
267 VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA, // kIDA_GrBlendCoeff | |
268 VK_BLEND_FACTOR_CONSTANT_COLOR, // kConstC_GrBlendCoeff | |
269 VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR, // kIConstC_GrBlendCoeff | |
270 VK_BLEND_FACTOR_CONSTANT_ALPHA, // kConstA_GrBlendCoeff | |
271 VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA, // kIConstA_GrBlendCoeff | |
272 VK_BLEND_FACTOR_SRC1_COLOR, // kS2C_GrBlendCoeff | |
273 VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, // kIS2C_GrBlendCoeff | |
274 VK_BLEND_FACTOR_SRC1_ALPHA, // kS2A_GrBlendCoeff | |
275 VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA, // kIS2A_GrBlendCoeff | |
276 | |
277 }; | |
278 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gTable) == kGrBlendCoeffCnt); | |
279 GR_STATIC_ASSERT(0 == kZero_GrBlendCoeff); | |
280 GR_STATIC_ASSERT(1 == kOne_GrBlendCoeff); | |
281 GR_STATIC_ASSERT(2 == kSC_GrBlendCoeff); | |
282 GR_STATIC_ASSERT(3 == kISC_GrBlendCoeff); | |
283 GR_STATIC_ASSERT(4 == kDC_GrBlendCoeff); | |
284 GR_STATIC_ASSERT(5 == kIDC_GrBlendCoeff); | |
285 GR_STATIC_ASSERT(6 == kSA_GrBlendCoeff); | |
286 GR_STATIC_ASSERT(7 == kISA_GrBlendCoeff); | |
287 GR_STATIC_ASSERT(8 == kDA_GrBlendCoeff); | |
288 GR_STATIC_ASSERT(9 == kIDA_GrBlendCoeff); | |
289 GR_STATIC_ASSERT(10 == kConstC_GrBlendCoeff); | |
290 GR_STATIC_ASSERT(11 == kIConstC_GrBlendCoeff); | |
291 GR_STATIC_ASSERT(12 == kConstA_GrBlendCoeff); | |
292 GR_STATIC_ASSERT(13 == kIConstA_GrBlendCoeff); | |
293 GR_STATIC_ASSERT(14 == kS2C_GrBlendCoeff); | |
294 GR_STATIC_ASSERT(15 == kIS2C_GrBlendCoeff); | |
295 GR_STATIC_ASSERT(16 == kS2A_GrBlendCoeff); | |
296 GR_STATIC_ASSERT(17 == kIS2A_GrBlendCoeff); | |
297 | |
298 SkASSERT((unsigned)coeff < kGrBlendCoeffCnt); | |
299 return gTable[coeff]; | |
300 } | |
301 | |
302 | |
303 static VkBlendOp blend_equation_to_vk_blend_op(GrBlendEquation equation) { | |
304 static const VkBlendOp gTable[] = { | |
305 VK_BLEND_OP_ADD, // kAdd_GrBlendEquation | |
306 VK_BLEND_OP_SUBTRACT, // kSubtract_GrBlendEquation | |
307 VK_BLEND_OP_REVERSE_SUBTRACT, // kReverseSubtract_GrBlendEquation | |
308 }; | |
309 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gTable) == kFirstAdvancedGrBlendEquation); | |
310 GR_STATIC_ASSERT(0 == kAdd_GrBlendEquation); | |
311 GR_STATIC_ASSERT(1 == kSubtract_GrBlendEquation); | |
312 GR_STATIC_ASSERT(2 == kReverseSubtract_GrBlendEquation); | |
313 | |
314 SkASSERT((unsigned)equation < kGrBlendCoeffCnt); | |
315 return gTable[equation]; | |
316 } | |
317 | |
318 bool blend_coeff_refs_constant(GrBlendCoeff coeff) { | |
319 static const bool gCoeffReferencesBlendConst[] = { | |
320 false, | |
321 false, | |
322 false, | |
323 false, | |
324 false, | |
325 false, | |
326 false, | |
327 false, | |
328 false, | |
329 false, | |
330 true, | |
331 true, | |
332 true, | |
333 true, | |
334 | |
335 // extended blend coeffs | |
336 false, | |
337 false, | |
338 false, | |
339 false, | |
340 }; | |
341 return gCoeffReferencesBlendConst[coeff]; | |
342 GR_STATIC_ASSERT(kGrBlendCoeffCnt == SK_ARRAY_COUNT(gCoeffReferencesBlendCon
st)); | |
343 // Individual enum asserts already made in blend_coeff_to_vk_blend | |
344 } | |
345 | |
346 void setup_color_blend_state(const GrVkGpu* gpu, | |
347 const GrPipeline& pipeline, | |
348 VkPipelineColorBlendStateCreateInfo* colorBlendInfo
, | |
349 VkPipelineColorBlendAttachmentState* attachmentStat
e) { | |
350 GrXferProcessor::BlendInfo blendInfo; | |
351 pipeline.getXferProcessor().getBlendInfo(&blendInfo); | |
352 | |
353 GrBlendEquation equation = blendInfo.fEquation; | |
354 GrBlendCoeff srcCoeff = blendInfo.fSrcBlend; | |
355 GrBlendCoeff dstCoeff = blendInfo.fDstBlend; | |
356 bool blendOff = (kAdd_GrBlendEquation == equation || kSubtract_GrBlendEquati
on == equation) && | |
357 kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCo
eff; | |
358 | |
359 memset(attachmentState, 0, sizeof(VkPipelineColorBlendAttachmentState)); | |
360 attachmentState->blendEnable = !blendOff; | |
361 if (!blendOff) { | |
362 attachmentState->srcColorBlendFactor = blend_coeff_to_vk_blend(srcCoeff)
; | |
363 attachmentState->dstColorBlendFactor = blend_coeff_to_vk_blend(dstCoeff)
; | |
364 attachmentState->colorBlendOp = blend_equation_to_vk_blend_op(equation); | |
365 attachmentState->srcAlphaBlendFactor = blend_coeff_to_vk_blend(srcCoeff)
; | |
366 attachmentState->dstAlphaBlendFactor = blend_coeff_to_vk_blend(dstCoeff)
; | |
367 attachmentState->alphaBlendOp = blend_equation_to_vk_blend_op(equation); | |
368 } | |
369 attachmentState->colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPON
ENT_G_BIT | | |
370 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPON
ENT_A_BIT; | |
371 | |
372 memset(colorBlendInfo, 0, sizeof(VkPipelineColorBlendStateCreateInfo)); | |
373 colorBlendInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_
INFO; | |
374 colorBlendInfo->pNext = nullptr; | |
375 colorBlendInfo->flags = 0; | |
376 colorBlendInfo->logicOpEnable = VK_FALSE; | |
377 colorBlendInfo->attachmentCount = 1; | |
378 colorBlendInfo->pAttachments = attachmentState; | |
379 if (blend_coeff_refs_constant(srcCoeff) || blend_coeff_refs_constant(dstCoef
f)) { | |
380 GrColorToRGBAFloat(blendInfo.fBlendConstant, colorBlendInfo->blendConsta
nts); | |
381 } | |
382 } | |
383 | |
384 VkCullModeFlags draw_face_to_vk_cull_mode(GrPipelineBuilder::DrawFace drawFace)
{ | |
385 // Assumes that we've set the front face to be ccw | |
386 static const VkCullModeFlags gTable[] = { | |
387 VK_CULL_MODE_NONE, // kBoth_DrawFace | |
388 VK_CULL_MODE_BACK_BIT, // kCCW_DrawFace, cull back face | |
389 VK_CULL_MODE_FRONT_BIT, // kCW_DrawFace, cull front face | |
390 }; | |
391 GR_STATIC_ASSERT(0 == GrPipelineBuilder::kBoth_DrawFace); | |
392 GR_STATIC_ASSERT(1 == GrPipelineBuilder::kCCW_DrawFace); | |
393 GR_STATIC_ASSERT(2 == GrPipelineBuilder::kCW_DrawFace); | |
394 SkASSERT((unsigned)drawFace <= 2); | |
395 | |
396 return gTable[drawFace]; | |
397 } | |
398 | |
399 void setup_raster_state(const GrVkGpu* gpu, | |
400 const GrPipeline& pipeline, | |
401 VkPipelineRasterizationStateCreateInfo* rasterInfo) { | |
402 memset(rasterInfo, 0, sizeof(VkPipelineRasterizationStateCreateInfo)); | |
403 rasterInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_IN
FO; | |
404 rasterInfo->pNext = nullptr; | |
405 rasterInfo->flags = 0; | |
406 rasterInfo->depthClampEnable = VK_FALSE; | |
407 rasterInfo->rasterizerDiscardEnable = VK_FALSE; | |
408 rasterInfo->polygonMode = VK_POLYGON_MODE_FILL; | |
409 rasterInfo->cullMode = draw_face_to_vk_cull_mode(pipeline.getDrawFace()); | |
410 rasterInfo->frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; | |
411 rasterInfo->depthBiasEnable = VK_FALSE; | |
412 rasterInfo->depthBiasConstantFactor = 0.0f; | |
413 rasterInfo->depthBiasClamp = 0.0f; | |
414 rasterInfo->depthBiasSlopeFactor = 0.0f; | |
415 rasterInfo->lineWidth = 1.0f; | |
416 } | |
417 | |
418 void setup_dynamic_state(const GrVkGpu* gpu, | |
419 const GrPipeline& pipeline, | |
420 VkPipelineDynamicStateCreateInfo* dynamicInfo) { | |
421 memset(dynamicInfo, 0, sizeof(VkPipelineDynamicStateCreateInfo)); | |
422 dynamicInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; | |
423 // TODO: mask out any state we might want to set dynamically | |
424 dynamicInfo->dynamicStateCount = 0; | |
425 } | |
426 | |
427 GrVkPipeline* GrVkPipeline::Create(GrVkGpu* gpu, const GrPipeline& pipeline, | |
428 const GrPrimitiveProcessor& primProc, | |
429 VkPipelineShaderStageCreateInfo* shaderStageI
nfo, | |
430 int shaderStageCount, | |
431 GrPrimitiveType primitiveType, | |
432 const GrVkRenderPass& renderPass, | |
433 VkPipelineLayout layout) { | |
434 VkPipelineVertexInputStateCreateInfo vertexInputInfo; | |
435 VkVertexInputBindingDescription bindingDesc; | |
436 // TODO: allocate this based on VkPhysicalDeviceLimits::maxVertexInputAttrib
utes | |
437 static const int kMaxVertexAttributes = 16; | |
438 static VkVertexInputAttributeDescription attributeDesc[kMaxVertexAttributes]
; | |
439 setup_vertex_input_state(primProc, &vertexInputInfo, &bindingDesc, 1, | |
440 attributeDesc, kMaxVertexAttributes); | |
441 | |
442 VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo; | |
443 setup_input_assembly_state(primitiveType, &inputAssemblyInfo); | |
444 | |
445 VkPipelineDepthStencilStateCreateInfo depthStencilInfo; | |
446 setup_depth_stencil_state(gpu, pipeline.getStencil(), &depthStencilInfo); | |
447 | |
448 GrRenderTarget* rt = pipeline.getRenderTarget(); | |
449 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(rt); | |
450 VkPipelineViewportStateCreateInfo viewportInfo; | |
451 VkViewport viewport; | |
452 VkRect2D scissor; | |
453 setup_viewport_scissor_state(gpu, pipeline, vkRT, &viewportInfo, &viewport,
&scissor); | |
454 | |
455 VkPipelineMultisampleStateCreateInfo multisampleInfo; | |
456 setup_multisample_state(pipeline, &multisampleInfo); | |
457 | |
458 // We will only have one color attachment per pipeline. | |
459 VkPipelineColorBlendAttachmentState attachmentStates[1]; | |
460 VkPipelineColorBlendStateCreateInfo colorBlendInfo; | |
461 setup_color_blend_state(gpu, pipeline, &colorBlendInfo, attachmentStates); | |
462 | |
463 VkPipelineRasterizationStateCreateInfo rasterInfo; | |
464 setup_raster_state(gpu, pipeline, &rasterInfo); | |
465 | |
466 VkPipelineDynamicStateCreateInfo dynamicInfo; | |
467 setup_dynamic_state(gpu, pipeline, &dynamicInfo); | |
468 | |
469 VkGraphicsPipelineCreateInfo pipelineCreateInfo; | |
470 memset(&pipelineCreateInfo, 0, sizeof(VkGraphicsPipelineCreateInfo)); | |
471 pipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; | |
472 pipelineCreateInfo.pNext = nullptr; | |
473 pipelineCreateInfo.flags = 0; | |
474 pipelineCreateInfo.stageCount = shaderStageCount; | |
475 pipelineCreateInfo.pStages = shaderStageInfo; | |
476 pipelineCreateInfo.pVertexInputState = &vertexInputInfo; | |
477 pipelineCreateInfo.pInputAssemblyState = &inputAssemblyInfo; | |
478 pipelineCreateInfo.pTessellationState = nullptr; | |
479 pipelineCreateInfo.pViewportState = &viewportInfo; | |
480 pipelineCreateInfo.pRasterizationState = &rasterInfo; | |
481 pipelineCreateInfo.pMultisampleState = &multisampleInfo; | |
482 pipelineCreateInfo.pDepthStencilState = &depthStencilInfo; | |
483 pipelineCreateInfo.pColorBlendState = &colorBlendInfo; | |
484 pipelineCreateInfo.pDynamicState = &dynamicInfo; | |
485 pipelineCreateInfo.layout = layout; | |
486 pipelineCreateInfo.renderPass = renderPass.vkRenderPass(); | |
487 pipelineCreateInfo.subpass = 0; | |
488 pipelineCreateInfo.basePipelineHandle = VK_NULL_HANDLE; | |
489 pipelineCreateInfo.basePipelineIndex = -1; | |
490 | |
491 VkPipeline vkPipeline; | |
492 VkResult err = GR_VK_CALL(gpu->vkInterface(), CreateGraphicsPipelines(gpu->d
evice(), | |
493 nullpt
r, 1, | |
494 &pipel
ineCreateInfo, | |
495 nullpt
r, &vkPipeline)); | |
496 if (err) { | |
497 return nullptr; | |
498 } | |
499 | |
500 return new GrVkPipeline(vkPipeline); | |
501 } | |
502 | |
503 void GrVkPipeline::freeGPUData(const GrVkGpu* gpu) const { | |
504 GR_VK_CALL(gpu->vkInterface(), DestroyPipeline(gpu->device(), fPipeline, nul
lptr)); | |
505 } | |
506 | |
507 | |
OLD | NEW |