Pica: Further improve Tev emulation.
This commit is contained in:
parent
3df88d59b0
commit
7e210e0229
|
@ -573,20 +573,26 @@ void DumpTevStageConfig(const std::array<Pica::Regs::TevStageConfig,6>& stages)
|
||||||
const std::map<Source, std::string> source_map = {
|
const std::map<Source, std::string> source_map = {
|
||||||
{ Source::PrimaryColor, "PrimaryColor" },
|
{ Source::PrimaryColor, "PrimaryColor" },
|
||||||
{ Source::Texture0, "Texture0" },
|
{ Source::Texture0, "Texture0" },
|
||||||
|
{ Source::Texture1, "Texture1" },
|
||||||
|
{ Source::Texture2, "Texture2" },
|
||||||
{ Source::Constant, "Constant" },
|
{ Source::Constant, "Constant" },
|
||||||
{ Source::Previous, "Previous" },
|
{ Source::Previous, "Previous" },
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::map<ColorModifier, std::string> color_modifier_map = {
|
const std::map<ColorModifier, std::string> color_modifier_map = {
|
||||||
{ ColorModifier::SourceColor, { "%source.rgb" } }
|
{ ColorModifier::SourceColor, { "%source.rgb" } },
|
||||||
|
{ ColorModifier::SourceAlpha, { "%source.aaa" } },
|
||||||
};
|
};
|
||||||
const std::map<AlphaModifier, std::string> alpha_modifier_map = {
|
const std::map<AlphaModifier, std::string> alpha_modifier_map = {
|
||||||
{ AlphaModifier::SourceAlpha, "%source.a" }
|
{ AlphaModifier::SourceAlpha, "%source.a" },
|
||||||
|
{ AlphaModifier::OneMinusSourceAlpha, "(255 - %source.a)" },
|
||||||
};
|
};
|
||||||
|
|
||||||
std::map<Operation, std::string> combiner_map = {
|
std::map<Operation, std::string> combiner_map = {
|
||||||
{ Operation::Replace, "%source1" },
|
{ Operation::Replace, "%source1" },
|
||||||
{ Operation::Modulate, "(%source1 * %source2) / 255" },
|
{ Operation::Modulate, "(%source1 * %source2) / 255" },
|
||||||
|
{ Operation::Add, "(%source1 + %source2)" },
|
||||||
|
{ Operation::Lerp, "lerp(%source1, %source2, %source3)" },
|
||||||
};
|
};
|
||||||
|
|
||||||
auto ReplacePattern =
|
auto ReplacePattern =
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "common/bit_field.h"
|
#include "common/bit_field.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
|
@ -225,28 +225,29 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0,
|
||||||
using AlphaModifier = Regs::TevStageConfig::AlphaModifier;
|
using AlphaModifier = Regs::TevStageConfig::AlphaModifier;
|
||||||
using Operation = Regs::TevStageConfig::Operation;
|
using Operation = Regs::TevStageConfig::Operation;
|
||||||
|
|
||||||
auto GetColorSource = [&](Source source) -> Math::Vec3<u8> {
|
auto GetColorSource = [&](Source source) -> Math::Vec4<u8> {
|
||||||
switch (source) {
|
switch (source) {
|
||||||
case Source::PrimaryColor:
|
case Source::PrimaryColor:
|
||||||
return primary_color.rgb();
|
return primary_color;
|
||||||
|
|
||||||
case Source::Texture0:
|
case Source::Texture0:
|
||||||
return texture_color[0].rgb();
|
return texture_color[0];
|
||||||
|
|
||||||
case Source::Texture1:
|
case Source::Texture1:
|
||||||
return texture_color[1].rgb();
|
return texture_color[1];
|
||||||
|
|
||||||
case Source::Texture2:
|
case Source::Texture2:
|
||||||
return texture_color[2].rgb();
|
return texture_color[2];
|
||||||
|
|
||||||
case Source::Constant:
|
case Source::Constant:
|
||||||
return {tev_stage.const_r, tev_stage.const_g, tev_stage.const_b};
|
return {tev_stage.const_r, tev_stage.const_g, tev_stage.const_b, tev_stage.const_a};
|
||||||
|
|
||||||
case Source::Previous:
|
case Source::Previous:
|
||||||
return combiner_output.rgb();
|
return combiner_output;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOG_ERROR(HW_GPU, "Unknown color combiner source %d\n", (int)source);
|
LOG_ERROR(HW_GPU, "Unknown color combiner source %d\n", (int)source);
|
||||||
|
_dbg_assert_(HW_GPU, 0);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -273,17 +274,23 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0,
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOG_ERROR(HW_GPU, "Unknown alpha combiner source %d\n", (int)source);
|
LOG_ERROR(HW_GPU, "Unknown alpha combiner source %d\n", (int)source);
|
||||||
|
_dbg_assert_(HW_GPU, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
auto GetColorModifier = [](ColorModifier factor, const Math::Vec3<u8>& values) -> Math::Vec3<u8> {
|
auto GetColorModifier = [](ColorModifier factor, const Math::Vec4<u8>& values) -> Math::Vec3<u8> {
|
||||||
switch (factor)
|
switch (factor)
|
||||||
{
|
{
|
||||||
case ColorModifier::SourceColor:
|
case ColorModifier::SourceColor:
|
||||||
return values;
|
return values.rgb();
|
||||||
|
|
||||||
|
case ColorModifier::SourceAlpha:
|
||||||
|
return { values.a(), values.a(), values.a() };
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOG_ERROR(HW_GPU, "Unknown color factor %d\n", (int)factor);
|
LOG_ERROR(HW_GPU, "Unknown color factor %d\n", (int)factor);
|
||||||
|
_dbg_assert_(HW_GPU, 0);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -292,8 +299,13 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0,
|
||||||
switch (factor) {
|
switch (factor) {
|
||||||
case AlphaModifier::SourceAlpha:
|
case AlphaModifier::SourceAlpha:
|
||||||
return value;
|
return value;
|
||||||
|
|
||||||
|
case AlphaModifier::OneMinusSourceAlpha:
|
||||||
|
return 255 - value;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOG_ERROR(HW_GPU, "Unknown color factor %d\n", (int)factor);
|
LOG_ERROR(HW_GPU, "Unknown alpha factor %d\n", (int)factor);
|
||||||
|
_dbg_assert_(HW_GPU, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -306,8 +318,21 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0,
|
||||||
case Operation::Modulate:
|
case Operation::Modulate:
|
||||||
return ((input[0] * input[1]) / 255).Cast<u8>();
|
return ((input[0] * input[1]) / 255).Cast<u8>();
|
||||||
|
|
||||||
|
case Operation::Add:
|
||||||
|
{
|
||||||
|
auto result = input[0] + input[1];
|
||||||
|
result.r() = std::min(255, result.r());
|
||||||
|
result.g() = std::min(255, result.g());
|
||||||
|
result.b() = std::min(255, result.b());
|
||||||
|
return result.Cast<u8>();
|
||||||
|
}
|
||||||
|
|
||||||
|
case Operation::Lerp:
|
||||||
|
return ((input[0] * input[2] + input[1] * (Math::MakeVec<u8>(255, 255, 255) - input[2]).Cast<u8>()) / 255).Cast<u8>();
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOG_ERROR(HW_GPU, "Unknown color combiner operation %d\n", (int)op);
|
LOG_ERROR(HW_GPU, "Unknown color combiner operation %d\n", (int)op);
|
||||||
|
_dbg_assert_(HW_GPU, 0);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -320,8 +345,15 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0,
|
||||||
case Operation::Modulate:
|
case Operation::Modulate:
|
||||||
return input[0] * input[1] / 255;
|
return input[0] * input[1] / 255;
|
||||||
|
|
||||||
|
case Operation::Add:
|
||||||
|
return std::min(255, input[0] + input[1]);
|
||||||
|
|
||||||
|
case Operation::Lerp:
|
||||||
|
return (input[0] * input[2] + input[1] * (255 - input[2])) / 255;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOG_ERROR(HW_GPU, "Unknown alpha combiner operation %d\n", (int)op);
|
LOG_ERROR(HW_GPU, "Unknown alpha combiner operation %d\n", (int)op);
|
||||||
|
_dbg_assert_(HW_GPU, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Reference in New Issue