Bug Summary

File:/home/anal/dolphin-emu/Source/Core/VideoBackends/Software/Src/EfbInterface.cpp
Location:line 368, column 12
Description:Assigned value is garbage or undefined

Annotated Source Code

1// Copyright 2013 Dolphin Emulator Project
2// Licensed under GPLv2
3// Refer to the license.txt file included.
4
5#include "Common.h"
6
7#include "EfbInterface.h"
8#include "BPMemLoader.h"
9#include "LookUpTables.h"
10#include "SWPixelEngine.h"
11
12
13u8 efb[EFB_WIDTH*EFB_HEIGHT*6];
14
15
16namespace EfbInterface
17{
18
19 u8 efbColorTexture[EFB_WIDTH*EFB_HEIGHT*4];
20
21 inline u32 GetColorOffset(u16 x, u16 y)
22 {
23 return (x + y * EFB_WIDTH) * 3;
24 }
25
26 inline u32 GetDepthOffset(u16 x, u16 y)
27 {
28 return (x + y * EFB_WIDTH) * 3 + DEPTH_BUFFER_START;
29 }
30
31 void DoState(PointerWrap &p)
32 {
33 p.DoArray(efb, EFB_WIDTH*EFB_HEIGHT*6);
34 p.DoArray(efbColorTexture, EFB_WIDTH*EFB_HEIGHT*4);
35 }
36
37 void SetPixelAlphaOnly(u32 offset, u8 a)
38 {
39 switch (bpmem.zcontrol.pixel_format)
40 {
41 case PIXELFMT_RGB8_Z240:
42 case PIXELFMT_Z243:
43 case PIXELFMT_RGB565_Z162:
44 // do nothing
45 break;
46 case PIXELFMT_RGBA6_Z241:
47 {
48 u32 a32 = a;
49 u32 *dst = (u32*)&efb[offset];
50 u32 val = *dst & 0xffffffc0;
51 val |= (a32 >> 2) & 0x0000003f;
52 *dst = val;
53 }
54 break;
55 default:
56 ERROR_LOG(VIDEO, "Unsupported pixel format: %i", bpmem.zcontrol.pixel_format)do { { if (LogTypes::LERROR <= 3) GenericLog(LogTypes::LERROR
, LogTypes::VIDEO, "/home/anal/dolphin-emu/Source/Core/VideoBackends/Software/Src/EfbInterface.cpp"
, 56, "Unsupported pixel format: %i", bpmem.zcontrol.pixel_format
); } } while (0)
;
57 }
58 }
59
60 void SetPixelColorOnly(u32 offset, u8 *rgb)
61 {
62 switch (bpmem.zcontrol.pixel_format)
63 {
64 case PIXELFMT_RGB8_Z240:
65 case PIXELFMT_Z243:
66 {
67 u32 src = *(u32*)rgb;
68 u32 *dst = (u32*)&efb[offset];
69 u32 val = *dst & 0xff000000;
70 val |= src >> 8;
71 *dst = val;
72 }
73 break;
74 case PIXELFMT_RGBA6_Z241:
75 {
76 u32 src = *(u32*)rgb;
77 u32 *dst = (u32*)&efb[offset];
78 u32 val = *dst & 0xff00003f;
79 val |= (src >> 4) & 0x00000fc0; // blue
80 val |= (src >> 6) & 0x0003f000; // green
81 val |= (src >> 8) & 0x00fc0000; // red
82 *dst = val;
83 }
84 break;
85 case PIXELFMT_RGB565_Z162:
86 {
87 INFO_LOG(VIDEO, "PIXELFMT_RGB565_Z16 is not supported correctly yet")do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::VIDEO, "/home/anal/dolphin-emu/Source/Core/VideoBackends/Software/Src/EfbInterface.cpp"
, 87, "PIXELFMT_RGB565_Z16 is not supported correctly yet"); }
} while (0)
;
88 u32 src = *(u32*)rgb;
89 u32 *dst = (u32*)&efb[offset];
90 u32 val = *dst & 0xff000000;
91 val |= src >> 8;
92 *dst = val;
93 }
94 break;
95 default:
96 ERROR_LOG(VIDEO, "Unsupported pixel format: %i", bpmem.zcontrol.pixel_format)do { { if (LogTypes::LERROR <= 3) GenericLog(LogTypes::LERROR
, LogTypes::VIDEO, "/home/anal/dolphin-emu/Source/Core/VideoBackends/Software/Src/EfbInterface.cpp"
, 96, "Unsupported pixel format: %i", bpmem.zcontrol.pixel_format
); } } while (0)
;
97 }
98 }
99
100 void SetPixelAlphaColor(u32 offset, u8 *color)
101 {
102 switch (bpmem.zcontrol.pixel_format)
103 {
104 case PIXELFMT_RGB8_Z240:
105 case PIXELFMT_Z243:
106 {
107 u32 src = *(u32*)color;
108 u32 *dst = (u32*)&efb[offset];
109 u32 val = *dst & 0xff000000;
110 val |= src >> 8;
111 *dst = val;
112 }
113 break;
114 case PIXELFMT_RGBA6_Z241:
115 {
116 u32 src = *(u32*)color;
117 u32 *dst = (u32*)&efb[offset];
118 u32 val = *dst & 0xff000000;
119 val |= (src >> 2) & 0x0000003f; // alpha
120 val |= (src >> 4) & 0x00000fc0; // blue
121 val |= (src >> 6) & 0x0003f000; // green
122 val |= (src >> 8) & 0x00fc0000; // red
123 *dst = val;
124 }
125 break;
126 case PIXELFMT_RGB565_Z162:
127 {
128 INFO_LOG(VIDEO, "PIXELFMT_RGB565_Z16 is not supported correctly yet")do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::VIDEO, "/home/anal/dolphin-emu/Source/Core/VideoBackends/Software/Src/EfbInterface.cpp"
, 128, "PIXELFMT_RGB565_Z16 is not supported correctly yet");
} } while (0)
;
129 u32 src = *(u32*)color;
130 u32 *dst = (u32*)&efb[offset];
131 u32 val = *dst & 0xff000000;
132 val |= src >> 8;
133 *dst = val;
134 }
135 break;
136 default:
137 ERROR_LOG(VIDEO, "Unsupported pixel format: %i", bpmem.zcontrol.pixel_format)do { { if (LogTypes::LERROR <= 3) GenericLog(LogTypes::LERROR
, LogTypes::VIDEO, "/home/anal/dolphin-emu/Source/Core/VideoBackends/Software/Src/EfbInterface.cpp"
, 137, "Unsupported pixel format: %i", bpmem.zcontrol.pixel_format
); } } while (0)
;
138 }
139 }
140
141 void GetPixelColor(u32 offset, u8 *color)
142 {
143 switch (bpmem.zcontrol.pixel_format)
144 {
145 case PIXELFMT_RGB8_Z240:
146 case PIXELFMT_Z243:
147 {
148 u32 src = *(u32*)&efb[offset];
149 u32 *dst = (u32*)color;
150 u32 val = 0xff | ((src & 0x00ffffff) << 8);
151 *dst = val;
152 }
153 break;
154 case PIXELFMT_RGBA6_Z241:
155 {
156 u32 src = *(u32*)&efb[offset];
157 color[ALP_C] = Convert6To8(src & 0x3f);
158 color[BLU_C] = Convert6To8((src >> 6) & 0x3f);
159 color[GRN_C] = Convert6To8((src >> 12) & 0x3f);
160 color[RED_C] = Convert6To8((src >> 18) & 0x3f);
161 }
162 break;
163 case PIXELFMT_RGB565_Z162:
164 {
165 INFO_LOG(VIDEO, "PIXELFMT_RGB565_Z16 is not supported correctly yet")do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::VIDEO, "/home/anal/dolphin-emu/Source/Core/VideoBackends/Software/Src/EfbInterface.cpp"
, 165, "PIXELFMT_RGB565_Z16 is not supported correctly yet");
} } while (0)
;
166 u32 src = *(u32*)&efb[offset];
167 u32 *dst = (u32*)color;
168 u32 val = 0xff | ((src & 0x00ffffff) << 8);
169 *dst = val;
170 }
171 break;
172 default:
173 ERROR_LOG(VIDEO, "Unsupported pixel format: %i", bpmem.zcontrol.pixel_format)do { { if (LogTypes::LERROR <= 3) GenericLog(LogTypes::LERROR
, LogTypes::VIDEO, "/home/anal/dolphin-emu/Source/Core/VideoBackends/Software/Src/EfbInterface.cpp"
, 173, "Unsupported pixel format: %i", bpmem.zcontrol.pixel_format
); } } while (0)
;
174 }
175 }
176
177 void SetPixelDepth(u32 offset, u32 depth)
178 {
179 switch (bpmem.zcontrol.pixel_format)
180 {
181 case PIXELFMT_RGB8_Z240:
182 case PIXELFMT_RGBA6_Z241:
183 case PIXELFMT_Z243:
184 {
185 u32 *dst = (u32*)&efb[offset];
186 u32 val = *dst & 0xff000000;
187 val |= depth & 0x00ffffff;
188 *dst = val;
189 }
190 break;
191 case PIXELFMT_RGB565_Z162:
192 {
193 INFO_LOG(VIDEO, "PIXELFMT_RGB565_Z16 is not supported correctly yet")do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::VIDEO, "/home/anal/dolphin-emu/Source/Core/VideoBackends/Software/Src/EfbInterface.cpp"
, 193, "PIXELFMT_RGB565_Z16 is not supported correctly yet");
} } while (0)
;
194 u32 *dst = (u32*)&efb[offset];
195 u32 val = *dst & 0xff000000;
196 val |= depth & 0x00ffffff;
197 *dst = val;
198 }
199 break;
200 default:
201 ERROR_LOG(VIDEO, "Unsupported pixel format: %i", bpmem.zcontrol.pixel_format)do { { if (LogTypes::LERROR <= 3) GenericLog(LogTypes::LERROR
, LogTypes::VIDEO, "/home/anal/dolphin-emu/Source/Core/VideoBackends/Software/Src/EfbInterface.cpp"
, 201, "Unsupported pixel format: %i", bpmem.zcontrol.pixel_format
); } } while (0)
;
202 }
203 }
204
205 u32 GetPixelDepth(u32 offset)
206 {
207 u32 depth = 0;
208
209 switch (bpmem.zcontrol.pixel_format)
210 {
211 case PIXELFMT_RGB8_Z240:
212 case PIXELFMT_RGBA6_Z241:
213 case PIXELFMT_Z243:
214 {
215 depth = (*(u32*)&efb[offset]) & 0x00ffffff;
216 }
217 break;
218 case PIXELFMT_RGB565_Z162:
219 {
220 INFO_LOG(VIDEO, "PIXELFMT_RGB565_Z16 is not supported correctly yet")do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO
, LogTypes::VIDEO, "/home/anal/dolphin-emu/Source/Core/VideoBackends/Software/Src/EfbInterface.cpp"
, 220, "PIXELFMT_RGB565_Z16 is not supported correctly yet");
} } while (0)
;
221 depth = (*(u32*)&efb[offset]) & 0x00ffffff;
222 }
223 break;
224 default:
225 ERROR_LOG(VIDEO, "Unsupported pixel format: %i", bpmem.zcontrol.pixel_format)do { { if (LogTypes::LERROR <= 3) GenericLog(LogTypes::LERROR
, LogTypes::VIDEO, "/home/anal/dolphin-emu/Source/Core/VideoBackends/Software/Src/EfbInterface.cpp"
, 225, "Unsupported pixel format: %i", bpmem.zcontrol.pixel_format
); } } while (0)
;
226 }
227
228 return depth;
229 }
230
231 u32 GetSourceFactor(u8 *srcClr, u8 *dstClr, int mode)
232 {
233 switch (mode) {
234 case 0: // zero
235 return 0;
236 case 1: // one
237 return 0xffffffff;
238 case 2: // dstclr
239 return *(u32*)dstClr;
240 case 3: // invdstclr
241 return 0xffffffff - *(u32*)dstClr;
242 case 4: // srcalpha
243 {
244 u8 alpha = srcClr[ALP_C];
245 u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
246 return factor;
247 }
248 case 5: // invsrcalpha
249 {
250 u8 alpha = 0xff - srcClr[ALP_C];
251 u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
252 return factor;
253 }
254 case 6: // dstalpha
255 {
256 u8 alpha = dstClr[ALP_C];
257 u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
258 return factor;
259 }
260 case 7: // invdstalpha
261 {
262 u8 alpha = 0xff - dstClr[ALP_C];
263 u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
264 return factor;
265 }
266 }
267
268 return 0;
269 }
270
271 u32 GetDestinationFactor(u8 *srcClr, u8 *dstClr, int mode)
272 {
273 switch (mode) {
274 case 0: // zero
275 return 0;
276 case 1: // one
277 return 0xffffffff;
278 case 2: // srcclr
279 return *(u32*)srcClr;
280 case 3: // invsrcclr
281 return 0xffffffff - *(u32*)srcClr;
282 case 4: // srcalpha
283 {
284 u8 alpha = srcClr[ALP_C];
285 u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
286 return factor;
287 }
288 case 5: // invsrcalpha
289 {
290 u8 alpha = 0xff - srcClr[ALP_C];
291 u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
292 return factor;
293 }
294 case 6: // dstalpha
295 {
296 u8 alpha = dstClr[ALP_C] & 0xff;
297 u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
298 return factor;
299 }
300 case 7: // invdstalpha
301 {
302 u8 alpha = 0xff - dstClr[ALP_C];
303 u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
304 return factor;
305 }
306 }
307
308 return 0;
309 }
310
311 void BlendColor(u8 *srcClr, u8 *dstClr)
312 {
313 u32 srcFactor = GetSourceFactor(srcClr, dstClr, bpmem.blendmode.srcfactor);
314 u32 dstFactor = GetDestinationFactor(srcClr, dstClr, bpmem.blendmode.dstfactor);
315
316 for (int i = 0; i < 4; i++)
317 {
318 // add MSB of factors to make their range 0 -> 256
319 u32 sf = (srcFactor & 0xff);
320 sf += sf >> 7;
321
322 u32 df = (dstFactor & 0xff);
323 df += df >> 7;
324
325 u32 color = (srcClr[i] * sf + dstClr[i] * df) >> 8;
326 dstClr[i] = (color>255)?255:color;
327
328 dstFactor >>= 8;
329 srcFactor >>= 8;
330 }
331 }
332
333 void LogicBlend(u32 srcClr, u32 &dstClr, int op)
334 {
335 switch (op)
4
Control jumps to 'case 10:' at line 367
336 {
337 case 0: // clear
338 dstClr = 0;
339 break;
340 case 1: // and
341 dstClr = srcClr & dstClr;
342 break;
343 case 2: // revand
344 dstClr = srcClr & (~dstClr);
345 break;
346 case 3: // copy
347 dstClr = srcClr;
348 break;
349 case 4: // invand
350 dstClr = (~srcClr) & dstClr;
351 break;
352 case 5: // noop
353 // Do nothing
354 break;
355 case 6: // xor
356 dstClr = srcClr ^ dstClr;
357 break;
358 case 7: // or
359 dstClr = srcClr | dstClr;
360 break;
361 case 8: // nor
362 dstClr = ~(srcClr | dstClr);
363 break;
364 case 9: // equiv
365 dstClr = ~(srcClr ^ dstClr);
366 break;
367 case 10: // inv
368 dstClr = ~dstClr;
5
Assigned value is garbage or undefined
369 break;
370 case 11: // revor
371 dstClr = srcClr | (~dstClr);
372 break;
373 case 12: // invcopy
374 dstClr = ~srcClr;
375 break;
376 case 13: // invor
377 dstClr = (~srcClr) | dstClr;
378 break;
379 case 14: // nand
380 dstClr = ~(srcClr & dstClr);
381 break;
382 case 15: // set
383 dstClr = 0xffffffff;
384 break;
385 }
386 }
387
388 void SubtractBlend(u8 *srcClr, u8 *dstClr)
389 {
390 for (int i = 0; i < 4; i++)
391 {
392 int c = (int)dstClr[i] - (int)srcClr[i];
393 dstClr[i] = (c < 0)?0:c;
394 }
395 }
396
397 void BlendTev(u16 x, u16 y, u8 *color)
398 {
399 u32 dstClr;
400 u32 offset = GetColorOffset(x, y);
401
402 u8 *dstClrPtr = (u8*)&dstClr;
403
404 GetPixelColor(offset, dstClrPtr);
405
406 if (bpmem.blendmode.blendenable)
1
Taking false branch
407 {
408 if (bpmem.blendmode.subtract)
409 SubtractBlend(color, dstClrPtr);
410 else
411 BlendColor(color, dstClrPtr);
412 }
413 else if (bpmem.blendmode.logicopenable)
2
Taking true branch
414 {
415 LogicBlend(*((u32*)color), dstClr, bpmem.blendmode.logicmode);
3
Calling 'LogicBlend'
416 }
417 else
418 {
419 dstClrPtr = color;
420 }
421
422 if (bpmem.dstalpha.enable)
423 dstClrPtr[ALP_C] = bpmem.dstalpha.alpha;
424
425 if (bpmem.blendmode.colorupdate)
426 {
427 if (bpmem.blendmode.alphaupdate)
428 SetPixelAlphaColor(offset, dstClrPtr);
429 else
430 SetPixelColorOnly(offset, dstClrPtr);
431 }
432 else if (bpmem.blendmode.alphaupdate)
433 {
434 SetPixelAlphaOnly(offset, dstClrPtr[ALP_C]);
435 }
436
437 // branchless bounding box update
438 SWPixelEngine::pereg.boxLeft = SWPixelEngine::pereg.boxLeft>x?x:SWPixelEngine::pereg.boxLeft;
439 SWPixelEngine::pereg.boxRight = SWPixelEngine::pereg.boxRight<x?x:SWPixelEngine::pereg.boxRight;
440 SWPixelEngine::pereg.boxTop = SWPixelEngine::pereg.boxTop>y?y:SWPixelEngine::pereg.boxTop;
441 SWPixelEngine::pereg.boxBottom = SWPixelEngine::pereg.boxBottom<y?y:SWPixelEngine::pereg.boxBottom;
442 }
443
444 void SetColor(u16 x, u16 y, u8 *color)
445 {
446 u32 offset = GetColorOffset(x, y);
447 if (bpmem.blendmode.colorupdate)
448 {
449 if (bpmem.blendmode.alphaupdate)
450 SetPixelAlphaColor(offset, color);
451 else
452 SetPixelColorOnly(offset, color);
453 }
454 else if (bpmem.blendmode.alphaupdate)
455 {
456 SetPixelAlphaOnly(offset, color[ALP_C]);
457 }
458 }
459
460 void SetDepth(u16 x, u16 y, u32 depth)
461 {
462 if (bpmem.zmode.updateenable)
463 SetPixelDepth(GetDepthOffset(x, y), depth);
464 }
465
466 void GetColor(u16 x, u16 y, u8 *color)
467 {
468 u32 offset = GetColorOffset(x, y);
469 GetPixelColor(offset, color);
470 }
471
472 u32 GetDepth(u16 x, u16 y)
473 {
474 u32 offset = GetDepthOffset(x, y);
475 return GetPixelDepth(offset);
476 }
477
478 u8 *GetPixelPointer(u16 x, u16 y, bool depth)
479 {
480 if (depth)
481 return &efb[GetDepthOffset(x, y)];
482 return &efb[GetColorOffset(x, y)];
483 }
484
485 void UpdateColorTexture()
486 {
487 u32 color;
488 u8* colorPtr = (u8*)&color;
489 u32* texturePtr = (u32*)efbColorTexture;
490 u32 textureAddress = 0;
491 u32 efbOffset = 0;
492
493 for (u16 y = 0; y < EFB_HEIGHT; y++)
494 {
495 for (u16 x = 0; x < EFB_WIDTH; x++)
496 {
497 GetPixelColor(efbOffset, colorPtr);
498 efbOffset += 3;
499 texturePtr[textureAddress++] = Common::swap32(color); // ABGR->RGBA
500 }
501 }
502 }
503
504 bool ZCompare(u16 x, u16 y, u32 z)
505 {
506 u32 offset = GetDepthOffset(x, y);
507 u32 depth = GetPixelDepth(offset);
508
509 bool pass;
510
511 switch (bpmem.zmode.func)
512 {
513 case COMPARE_NEVER:
514 pass = false;
515 break;
516 case COMPARE_LESS:
517 pass = z < depth;
518 break;
519 case COMPARE_EQUAL:
520 pass = z == depth;
521 break;
522 case COMPARE_LEQUAL:
523 pass = z <= depth;
524 break;
525 case COMPARE_GREATER:
526 pass = z > depth;
527 break;
528 case COMPARE_NEQUAL:
529 pass = z != depth;
530 break;
531 case COMPARE_GEQUAL:
532 pass = z >= depth;
533 break;
534 case COMPARE_ALWAYS:
535 pass = true;
536 break;
537 default:
538 pass = false;
539 ERROR_LOG(VIDEO, "Bad Z compare mode %i", bpmem.zmode.func)do { { if (LogTypes::LERROR <= 3) GenericLog(LogTypes::LERROR
, LogTypes::VIDEO, "/home/anal/dolphin-emu/Source/Core/VideoBackends/Software/Src/EfbInterface.cpp"
, 539, "Bad Z compare mode %i", bpmem.zmode.func); } } while (
0)
;
540 }
541
542 if (pass && bpmem.zmode.updateenable)
543 {
544 SetPixelDepth(offset, z);
545 }
546
547 return pass;
548 }
549}