diff options
| author | 2015-02-05 16:07:37 +0100 | |
|---|---|---|
| committer | 2015-02-05 16:07:37 +0100 | |
| commit | 1576a318f2c059305364f0e5de81aab80094a610 (patch) | |
| tree | e85a096e8e637af7a9151dfd3176c4167463100f /src | |
| parent | Merge pull request #537 from lioncash/vfp (diff) | |
| parent | Rasterizer: Implement the other color and alpha modifiers. (diff) | |
| download | yuzu-1576a318f2c059305364f0e5de81aab80094a610.tar.gz yuzu-1576a318f2c059305364f0e5de81aab80094a610.tar.xz yuzu-1576a318f2c059305364f0e5de81aab80094a610.zip | |
Merge pull request #535 from bunnei/color-modifiers
Implement color/alpha modifiers
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/math.h | 51 | ||||
| -rw-r--r-- | src/video_core/pica.h | 30 | ||||
| -rw-r--r-- | src/video_core/rasterizer.cpp | 97 |
3 files changed, 104 insertions, 74 deletions
diff --git a/src/video_core/math.h b/src/video_core/math.h index 9622e7614..c176b225a 100644 --- a/src/video_core/math.h +++ b/src/video_core/math.h | |||
| @@ -457,27 +457,41 @@ public: | |||
| 457 | const T& b() const { return z; } | 457 | const T& b() const { return z; } |
| 458 | const T& a() const { return w; } | 458 | const T& a() const { return w; } |
| 459 | 459 | ||
| 460 | // swizzlers - create a subvector of specific components | 460 | // Swizzlers - Create a subvector of specific components |
| 461 | // e.g. Vec2 uv() { return Vec2(x,y); } | 461 | // e.g. Vec2 uv() { return Vec2(x,y); } |
| 462 | // _DEFINE_SWIZZLER2 defines a single such function, DEFINE_SWIZZLER2 defines all of them for all component names (x<->r) and permutations (xy<->yx) | 462 | |
| 463 | // _DEFINE_SWIZZLER2 defines a single such function | ||
| 464 | // DEFINE_SWIZZLER2_COMP1 defines one-component functions for all component names (x<->r) | ||
| 465 | // DEFINE_SWIZZLER2_COMP2 defines two component functions for all component names (x<->r) and permutations (xy<->yx) | ||
| 463 | #define _DEFINE_SWIZZLER2(a, b, name) const Vec2<T> name() const { return Vec2<T>(a, b); } | 466 | #define _DEFINE_SWIZZLER2(a, b, name) const Vec2<T> name() const { return Vec2<T>(a, b); } |
| 464 | #define DEFINE_SWIZZLER2(a, b, a2, b2) \ | 467 | #define DEFINE_SWIZZLER2_COMP1(a, a2) \ |
| 468 | _DEFINE_SWIZZLER2(a, a, a##a); \ | ||
| 469 | _DEFINE_SWIZZLER2(a, a, a2##a2) | ||
| 470 | #define DEFINE_SWIZZLER2_COMP2(a, b, a2, b2) \ | ||
| 465 | _DEFINE_SWIZZLER2(a, b, a##b); \ | 471 | _DEFINE_SWIZZLER2(a, b, a##b); \ |
| 466 | _DEFINE_SWIZZLER2(a, b, a2##b2); \ | 472 | _DEFINE_SWIZZLER2(a, b, a2##b2); \ |
| 467 | _DEFINE_SWIZZLER2(b, a, b##a); \ | 473 | _DEFINE_SWIZZLER2(b, a, b##a); \ |
| 468 | _DEFINE_SWIZZLER2(b, a, b2##a2) | 474 | _DEFINE_SWIZZLER2(b, a, b2##a2) |
| 469 | 475 | ||
| 470 | DEFINE_SWIZZLER2(x, y, r, g); | 476 | DEFINE_SWIZZLER2_COMP2(x, y, r, g); |
| 471 | DEFINE_SWIZZLER2(x, z, r, b); | 477 | DEFINE_SWIZZLER2_COMP2(x, z, r, b); |
| 472 | DEFINE_SWIZZLER2(x, w, r, a); | 478 | DEFINE_SWIZZLER2_COMP2(x, w, r, a); |
| 473 | DEFINE_SWIZZLER2(y, z, g, b); | 479 | DEFINE_SWIZZLER2_COMP2(y, z, g, b); |
| 474 | DEFINE_SWIZZLER2(y, w, g, a); | 480 | DEFINE_SWIZZLER2_COMP2(y, w, g, a); |
| 475 | DEFINE_SWIZZLER2(z, w, b, a); | 481 | DEFINE_SWIZZLER2_COMP2(z, w, b, a); |
| 476 | #undef DEFINE_SWIZZLER2 | 482 | DEFINE_SWIZZLER2_COMP1(x, r); |
| 483 | DEFINE_SWIZZLER2_COMP1(y, g); | ||
| 484 | DEFINE_SWIZZLER2_COMP1(z, b); | ||
| 485 | DEFINE_SWIZZLER2_COMP1(w, a); | ||
| 486 | #undef DEFINE_SWIZZLER2_COMP1 | ||
| 487 | #undef DEFINE_SWIZZLER2_COMP2 | ||
| 477 | #undef _DEFINE_SWIZZLER2 | 488 | #undef _DEFINE_SWIZZLER2 |
| 478 | 489 | ||
| 479 | #define _DEFINE_SWIZZLER3(a, b, c, name) const Vec3<T> name() const { return Vec3<T>(a, b, c); } | 490 | #define _DEFINE_SWIZZLER3(a, b, c, name) const Vec3<T> name() const { return Vec3<T>(a, b, c); } |
| 480 | #define DEFINE_SWIZZLER3(a, b, c, a2, b2, c2) \ | 491 | #define DEFINE_SWIZZLER3_COMP1(a, a2) \ |
| 492 | _DEFINE_SWIZZLER3(a, a, a, a##a##a); \ | ||
| 493 | _DEFINE_SWIZZLER3(a, a, a, a2##a2##a2) | ||
| 494 | #define DEFINE_SWIZZLER3_COMP3(a, b, c, a2, b2, c2) \ | ||
| 481 | _DEFINE_SWIZZLER3(a, b, c, a##b##c); \ | 495 | _DEFINE_SWIZZLER3(a, b, c, a##b##c); \ |
| 482 | _DEFINE_SWIZZLER3(a, c, b, a##c##b); \ | 496 | _DEFINE_SWIZZLER3(a, c, b, a##c##b); \ |
| 483 | _DEFINE_SWIZZLER3(b, a, c, b##a##c); \ | 497 | _DEFINE_SWIZZLER3(b, a, c, b##a##c); \ |
| @@ -491,11 +505,16 @@ public: | |||
| 491 | _DEFINE_SWIZZLER3(c, a, b, c2##a2##b2); \ | 505 | _DEFINE_SWIZZLER3(c, a, b, c2##a2##b2); \ |
| 492 | _DEFINE_SWIZZLER3(c, b, a, c2##b2##a2) | 506 | _DEFINE_SWIZZLER3(c, b, a, c2##b2##a2) |
| 493 | 507 | ||
| 494 | DEFINE_SWIZZLER3(x, y, z, r, g, b); | 508 | DEFINE_SWIZZLER3_COMP3(x, y, z, r, g, b); |
| 495 | DEFINE_SWIZZLER3(x, y, w, r, g, a); | 509 | DEFINE_SWIZZLER3_COMP3(x, y, w, r, g, a); |
| 496 | DEFINE_SWIZZLER3(x, z, w, r, b, a); | 510 | DEFINE_SWIZZLER3_COMP3(x, z, w, r, b, a); |
| 497 | DEFINE_SWIZZLER3(y, z, w, g, b, a); | 511 | DEFINE_SWIZZLER3_COMP3(y, z, w, g, b, a); |
| 498 | #undef DEFINE_SWIZZLER3 | 512 | DEFINE_SWIZZLER3_COMP1(x, r); |
| 513 | DEFINE_SWIZZLER3_COMP1(y, g); | ||
| 514 | DEFINE_SWIZZLER3_COMP1(z, b); | ||
| 515 | DEFINE_SWIZZLER3_COMP1(w, a); | ||
| 516 | #undef DEFINE_SWIZZLER3_COMP1 | ||
| 517 | #undef DEFINE_SWIZZLER3_COMP3 | ||
| 499 | #undef _DEFINE_SWIZZLER3 | 518 | #undef _DEFINE_SWIZZLER3 |
| 500 | }; | 519 | }; |
| 501 | 520 | ||
diff --git a/src/video_core/pica.h b/src/video_core/pica.h index 2506bf78e..1566b890d 100644 --- a/src/video_core/pica.h +++ b/src/video_core/pica.h | |||
| @@ -233,19 +233,29 @@ struct Regs { | |||
| 233 | }; | 233 | }; |
| 234 | 234 | ||
| 235 | enum class ColorModifier : u32 { | 235 | enum class ColorModifier : u32 { |
| 236 | SourceColor = 0, | 236 | SourceColor = 0x0, |
| 237 | OneMinusSourceColor = 1, | 237 | OneMinusSourceColor = 0x1, |
| 238 | SourceAlpha = 2, | 238 | SourceAlpha = 0x2, |
| 239 | OneMinusSourceAlpha = 3, | 239 | OneMinusSourceAlpha = 0x3, |
| 240 | 240 | SourceRed = 0x4, | |
| 241 | // Other values seem to be non-standard extensions | 241 | OneMinusSourceRed = 0x5, |
| 242 | |||
| 243 | SourceGreen = 0x8, | ||
| 244 | OneMinusSourceGreen = 0x9, | ||
| 245 | |||
| 246 | SourceBlue = 0xc, | ||
| 247 | OneMinusSourceBlue = 0xd, | ||
| 242 | }; | 248 | }; |
| 243 | 249 | ||
| 244 | enum class AlphaModifier : u32 { | 250 | enum class AlphaModifier : u32 { |
| 245 | SourceAlpha = 0, | 251 | SourceAlpha = 0x0, |
| 246 | OneMinusSourceAlpha = 1, | 252 | OneMinusSourceAlpha = 0x1, |
| 247 | 253 | SourceRed = 0x2, | |
| 248 | // Other values seem to be non-standard extensions | 254 | OneMinusSourceRed = 0x3, |
| 255 | SourceGreen = 0x4, | ||
| 256 | OneMinusSourceGreen = 0x5, | ||
| 257 | SourceBlue = 0x6, | ||
| 258 | OneMinusSourceBlue = 0x7, | ||
| 249 | }; | 259 | }; |
| 250 | 260 | ||
| 251 | enum class Operation : u32 { | 261 | enum class Operation : u32 { |
diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp index 845f1c4b2..5920477eb 100644 --- a/src/video_core/rasterizer.cpp +++ b/src/video_core/rasterizer.cpp | |||
| @@ -260,7 +260,7 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0, | |||
| 260 | using AlphaModifier = Regs::TevStageConfig::AlphaModifier; | 260 | using AlphaModifier = Regs::TevStageConfig::AlphaModifier; |
| 261 | using Operation = Regs::TevStageConfig::Operation; | 261 | using Operation = Regs::TevStageConfig::Operation; |
| 262 | 262 | ||
| 263 | auto GetColorSource = [&](Source source) -> Math::Vec4<u8> { | 263 | auto GetSource = [&](Source source) -> Math::Vec4<u8> { |
| 264 | switch (source) { | 264 | switch (source) { |
| 265 | case Source::PrimaryColor: | 265 | case Source::PrimaryColor: |
| 266 | return primary_color; | 266 | return primary_color; |
| @@ -287,36 +287,8 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0, | |||
| 287 | } | 287 | } |
| 288 | }; | 288 | }; |
| 289 | 289 | ||
| 290 | auto GetAlphaSource = [&](Source source) -> u8 { | ||
| 291 | switch (source) { | ||
| 292 | case Source::PrimaryColor: | ||
| 293 | return primary_color.a(); | ||
| 294 | |||
| 295 | case Source::Texture0: | ||
| 296 | return texture_color[0].a(); | ||
| 297 | |||
| 298 | case Source::Texture1: | ||
| 299 | return texture_color[1].a(); | ||
| 300 | |||
| 301 | case Source::Texture2: | ||
| 302 | return texture_color[2].a(); | ||
| 303 | |||
| 304 | case Source::Constant: | ||
| 305 | return tev_stage.const_a; | ||
| 306 | |||
| 307 | case Source::Previous: | ||
| 308 | return combiner_output.a(); | ||
| 309 | |||
| 310 | default: | ||
| 311 | LOG_ERROR(HW_GPU, "Unknown alpha combiner source %d\n", (int)source); | ||
| 312 | _dbg_assert_(HW_GPU, 0); | ||
| 313 | return 0; | ||
| 314 | } | ||
| 315 | }; | ||
| 316 | |||
| 317 | static auto GetColorModifier = [](ColorModifier factor, const Math::Vec4<u8>& values) -> Math::Vec3<u8> { | 290 | static auto GetColorModifier = [](ColorModifier factor, const Math::Vec4<u8>& values) -> Math::Vec3<u8> { |
| 318 | switch (factor) | 291 | switch (factor) { |
| 319 | { | ||
| 320 | case ColorModifier::SourceColor: | 292 | case ColorModifier::SourceColor: |
| 321 | return values.rgb(); | 293 | return values.rgb(); |
| 322 | 294 | ||
| @@ -324,27 +296,56 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0, | |||
| 324 | return (Math::Vec3<u8>(255, 255, 255) - values.rgb()).Cast<u8>(); | 296 | return (Math::Vec3<u8>(255, 255, 255) - values.rgb()).Cast<u8>(); |
| 325 | 297 | ||
| 326 | case ColorModifier::SourceAlpha: | 298 | case ColorModifier::SourceAlpha: |
| 327 | return { values.a(), values.a(), values.a() }; | 299 | return values.aaa(); |
| 328 | 300 | ||
| 329 | default: | 301 | case ColorModifier::OneMinusSourceAlpha: |
| 330 | LOG_ERROR(HW_GPU, "Unknown color factor %d\n", (int)factor); | 302 | return (Math::Vec3<u8>(255, 255, 255) - values.aaa()).Cast<u8>(); |
| 331 | _dbg_assert_(HW_GPU, 0); | 303 | |
| 332 | return {}; | 304 | case ColorModifier::SourceRed: |
| 305 | return values.rrr(); | ||
| 306 | |||
| 307 | case ColorModifier::OneMinusSourceRed: | ||
| 308 | return (Math::Vec3<u8>(255, 255, 255) - values.rrr()).Cast<u8>(); | ||
| 309 | |||
| 310 | case ColorModifier::SourceGreen: | ||
| 311 | return values.ggg(); | ||
| 312 | |||
| 313 | case ColorModifier::OneMinusSourceGreen: | ||
| 314 | return (Math::Vec3<u8>(255, 255, 255) - values.ggg()).Cast<u8>(); | ||
| 315 | |||
| 316 | case ColorModifier::SourceBlue: | ||
| 317 | return values.bbb(); | ||
| 318 | |||
| 319 | case ColorModifier::OneMinusSourceBlue: | ||
| 320 | return (Math::Vec3<u8>(255, 255, 255) - values.bbb()).Cast<u8>(); | ||
| 333 | } | 321 | } |
| 334 | }; | 322 | }; |
| 335 | 323 | ||
| 336 | static auto GetAlphaModifier = [](AlphaModifier factor, u8 value) -> u8 { | 324 | static auto GetAlphaModifier = [](AlphaModifier factor, const Math::Vec4<u8>& values) -> u8 { |
| 337 | switch (factor) { | 325 | switch (factor) { |
| 338 | case AlphaModifier::SourceAlpha: | 326 | case AlphaModifier::SourceAlpha: |
| 339 | return value; | 327 | return values.a(); |
| 340 | 328 | ||
| 341 | case AlphaModifier::OneMinusSourceAlpha: | 329 | case AlphaModifier::OneMinusSourceAlpha: |
| 342 | return 255 - value; | 330 | return 255 - values.a(); |
| 343 | 331 | ||
| 344 | default: | 332 | case AlphaModifier::SourceRed: |
| 345 | LOG_ERROR(HW_GPU, "Unknown alpha factor %d\n", (int)factor); | 333 | return values.r(); |
| 346 | _dbg_assert_(HW_GPU, 0); | 334 | |
| 347 | return 0; | 335 | case AlphaModifier::OneMinusSourceRed: |
| 336 | return 255 - values.r(); | ||
| 337 | |||
| 338 | case AlphaModifier::SourceGreen: | ||
| 339 | return values.g(); | ||
| 340 | |||
| 341 | case AlphaModifier::OneMinusSourceGreen: | ||
| 342 | return 255 - values.g(); | ||
| 343 | |||
| 344 | case AlphaModifier::SourceBlue: | ||
| 345 | return values.b(); | ||
| 346 | |||
| 347 | case AlphaModifier::OneMinusSourceBlue: | ||
| 348 | return 255 - values.b(); | ||
| 348 | } | 349 | } |
| 349 | }; | 350 | }; |
| 350 | 351 | ||
| @@ -414,17 +415,17 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0, | |||
| 414 | // combiner_output.rgb(), but instead store it in a temporary variable until | 415 | // combiner_output.rgb(), but instead store it in a temporary variable until |
| 415 | // alpha combining has been done. | 416 | // alpha combining has been done. |
| 416 | Math::Vec3<u8> color_result[3] = { | 417 | Math::Vec3<u8> color_result[3] = { |
| 417 | GetColorModifier(tev_stage.color_modifier1, GetColorSource(tev_stage.color_source1)), | 418 | GetColorModifier(tev_stage.color_modifier1, GetSource(tev_stage.color_source1)), |
| 418 | GetColorModifier(tev_stage.color_modifier2, GetColorSource(tev_stage.color_source2)), | 419 | GetColorModifier(tev_stage.color_modifier2, GetSource(tev_stage.color_source2)), |
| 419 | GetColorModifier(tev_stage.color_modifier3, GetColorSource(tev_stage.color_source3)) | 420 | GetColorModifier(tev_stage.color_modifier3, GetSource(tev_stage.color_source3)) |
| 420 | }; | 421 | }; |
| 421 | auto color_output = ColorCombine(tev_stage.color_op, color_result); | 422 | auto color_output = ColorCombine(tev_stage.color_op, color_result); |
| 422 | 423 | ||
| 423 | // alpha combiner | 424 | // alpha combiner |
| 424 | std::array<u8,3> alpha_result = { | 425 | std::array<u8,3> alpha_result = { |
| 425 | GetAlphaModifier(tev_stage.alpha_modifier1, GetAlphaSource(tev_stage.alpha_source1)), | 426 | GetAlphaModifier(tev_stage.alpha_modifier1, GetSource(tev_stage.alpha_source1)), |
| 426 | GetAlphaModifier(tev_stage.alpha_modifier2, GetAlphaSource(tev_stage.alpha_source2)), | 427 | GetAlphaModifier(tev_stage.alpha_modifier2, GetSource(tev_stage.alpha_source2)), |
| 427 | GetAlphaModifier(tev_stage.alpha_modifier3, GetAlphaSource(tev_stage.alpha_source3)) | 428 | GetAlphaModifier(tev_stage.alpha_modifier3, GetSource(tev_stage.alpha_source3)) |
| 428 | }; | 429 | }; |
| 429 | auto alpha_output = AlphaCombine(tev_stage.alpha_op, alpha_result); | 430 | auto alpha_output = AlphaCombine(tev_stage.alpha_op, alpha_result); |
| 430 | 431 | ||