blob: da0e2c4fb7cae1f4765637a507faecf9bf917efc [file] [log] [blame]
Nicolas Capens68a82382018-10-02 13:16:55 -04001// 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"
Ben Claytonfccfc562019-12-17 20:37:31 +000018#include "Pipeline/SpirvShader.hpp"
Ben Clayton25e06e02020-02-07 11:19:08 +000019#include "System/Debug.hpp"
Nicolas Capens1d8c8db2018-11-05 16:30:42 -050020#include "System/Memory.hpp"
Alexis Hetu6159a852019-02-26 14:42:36 -050021#include "Vulkan/VkImageView.hpp"
Nicolas Capens68a82382018-10-02 13:16:55 -040022
23#include <string.h>
24
Nicolas Capens157ba262019-12-10 17:49:14 -050025namespace sw {
26
27Context::Context()
Nicolas Capens68a82382018-10-02 13:16:55 -040028{
Nicolas Capens157ba262019-12-10 17:49:14 -050029 init();
30}
31
32bool Context::isDrawPoint(bool polygonModeAware) const
33{
34 switch(topology)
Nicolas Capens68a82382018-10-02 13:16:55 -040035 {
Ben Claytonfccfc562019-12-17 20:37:31 +000036 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:
Nicolas Capens865f8892020-01-21 14:27:10 -050046 UNSUPPORTED("topology %d", int(topology));
Nicolas Capens157ba262019-12-10 17:49:14 -050047 }
48 return false;
49}
50
51bool Context::isDrawLine(bool polygonModeAware) const
52{
53 switch(topology)
54 {
Ben Claytonfccfc562019-12-17 20:37:31 +000055 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:
Nicolas Capens865f8892020-01-21 14:27:10 -050065 UNSUPPORTED("topology %d", int(topology));
Nicolas Capens157ba262019-12-10 17:49:14 -050066 }
67 return false;
68}
69
70bool Context::isDrawTriangle(bool polygonModeAware) const
71{
72 switch(topology)
73 {
Ben Claytonfccfc562019-12-17 20:37:31 +000074 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:
Nicolas Capens865f8892020-01-21 14:27:10 -050083 UNSUPPORTED("topology %d", int(topology));
Nicolas Capens157ba262019-12-10 17:49:14 -050084 }
85 return false;
86}
87
88void Context::init()
89{
90 for(int i = 0; i < RENDERTARGETS; ++i)
91 {
92 renderTarget[i] = nullptr;
Chris Forbes4d659342019-05-10 13:40:00 -070093 }
94
Nicolas Capens157ba262019-12-10 17:49:14 -050095 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++)
Nicolas Capens68a82382018-10-02 13:16:55 -0400120 {
Nicolas Capens157ba262019-12-10 17:49:14 -0500121 colorWriteMask[i] = 0x0000000F;
122 }
Nicolas Capens68a82382018-10-02 13:16:55 -0400123
Nicolas Capens157ba262019-12-10 17:49:14 -0500124 pipelineLayout = nullptr;
Alexis Hetu51d51082019-07-15 17:20:40 -0400125
Nicolas Capens157ba262019-12-10 17:49:14 -0500126 pixelShader = nullptr;
127 vertexShader = nullptr;
128
129 occlusionEnabled = false;
130
131 lineWidth = 1.0f;
132
133 sampleMask = 0xFFFFFFFF;
134 alphaToCoverage = false;
135}
136
137bool Context::depthWriteActive() const
138{
139 if(!depthBufferActive()) return false;
140
141 return depthWriteEnable;
142}
143
144bool Context::depthBufferActive() const
145{
146 return depthBuffer && depthBufferEnable;
147}
148
149bool Context::stencilActive() const
150{
151 return stencilBuffer && stencilEnable;
152}
153
154void Context::setBlendState(int index, BlendState state)
155{
156 ASSERT((index >= 0) && (index < RENDERTARGETS));
157
158 blendState[index] = state;
159}
160
161BlendState 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
176bool 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
196VkBlendFactor 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 {
Ben Claytonfccfc562019-12-17 20:37:31 +0000204 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);
Nicolas Capens157ba262019-12-10 17:49:14 -0500214 }
215
216 return blendState[index].sourceBlendFactor;
217}
218
219VkBlendFactor 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 {
Ben Claytonfccfc562019-12-17 20:37:31 +0000227 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);
Nicolas Capens157ba262019-12-10 17:49:14 -0500237 }
238
239 return blendState[index].destBlendFactor;
240}
241
242bool Context::allTargetsColorClamp() const
243{
244 // TODO: remove all of this and support VkPhysicalDeviceFeatures::independentBlend instead
Nicolas Capens81bc9d92019-12-16 15:05:57 -0500245 for(int i = 0; i < RENDERTARGETS; i++)
Nicolas Capens157ba262019-12-10 17:49:14 -0500246 {
Nicolas Capens81bc9d92019-12-16 15:05:57 -0500247 if(renderTarget[i] && renderTarget[i]->getFormat().isFloatFormat())
Nicolas Capens68a82382018-10-02 13:16:55 -0400248 {
Nicolas Capens157ba262019-12-10 17:49:14 -0500249 return false;
Nicolas Capens68a82382018-10-02 13:16:55 -0400250 }
Nicolas Capens68a82382018-10-02 13:16:55 -0400251 }
252
Nicolas Capens157ba262019-12-10 17:49:14 -0500253 return true;
254}
255
256VkBlendOp 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)
Nicolas Capens68a82382018-10-02 13:16:55 -0400263 {
Ben Claytonfccfc562019-12-17 20:37:31 +0000264 case VK_BLEND_OP_ADD:
265 if(sourceBlendFactor(index) == VK_BLEND_FACTOR_ZERO)
Nicolas Capens68a82382018-10-02 13:16:55 -0400266 {
Ben Claytonfccfc562019-12-17 20:37:31 +0000267 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 }
Chris Forbes3e351312019-05-14 17:33:01 -0700286 }
287 else
288 {
Ben Claytonfccfc562019-12-17 20:37:31 +0000289 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 }
Chris Forbes3e351312019-05-14 17:33:01 -0700297 }
Ben Claytonfccfc562019-12-17 20:37:31 +0000298 case VK_BLEND_OP_SUBTRACT:
299 if(sourceBlendFactor(index) == VK_BLEND_FACTOR_ZERO && allTargetsColorClamp())
Nicolas Capens157ba262019-12-10 17:49:14 -0500300 {
Ben Claytonfccfc562019-12-17 20:37:31 +0000301 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 }
Nicolas Capens157ba262019-12-10 17:49:14 -0500313 }
314 else
315 {
Ben Claytonfccfc562019-12-17 20:37:31 +0000316 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 }
Nicolas Capens157ba262019-12-10 17:49:14 -0500324 }
Ben Claytonfccfc562019-12-17 20:37:31 +0000325 case VK_BLEND_OP_REVERSE_SUBTRACT:
326 if(sourceBlendFactor(index) == VK_BLEND_FACTOR_ZERO)
Chris Forbesbc63cf92019-02-28 09:03:38 -0800327 {
Ben Claytonfccfc562019-12-17 20:37:31 +0000328 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 }
Nicolas Capens157ba262019-12-10 17:49:14 -0500347 }
348 else
349 {
Ben Claytonfccfc562019-12-17 20:37:31 +0000350 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 }
Chris Forbesbc63cf92019-02-28 09:03:38 -0800358 }
Ben Claytonfccfc562019-12-17 20:37:31 +0000359 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);
Nicolas Capens68a82382018-10-02 13:16:55 -0400365 }
366
Nicolas Capens157ba262019-12-10 17:49:14 -0500367 return blendState[index].blendOperation;
368}
369
370VkBlendFactor Context::sourceBlendFactorAlpha(int index) const
371{
372 ASSERT((index >= 0) && (index < RENDERTARGETS));
373
Nicolas Capens81bc9d92019-12-16 15:05:57 -0500374 switch(blendState[index].blendOperationAlpha)
Nicolas Capens68a82382018-10-02 13:16:55 -0400375 {
Ben Claytonfccfc562019-12-17 20:37:31 +0000376 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);
Nicolas Capens68a82382018-10-02 13:16:55 -0400386 }
387
Nicolas Capens157ba262019-12-10 17:49:14 -0500388 return blendState[index].sourceBlendFactorAlpha;
389}
390
391VkBlendFactor Context::destBlendFactorAlpha(int index) const
392{
393 ASSERT((index >= 0) && (index < RENDERTARGETS));
394
Nicolas Capens81bc9d92019-12-16 15:05:57 -0500395 switch(blendState[index].blendOperationAlpha)
Nicolas Capens68a82382018-10-02 13:16:55 -0400396 {
Ben Claytonfccfc562019-12-17 20:37:31 +0000397 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);
Nicolas Capens157ba262019-12-10 17:49:14 -0500407 }
408
409 return blendState[index].destBlendFactorAlpha;
410}
411
412VkBlendOp Context::blendOperationAlpha(int index) const
413{
414 ASSERT((index >= 0) && (index < RENDERTARGETS));
415
Nicolas Capens81bc9d92019-12-16 15:05:57 -0500416 switch(blendState[index].blendOperationAlpha)
Nicolas Capens157ba262019-12-10 17:49:14 -0500417 {
Ben Claytonfccfc562019-12-17 20:37:31 +0000418 case VK_BLEND_OP_ADD:
419 if(sourceBlendFactorAlpha(index) == VK_BLEND_FACTOR_ZERO)
Nicolas Capens157ba262019-12-10 17:49:14 -0500420 {
Ben Claytonfccfc562019-12-17 20:37:31 +0000421 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 }
Nicolas Capens157ba262019-12-10 17:49:14 -0500440 }
441 else
442 {
Ben Claytonfccfc562019-12-17 20:37:31 +0000443 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 }
Nicolas Capens157ba262019-12-10 17:49:14 -0500451 }
Ben Claytonfccfc562019-12-17 20:37:31 +0000452 case VK_BLEND_OP_SUBTRACT:
453 if(sourceBlendFactorAlpha(index) == VK_BLEND_FACTOR_ZERO && allTargetsColorClamp())
Nicolas Capens157ba262019-12-10 17:49:14 -0500454 {
Ben Claytonfccfc562019-12-17 20:37:31 +0000455 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 }
Nicolas Capens157ba262019-12-10 17:49:14 -0500467 }
468 else
469 {
Ben Claytonfccfc562019-12-17 20:37:31 +0000470 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 }
Nicolas Capens157ba262019-12-10 17:49:14 -0500478 }
Ben Claytonfccfc562019-12-17 20:37:31 +0000479 case VK_BLEND_OP_REVERSE_SUBTRACT:
480 if(sourceBlendFactorAlpha(index) == VK_BLEND_FACTOR_ZERO)
Nicolas Capens157ba262019-12-10 17:49:14 -0500481 {
Ben Claytonfccfc562019-12-17 20:37:31 +0000482 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 }
Nicolas Capens157ba262019-12-10 17:49:14 -0500501 }
502 else
503 {
Ben Claytonfccfc562019-12-17 20:37:31 +0000504 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 }
Nicolas Capens157ba262019-12-10 17:49:14 -0500512 }
Ben Claytonfccfc562019-12-17 20:37:31 +0000513 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);
Nicolas Capens157ba262019-12-10 17:49:14 -0500519 }
520
521 return blendState[index].blendOperationAlpha;
522}
523
524VkFormat 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;
Nicolas Capens68a82382018-10-02 13:16:55 -0400535 }
536}
Nicolas Capens157ba262019-12-10 17:49:14 -0500537
538bool Context::colorWriteActive() const
539{
Nicolas Capens81bc9d92019-12-16 15:05:57 -0500540 for(int i = 0; i < RENDERTARGETS; i++)
Nicolas Capens157ba262019-12-10 17:49:14 -0500541 {
Nicolas Capens81bc9d92019-12-16 15:05:57 -0500542 if(colorWriteActive(i))
Nicolas Capens157ba262019-12-10 17:49:14 -0500543 {
544 return true;
545 }
546 }
547
548 return false;
549}
550
551int 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
569bool Context::colorUsed() const
570{
571 return colorWriteActive() || (pixelShader && pixelShader->getModes().ContainsKill);
572}
573
574} // namespace sw