1 | // Copyright 2016 The SwiftShader Authors. All Rights Reserved. |
2 | // |
3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | // you may not use this file except in compliance with the License. |
5 | // You may obtain a copy of the License at |
6 | // |
7 | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | // |
9 | // Unless required by applicable law or agreed to in writing, software |
10 | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | // See the License for the specific language governing permissions and |
13 | // limitations under the License. |
14 | |
15 | #include "Context.hpp" |
16 | |
17 | #include "Primitive.hpp" |
18 | #include "System/Memory.hpp" |
19 | #include "Vulkan/VkDebug.hpp" |
20 | #include "Vulkan/VkImageView.hpp" |
21 | #include "Pipeline/SpirvShader.hpp" |
22 | |
23 | #include <string.h> |
24 | |
25 | namespace sw |
26 | { |
27 | Context::Context() |
28 | { |
29 | init(); |
30 | } |
31 | |
32 | bool Context::isDrawPoint(bool polygonModeAware) const |
33 | { |
34 | switch(topology) |
35 | { |
36 | case VK_PRIMITIVE_TOPOLOGY_POINT_LIST: |
37 | return true; |
38 | case VK_PRIMITIVE_TOPOLOGY_LINE_LIST: |
39 | case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP: |
40 | return false; |
41 | case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST: |
42 | case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP: |
43 | case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN: |
44 | return polygonModeAware ? (polygonMode == VK_POLYGON_MODE_POINT) : false; |
45 | default: |
46 | UNIMPLEMENTED("topology %d" , int(topology)); |
47 | } |
48 | return false; |
49 | } |
50 | |
51 | bool Context::isDrawLine(bool polygonModeAware) const |
52 | { |
53 | switch(topology) |
54 | { |
55 | case VK_PRIMITIVE_TOPOLOGY_POINT_LIST: |
56 | return false; |
57 | case VK_PRIMITIVE_TOPOLOGY_LINE_LIST: |
58 | case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP: |
59 | return true; |
60 | case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST: |
61 | case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP: |
62 | case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN: |
63 | return polygonModeAware ? (polygonMode == VK_POLYGON_MODE_LINE) : false; |
64 | default: |
65 | UNIMPLEMENTED("topology %d" , int(topology)); |
66 | } |
67 | return false; |
68 | } |
69 | |
70 | bool Context::isDrawTriangle(bool polygonModeAware) const |
71 | { |
72 | switch(topology) |
73 | { |
74 | case VK_PRIMITIVE_TOPOLOGY_POINT_LIST: |
75 | case VK_PRIMITIVE_TOPOLOGY_LINE_LIST: |
76 | case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP: |
77 | return false; |
78 | case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST: |
79 | case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP: |
80 | case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN: |
81 | return polygonModeAware ? (polygonMode == VK_POLYGON_MODE_FILL) : true; |
82 | default: |
83 | UNIMPLEMENTED("topology %d" , int(topology)); |
84 | } |
85 | return false; |
86 | } |
87 | |
88 | void Context::init() |
89 | { |
90 | for(int i = 0; i < RENDERTARGETS; ++i) |
91 | { |
92 | renderTarget[i] = nullptr; |
93 | } |
94 | |
95 | depthBuffer = nullptr; |
96 | stencilBuffer = nullptr; |
97 | |
98 | stencilEnable = false; |
99 | frontStencil = {}; |
100 | backStencil = {}; |
101 | |
102 | robustBufferAccess = false; |
103 | |
104 | rasterizerDiscard = false; |
105 | |
106 | depthCompareMode = VK_COMPARE_OP_LESS; |
107 | depthBoundsTestEnable = false; |
108 | depthBufferEnable = false; |
109 | depthWriteEnable = false; |
110 | |
111 | cullMode = VK_CULL_MODE_FRONT_BIT; |
112 | frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; |
113 | provokingVertexMode = VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT; |
114 | lineRasterizationMode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT; |
115 | |
116 | depthBias = 0.0f; |
117 | slopeDepthBias = 0.0f; |
118 | |
119 | for(int i = 0; i < RENDERTARGETS; i++) |
120 | { |
121 | colorWriteMask[i] = 0x0000000F; |
122 | } |
123 | |
124 | pipelineLayout = nullptr; |
125 | |
126 | pixelShader = nullptr; |
127 | vertexShader = nullptr; |
128 | |
129 | occlusionEnabled = false; |
130 | |
131 | lineWidth = 1.0f; |
132 | |
133 | sampleMask = 0xFFFFFFFF; |
134 | alphaToCoverage = false; |
135 | } |
136 | |
137 | bool Context::depthWriteActive() const |
138 | { |
139 | if(!depthBufferActive()) return false; |
140 | |
141 | return depthWriteEnable; |
142 | } |
143 | |
144 | bool Context::depthBufferActive() const |
145 | { |
146 | return depthBuffer && depthBufferEnable; |
147 | } |
148 | |
149 | bool Context::stencilActive() const |
150 | { |
151 | return stencilBuffer && stencilEnable; |
152 | } |
153 | |
154 | void Context::setBlendState(int index, BlendState state) |
155 | { |
156 | ASSERT((index >= 0) && (index < RENDERTARGETS)); |
157 | |
158 | blendState[index] = state; |
159 | } |
160 | |
161 | BlendState Context::getBlendState(int index) const |
162 | { |
163 | ASSERT((index >= 0) && (index < RENDERTARGETS)); |
164 | |
165 | BlendState activeBlendState; |
166 | activeBlendState.alphaBlendEnable = alphaBlendActive(index); |
167 | activeBlendState.sourceBlendFactor = sourceBlendFactor(index); |
168 | activeBlendState.destBlendFactor = destBlendFactor(index); |
169 | activeBlendState.blendOperation = blendOperation(index); |
170 | activeBlendState.sourceBlendFactorAlpha = sourceBlendFactorAlpha(index); |
171 | activeBlendState.destBlendFactorAlpha = destBlendFactorAlpha(index); |
172 | activeBlendState.blendOperationAlpha = blendOperationAlpha(index); |
173 | return activeBlendState; |
174 | } |
175 | |
176 | bool Context::alphaBlendActive(int index) const |
177 | { |
178 | ASSERT((index >= 0) && (index < RENDERTARGETS)); |
179 | |
180 | if(!blendState[index].alphaBlendEnable) |
181 | { |
182 | return false; |
183 | } |
184 | |
185 | if(!colorUsed()) |
186 | { |
187 | return false; |
188 | } |
189 | |
190 | bool colorBlend = !(blendOperation(index) == VK_BLEND_OP_SRC_EXT && sourceBlendFactor(index) == VK_BLEND_FACTOR_ONE); |
191 | bool alphaBlend = !(blendOperationAlpha(index) == VK_BLEND_OP_SRC_EXT && sourceBlendFactorAlpha(index) == VK_BLEND_FACTOR_ONE); |
192 | |
193 | return colorBlend || alphaBlend; |
194 | } |
195 | |
196 | VkBlendFactor Context::sourceBlendFactor(int index) const |
197 | { |
198 | ASSERT((index >= 0) && (index < RENDERTARGETS)); |
199 | |
200 | if(!blendState[index].alphaBlendEnable) return VK_BLEND_FACTOR_ONE; |
201 | |
202 | switch(blendState[index].blendOperation) |
203 | { |
204 | case VK_BLEND_OP_ADD: |
205 | case VK_BLEND_OP_SUBTRACT: |
206 | case VK_BLEND_OP_REVERSE_SUBTRACT: |
207 | return blendState[index].sourceBlendFactor; |
208 | case VK_BLEND_OP_MIN: |
209 | return VK_BLEND_FACTOR_ONE; |
210 | case VK_BLEND_OP_MAX: |
211 | return VK_BLEND_FACTOR_ONE; |
212 | default: |
213 | ASSERT(false); |
214 | } |
215 | |
216 | return blendState[index].sourceBlendFactor; |
217 | } |
218 | |
219 | VkBlendFactor Context::destBlendFactor(int index) const |
220 | { |
221 | ASSERT((index >= 0) && (index < RENDERTARGETS)); |
222 | |
223 | if(!blendState[index].alphaBlendEnable) return VK_BLEND_FACTOR_ONE; |
224 | |
225 | switch(blendState[index].blendOperation) |
226 | { |
227 | case VK_BLEND_OP_ADD: |
228 | case VK_BLEND_OP_SUBTRACT: |
229 | case VK_BLEND_OP_REVERSE_SUBTRACT: |
230 | return blendState[index].destBlendFactor; |
231 | case VK_BLEND_OP_MIN: |
232 | return VK_BLEND_FACTOR_ONE; |
233 | case VK_BLEND_OP_MAX: |
234 | return VK_BLEND_FACTOR_ONE; |
235 | default: |
236 | ASSERT(false); |
237 | } |
238 | |
239 | return blendState[index].destBlendFactor; |
240 | } |
241 | |
242 | bool Context::allTargetsColorClamp() const |
243 | { |
244 | // TODO: remove all of this and support VkPhysicalDeviceFeatures::independentBlend instead |
245 | for (int i = 0; i < RENDERTARGETS; i++) |
246 | { |
247 | if (renderTarget[i] && renderTarget[i]->getFormat().isFloatFormat()) |
248 | { |
249 | return false; |
250 | } |
251 | } |
252 | |
253 | return true; |
254 | } |
255 | |
256 | VkBlendOp Context::blendOperation(int index) const |
257 | { |
258 | ASSERT((index >= 0) && (index < RENDERTARGETS)); |
259 | |
260 | if(!blendState[index].alphaBlendEnable) return VK_BLEND_OP_SRC_EXT; |
261 | |
262 | switch(blendState[index].blendOperation) |
263 | { |
264 | case VK_BLEND_OP_ADD: |
265 | if(sourceBlendFactor(index) == VK_BLEND_FACTOR_ZERO) |
266 | { |
267 | if(destBlendFactor(index) == VK_BLEND_FACTOR_ZERO) |
268 | { |
269 | return VK_BLEND_OP_ZERO_EXT; |
270 | } |
271 | else |
272 | { |
273 | return VK_BLEND_OP_DST_EXT; |
274 | } |
275 | } |
276 | else if(sourceBlendFactor(index) == VK_BLEND_FACTOR_ONE) |
277 | { |
278 | if(destBlendFactor(index) == VK_BLEND_FACTOR_ZERO) |
279 | { |
280 | return VK_BLEND_OP_SRC_EXT; |
281 | } |
282 | else |
283 | { |
284 | return VK_BLEND_OP_ADD; |
285 | } |
286 | } |
287 | else |
288 | { |
289 | if(destBlendFactor(index) == VK_BLEND_FACTOR_ZERO) |
290 | { |
291 | return VK_BLEND_OP_SRC_EXT; |
292 | } |
293 | else |
294 | { |
295 | return VK_BLEND_OP_ADD; |
296 | } |
297 | } |
298 | case VK_BLEND_OP_SUBTRACT: |
299 | if(sourceBlendFactor(index) == VK_BLEND_FACTOR_ZERO && allTargetsColorClamp()) |
300 | { |
301 | return VK_BLEND_OP_ZERO_EXT; // Negative, clamped to zero |
302 | } |
303 | else if(sourceBlendFactor(index) == VK_BLEND_FACTOR_ONE) |
304 | { |
305 | if(destBlendFactor(index) == VK_BLEND_FACTOR_ZERO) |
306 | { |
307 | return VK_BLEND_OP_SRC_EXT; |
308 | } |
309 | else |
310 | { |
311 | return VK_BLEND_OP_SUBTRACT; |
312 | } |
313 | } |
314 | else |
315 | { |
316 | if(destBlendFactor(index) == VK_BLEND_FACTOR_ZERO) |
317 | { |
318 | return VK_BLEND_OP_SRC_EXT; |
319 | } |
320 | else |
321 | { |
322 | return VK_BLEND_OP_SUBTRACT; |
323 | } |
324 | } |
325 | case VK_BLEND_OP_REVERSE_SUBTRACT: |
326 | if(sourceBlendFactor(index) == VK_BLEND_FACTOR_ZERO) |
327 | { |
328 | if(destBlendFactor(index) == VK_BLEND_FACTOR_ZERO) |
329 | { |
330 | return VK_BLEND_OP_ZERO_EXT; |
331 | } |
332 | else |
333 | { |
334 | return VK_BLEND_OP_DST_EXT; |
335 | } |
336 | } |
337 | else if(sourceBlendFactor(index) == VK_BLEND_FACTOR_ONE) |
338 | { |
339 | if(destBlendFactor(index) == VK_BLEND_FACTOR_ZERO && allTargetsColorClamp()) |
340 | { |
341 | return VK_BLEND_OP_ZERO_EXT; // Negative, clamped to zero |
342 | } |
343 | else |
344 | { |
345 | return VK_BLEND_OP_REVERSE_SUBTRACT; |
346 | } |
347 | } |
348 | else |
349 | { |
350 | if(destBlendFactor(index) == VK_BLEND_FACTOR_ZERO && allTargetsColorClamp()) |
351 | { |
352 | return VK_BLEND_OP_ZERO_EXT; // Negative, clamped to zero |
353 | } |
354 | else |
355 | { |
356 | return VK_BLEND_OP_REVERSE_SUBTRACT; |
357 | } |
358 | } |
359 | case VK_BLEND_OP_MIN: |
360 | return VK_BLEND_OP_MIN; |
361 | case VK_BLEND_OP_MAX: |
362 | return VK_BLEND_OP_MAX; |
363 | default: |
364 | ASSERT(false); |
365 | } |
366 | |
367 | return blendState[index].blendOperation; |
368 | } |
369 | |
370 | VkBlendFactor Context::sourceBlendFactorAlpha(int index) const |
371 | { |
372 | ASSERT((index >= 0) && (index < RENDERTARGETS)); |
373 | |
374 | switch (blendState[index].blendOperationAlpha) |
375 | { |
376 | case VK_BLEND_OP_ADD: |
377 | case VK_BLEND_OP_SUBTRACT: |
378 | case VK_BLEND_OP_REVERSE_SUBTRACT: |
379 | return blendState[index].sourceBlendFactorAlpha; |
380 | case VK_BLEND_OP_MIN: |
381 | return VK_BLEND_FACTOR_ONE; |
382 | case VK_BLEND_OP_MAX: |
383 | return VK_BLEND_FACTOR_ONE; |
384 | default: |
385 | ASSERT(false); |
386 | } |
387 | |
388 | return blendState[index].sourceBlendFactorAlpha; |
389 | } |
390 | |
391 | VkBlendFactor Context::destBlendFactorAlpha(int index) const |
392 | { |
393 | ASSERT((index >= 0) && (index < RENDERTARGETS)); |
394 | |
395 | switch (blendState[index].blendOperationAlpha) |
396 | { |
397 | case VK_BLEND_OP_ADD: |
398 | case VK_BLEND_OP_SUBTRACT: |
399 | case VK_BLEND_OP_REVERSE_SUBTRACT: |
400 | return blendState[index].destBlendFactorAlpha; |
401 | case VK_BLEND_OP_MIN: |
402 | return VK_BLEND_FACTOR_ONE; |
403 | case VK_BLEND_OP_MAX: |
404 | return VK_BLEND_FACTOR_ONE; |
405 | default: |
406 | ASSERT(false); |
407 | } |
408 | |
409 | return blendState[index].destBlendFactorAlpha; |
410 | } |
411 | |
412 | VkBlendOp Context::blendOperationAlpha(int index) const |
413 | { |
414 | ASSERT((index >= 0) && (index < RENDERTARGETS)); |
415 | |
416 | switch (blendState[index].blendOperationAlpha) |
417 | { |
418 | case VK_BLEND_OP_ADD: |
419 | if (sourceBlendFactorAlpha(index) == VK_BLEND_FACTOR_ZERO) |
420 | { |
421 | if (destBlendFactorAlpha(index) == VK_BLEND_FACTOR_ZERO) |
422 | { |
423 | return VK_BLEND_OP_ZERO_EXT; |
424 | } |
425 | else |
426 | { |
427 | return VK_BLEND_OP_DST_EXT; |
428 | } |
429 | } |
430 | else if (sourceBlendFactorAlpha(index) == VK_BLEND_FACTOR_ONE) |
431 | { |
432 | if (destBlendFactorAlpha(index) == VK_BLEND_FACTOR_ZERO) |
433 | { |
434 | return VK_BLEND_OP_SRC_EXT; |
435 | } |
436 | else |
437 | { |
438 | return VK_BLEND_OP_ADD; |
439 | } |
440 | } |
441 | else |
442 | { |
443 | if (destBlendFactorAlpha(index) == VK_BLEND_FACTOR_ZERO) |
444 | { |
445 | return VK_BLEND_OP_SRC_EXT; |
446 | } |
447 | else |
448 | { |
449 | return VK_BLEND_OP_ADD; |
450 | } |
451 | } |
452 | case VK_BLEND_OP_SUBTRACT: |
453 | if (sourceBlendFactorAlpha(index) == VK_BLEND_FACTOR_ZERO && allTargetsColorClamp()) |
454 | { |
455 | return VK_BLEND_OP_ZERO_EXT; // Negative, clamped to zero |
456 | } |
457 | else if (sourceBlendFactorAlpha(index) == VK_BLEND_FACTOR_ONE) |
458 | { |
459 | if (destBlendFactorAlpha(index) == VK_BLEND_FACTOR_ZERO) |
460 | { |
461 | return VK_BLEND_OP_SRC_EXT; |
462 | } |
463 | else |
464 | { |
465 | return VK_BLEND_OP_SUBTRACT; |
466 | } |
467 | } |
468 | else |
469 | { |
470 | if (destBlendFactorAlpha(index) == VK_BLEND_FACTOR_ZERO) |
471 | { |
472 | return VK_BLEND_OP_SRC_EXT; |
473 | } |
474 | else |
475 | { |
476 | return VK_BLEND_OP_SUBTRACT; |
477 | } |
478 | } |
479 | case VK_BLEND_OP_REVERSE_SUBTRACT: |
480 | if (sourceBlendFactorAlpha(index) == VK_BLEND_FACTOR_ZERO) |
481 | { |
482 | if (destBlendFactorAlpha(index) == VK_BLEND_FACTOR_ZERO) |
483 | { |
484 | return VK_BLEND_OP_ZERO_EXT; |
485 | } |
486 | else |
487 | { |
488 | return VK_BLEND_OP_DST_EXT; |
489 | } |
490 | } |
491 | else if (sourceBlendFactorAlpha(index) == VK_BLEND_FACTOR_ONE) |
492 | { |
493 | if (destBlendFactorAlpha(index) == VK_BLEND_FACTOR_ZERO && allTargetsColorClamp()) |
494 | { |
495 | return VK_BLEND_OP_ZERO_EXT; // Negative, clamped to zero |
496 | } |
497 | else |
498 | { |
499 | return VK_BLEND_OP_REVERSE_SUBTRACT; |
500 | } |
501 | } |
502 | else |
503 | { |
504 | if (destBlendFactorAlpha(index) == VK_BLEND_FACTOR_ZERO && allTargetsColorClamp()) |
505 | { |
506 | return VK_BLEND_OP_ZERO_EXT; // Negative, clamped to zero |
507 | } |
508 | else |
509 | { |
510 | return VK_BLEND_OP_REVERSE_SUBTRACT; |
511 | } |
512 | } |
513 | case VK_BLEND_OP_MIN: |
514 | return VK_BLEND_OP_MIN; |
515 | case VK_BLEND_OP_MAX: |
516 | return VK_BLEND_OP_MAX; |
517 | default: |
518 | ASSERT(false); |
519 | } |
520 | |
521 | return blendState[index].blendOperationAlpha; |
522 | } |
523 | |
524 | VkFormat Context::renderTargetInternalFormat(int index) const |
525 | { |
526 | ASSERT((index >= 0) && (index < RENDERTARGETS)); |
527 | |
528 | if(renderTarget[index]) |
529 | { |
530 | return renderTarget[index]->getFormat(); |
531 | } |
532 | else |
533 | { |
534 | return VK_FORMAT_UNDEFINED; |
535 | } |
536 | } |
537 | |
538 | bool Context::colorWriteActive() const |
539 | { |
540 | for (int i = 0; i < RENDERTARGETS; i++) |
541 | { |
542 | if (colorWriteActive(i)) |
543 | { |
544 | return true; |
545 | } |
546 | } |
547 | |
548 | return false; |
549 | } |
550 | |
551 | int Context::colorWriteActive(int index) const |
552 | { |
553 | ASSERT((index >= 0) && (index < RENDERTARGETS)); |
554 | |
555 | if(!renderTarget[index] || renderTarget[index]->getFormat() == VK_FORMAT_UNDEFINED) |
556 | { |
557 | return 0; |
558 | } |
559 | |
560 | if(blendOperation(index) == VK_BLEND_OP_DST_EXT && destBlendFactor(index) == VK_BLEND_FACTOR_ONE && |
561 | (blendOperationAlpha(index) == VK_BLEND_OP_DST_EXT && destBlendFactorAlpha(index) == VK_BLEND_FACTOR_ONE)) |
562 | { |
563 | return 0; |
564 | } |
565 | |
566 | return colorWriteMask[index]; |
567 | } |
568 | |
569 | bool Context::colorUsed() const |
570 | { |
571 | return colorWriteActive() || (pixelShader && pixelShader->getModes().ContainsKill); |
572 | } |
573 | } |
574 | |