mirror of
https://github.com/mikage-emu/mikage-dev.git
synced 2025-01-08 14:30:59 +01:00
Pica: Migrate some register definitions to BitField::v3
This commit is contained in:
parent
14a19c29ae
commit
2100cfe3ee
5 changed files with 72 additions and 78 deletions
|
@ -31,7 +31,7 @@ enum class CullMode : uint32_t {
|
||||||
// TODO: What does the third value imply?
|
// TODO: What does the third value imply?
|
||||||
};
|
};
|
||||||
|
|
||||||
union AlphaTest {
|
struct AlphaTest {
|
||||||
enum class Function : uint32_t {
|
enum class Function : uint32_t {
|
||||||
Always = 1,
|
Always = 1,
|
||||||
NotEqual = 3,
|
NotEqual = 3,
|
||||||
|
@ -39,9 +39,11 @@ union AlphaTest {
|
||||||
GreaterThanOrEqual = 7,
|
GreaterThanOrEqual = 7,
|
||||||
};
|
};
|
||||||
|
|
||||||
BitFieldLegacy<0, 1, uint32_t> enable;
|
uint32_t storage;
|
||||||
BitFieldLegacy<4, 3, Function> function;
|
|
||||||
BitFieldLegacy<8, 8, uint32_t> reference;
|
auto enable() const { return BitField::v3::MakeFlagOn<0>(this); }
|
||||||
|
auto function() const { return BitField::v3::MakeFieldOn<4, 3, Function>(this); }
|
||||||
|
auto reference() const { return BitField::v3::MakeFieldOn<8, 8>(this); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct StencilTest {
|
struct StencilTest {
|
||||||
|
@ -474,54 +476,46 @@ struct Regs {
|
||||||
AddThenMultiply = 9,
|
AddThenMultiply = 9,
|
||||||
};
|
};
|
||||||
|
|
||||||
union {
|
uint32_t storage[5];
|
||||||
BitFieldLegacy< 0, 4, Source> color_source1;
|
|
||||||
BitFieldLegacy< 4, 4, Source> color_source2;
|
|
||||||
BitFieldLegacy< 8, 4, Source> color_source3;
|
|
||||||
BitFieldLegacy<16, 4, Source> alpha_source1;
|
|
||||||
BitFieldLegacy<20, 4, Source> alpha_source2;
|
|
||||||
BitFieldLegacy<24, 4, Source> alpha_source3;
|
|
||||||
};
|
|
||||||
|
|
||||||
union {
|
auto color_source1() const { return BitField::v3::MakeFieldOn<0, 4, Source>(&storage[0]); }
|
||||||
BitFieldLegacy< 0, 4, ColorModifier> color_modifier1;
|
auto color_source2() const { return BitField::v3::MakeFieldOn<4, 4, Source>(&storage[0]); }
|
||||||
BitFieldLegacy< 4, 4, ColorModifier> color_modifier2;
|
auto color_source3() const { return BitField::v3::MakeFieldOn<8, 4, Source>(&storage[0]); }
|
||||||
BitFieldLegacy< 8, 4, ColorModifier> color_modifier3;
|
auto alpha_source1() const { return BitField::v3::MakeFieldOn<16, 4, Source>(&storage[0]); }
|
||||||
BitFieldLegacy<12, 3, AlphaModifier> alpha_modifier1;
|
auto alpha_source2() const { return BitField::v3::MakeFieldOn<20, 4, Source>(&storage[0]); }
|
||||||
BitFieldLegacy<16, 3, AlphaModifier> alpha_modifier2;
|
auto alpha_source3() const { return BitField::v3::MakeFieldOn<24, 4, Source>(&storage[0]); }
|
||||||
BitFieldLegacy<20, 3, AlphaModifier> alpha_modifier3;
|
|
||||||
};
|
|
||||||
|
|
||||||
union {
|
auto color_modifier1() const { return BitField::v3::MakeFieldOn<0, 4, ColorModifier>(&storage[1]); }
|
||||||
BitFieldLegacy< 0, 4, Operation> color_op;
|
auto color_modifier2() const { return BitField::v3::MakeFieldOn<4, 4, ColorModifier>(&storage[1]); }
|
||||||
BitFieldLegacy<16, 4, Operation> alpha_op;
|
auto color_modifier3() const { return BitField::v3::MakeFieldOn<8, 4, ColorModifier>(&storage[1]); }
|
||||||
};
|
auto alpha_modifier1() const { return BitField::v3::MakeFieldOn<12, 3, AlphaModifier>(&storage[1]); }
|
||||||
|
auto alpha_modifier2() const { return BitField::v3::MakeFieldOn<16, 3, AlphaModifier>(&storage[1]); }
|
||||||
|
auto alpha_modifier3() const { return BitField::v3::MakeFieldOn<20, 3, AlphaModifier>(&storage[1]); }
|
||||||
|
|
||||||
union {
|
auto color_op() const { return BitField::v3::MakeFieldOn<0, 4, Operation>(&storage[2]); }
|
||||||
BitFieldLegacy< 0, 8, uint32_t> const_r;
|
auto alpha_op() const { return BitField::v3::MakeFieldOn<16, 4, Operation>(&storage[2]); }
|
||||||
BitFieldLegacy< 8, 8, uint32_t> const_g;
|
|
||||||
BitFieldLegacy<16, 8, uint32_t> const_b;
|
auto const_r() const { return BitField::v3::MakeFieldOn<0, 8, uint8_t>(&storage[3]); }
|
||||||
BitFieldLegacy<24, 8, uint32_t> const_a;
|
auto const_g() const { return BitField::v3::MakeFieldOn<8, 8, uint8_t>(&storage[3]); }
|
||||||
};
|
auto const_b() const { return BitField::v3::MakeFieldOn<16, 8, uint8_t>(&storage[3]); }
|
||||||
|
auto const_a() const { return BitField::v3::MakeFieldOn<24, 8, uint8_t>(&storage[3]); }
|
||||||
|
|
||||||
union {
|
|
||||||
// Access these through the convenience getters below
|
// Access these through the convenience getters below
|
||||||
BitFieldLegacy< 0, 2, uint32_t> multiplier_exp_rgb;
|
auto multiplier_exp_rgb() const { return BitField::v3::MakeFieldOn<0, 2>(&storage[4]); }
|
||||||
BitFieldLegacy<16, 2, uint32_t> multiplier_exp_a;
|
auto multiplier_exp_a() const { return BitField::v3::MakeFieldOn<16, 2>(&storage[4]); }
|
||||||
};
|
|
||||||
|
|
||||||
uint32_t GetMultiplierRGB() const {
|
uint32_t GetMultiplierRGB() const {
|
||||||
if (multiplier_exp_rgb == 3) {
|
if (multiplier_exp_rgb() == 3) {
|
||||||
throw std::runtime_error("Invalid RGB scaling exponent 3");
|
throw std::runtime_error("Invalid RGB scaling exponent 3");
|
||||||
}
|
}
|
||||||
return (1 << multiplier_exp_rgb);
|
return (1 << multiplier_exp_rgb());
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t GetMultiplierA() const {
|
uint32_t GetMultiplierA() const {
|
||||||
if (multiplier_exp_a == 3) {
|
if (multiplier_exp_a() == 3) {
|
||||||
throw std::runtime_error("Invalid alpha scaling exponent 3");
|
throw std::runtime_error("Invalid alpha scaling exponent 3");
|
||||||
}
|
}
|
||||||
return (1 << multiplier_exp_a);
|
return (1 << multiplier_exp_a());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -687,12 +681,12 @@ struct Regs {
|
||||||
struct {
|
struct {
|
||||||
// The 3DS fragment lighting pipeline doesn't distinguish between
|
// The 3DS fragment lighting pipeline doesn't distinguish between
|
||||||
// materials and lights, so these properties are premultiplied
|
// materials and lights, so these properties are premultiplied
|
||||||
LightingColor specular[2];
|
std::array<LightingColor, 2> specular;
|
||||||
LightingColor diffuse;
|
LightingColor diffuse;
|
||||||
LightingColor ambient;
|
LightingColor ambient;
|
||||||
|
|
||||||
// NOTE: If is_directional() is false, these actually specify the position
|
// NOTE: If is_directional() is false, these actually specify the position
|
||||||
uint32_t raw_light_dir[2];
|
std::array<uint32_t, 2> raw_light_dir;
|
||||||
constexpr auto raw_light_dir_x() const { return BitField::v3::MakeFieldOn< 0, 16>(&raw_light_dir[0]); }
|
constexpr auto raw_light_dir_x() const { return BitField::v3::MakeFieldOn< 0, 16>(&raw_light_dir[0]); }
|
||||||
constexpr auto raw_light_dir_y() const { return BitField::v3::MakeFieldOn<16, 16>(&raw_light_dir[0]); }
|
constexpr auto raw_light_dir_y() const { return BitField::v3::MakeFieldOn<16, 16>(&raw_light_dir[0]); }
|
||||||
constexpr auto raw_light_dir_z() const { return BitField::v3::MakeFieldOn< 0, 16>(&raw_light_dir[1]); }
|
constexpr auto raw_light_dir_z() const { return BitField::v3::MakeFieldOn< 0, 16>(&raw_light_dir[1]); }
|
||||||
|
@ -701,7 +695,7 @@ struct Regs {
|
||||||
float16 get_light_dir_z() const { return float16::FromRawFloat(raw_light_dir_z()); }
|
float16 get_light_dir_z() const { return float16::FromRawFloat(raw_light_dir_z()); }
|
||||||
|
|
||||||
// 13-bit signed fixed-point coordinates with 11 bits of precision
|
// 13-bit signed fixed-point coordinates with 11 bits of precision
|
||||||
uint32_t raw_spot_dir[2];
|
std::array<uint32_t, 2> raw_spot_dir;
|
||||||
constexpr auto spot_dir_x() const { return BitField::v3::MakeFieldOn< 0, 13, int32_t>(&raw_spot_dir[0]); }
|
constexpr auto spot_dir_x() const { return BitField::v3::MakeFieldOn< 0, 13, int32_t>(&raw_spot_dir[0]); }
|
||||||
constexpr auto spot_dir_y() const { return BitField::v3::MakeFieldOn<16, 13, int32_t>(&raw_spot_dir[0]); }
|
constexpr auto spot_dir_y() const { return BitField::v3::MakeFieldOn<16, 13, int32_t>(&raw_spot_dir[0]); }
|
||||||
constexpr auto spot_dir_z() const { return BitField::v3::MakeFieldOn< 0, 13, int32_t>(&raw_spot_dir[1]); }
|
constexpr auto spot_dir_z() const { return BitField::v3::MakeFieldOn< 0, 13, int32_t>(&raw_spot_dir[1]); }
|
||||||
|
@ -857,7 +851,7 @@ struct Regs {
|
||||||
uint32_t storage_light_permutation;
|
uint32_t storage_light_permutation;
|
||||||
|
|
||||||
// Maps light IDs (0..max_light_id) to indexes into the light config array
|
// Maps light IDs (0..max_light_id) to indexes into the light config array
|
||||||
unsigned GetLightIndex(unsigned id) {
|
unsigned GetLightIndex(unsigned id) const {
|
||||||
return (storage_light_permutation >> (4 * id)) & 0b111;
|
return (storage_light_permutation >> (4 * id)) & 0b111;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -676,7 +676,7 @@ void DumpTevStageConfig(const std::array<Pica::Regs::TevStageConfig,6>& stages)
|
||||||
{ Source::Texture0, "Texture0" },
|
{ Source::Texture0, "Texture0" },
|
||||||
{ Source::Texture1, "Texture1" },
|
{ Source::Texture1, "Texture1" },
|
||||||
{ Source::Texture2, "Texture2" },
|
{ Source::Texture2, "Texture2" },
|
||||||
{ Source::Constant, fmt::format("({}, {}, {}, {})", tev_stage.const_r.Value(), tev_stage.const_g.Value(), tev_stage.const_b.Value(), tev_stage.const_a.Value()) },
|
{ Source::Constant, fmt::format("({}, {}, {}, {})", tev_stage.const_r()(), tev_stage.const_g()(), tev_stage.const_b()(), tev_stage.const_a()()) },
|
||||||
{ Source::Previous, "Previous" },
|
{ Source::Previous, "Previous" },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -733,18 +733,18 @@ void DumpTevStageConfig(const std::array<Pica::Regs::TevStageConfig,6>& stages)
|
||||||
};
|
};
|
||||||
static auto GetColorCombinerStr =
|
static auto GetColorCombinerStr =
|
||||||
[](const Regs::TevStageConfig& tev_stage) {
|
[](const Regs::TevStageConfig& tev_stage) {
|
||||||
auto op_it = combiner_map.find(tev_stage.color_op);
|
auto op_it = combiner_map.find(tev_stage.color_op());
|
||||||
std::string op_str = "Unknown op (%source1, %source2, %source3)";
|
std::string op_str = "Unknown op (%source1, %source2, %source3)";
|
||||||
if (op_it != combiner_map.end()) {
|
if (op_it != combiner_map.end()) {
|
||||||
op_str = op_it->second;
|
op_str = op_it->second;
|
||||||
} else {
|
} else {
|
||||||
op_str = fmt::format("UnknownOp_{:#x}", static_cast<uint32_t>(tev_stage.color_op.Value()));
|
op_str = fmt::format("UnknownOp_{:#x}", static_cast<uint32_t>(tev_stage.color_op()()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
op_str = ReplacePattern(op_str, "%source1", GetColorSourceStr(tev_stage.color_source1, tev_stage.color_modifier1));
|
op_str = ReplacePattern(op_str, "%source1", GetColorSourceStr(tev_stage.color_source1(), tev_stage.color_modifier1()));
|
||||||
op_str = ReplacePattern(op_str, "%source2", GetColorSourceStr(tev_stage.color_source2, tev_stage.color_modifier2));
|
op_str = ReplacePattern(op_str, "%source2", GetColorSourceStr(tev_stage.color_source2(), tev_stage.color_modifier2()));
|
||||||
return ReplacePattern(op_str, "%source3", GetColorSourceStr(tev_stage.color_source3, tev_stage.color_modifier3));
|
return ReplacePattern(op_str, "%source3", GetColorSourceStr(tev_stage.color_source3(), tev_stage.color_modifier3()));
|
||||||
};
|
};
|
||||||
static auto GetAlphaSourceStr =
|
static auto GetAlphaSourceStr =
|
||||||
[](const Source& src, const AlphaModifier& modifier) {
|
[](const Source& src, const AlphaModifier& modifier) {
|
||||||
|
@ -765,14 +765,14 @@ void DumpTevStageConfig(const std::array<Pica::Regs::TevStageConfig,6>& stages)
|
||||||
};
|
};
|
||||||
static auto GetAlphaCombinerStr =
|
static auto GetAlphaCombinerStr =
|
||||||
[](const Regs::TevStageConfig& tev_stage) {
|
[](const Regs::TevStageConfig& tev_stage) {
|
||||||
auto op_it = combiner_map.find(tev_stage.alpha_op);
|
auto op_it = combiner_map.find(tev_stage.alpha_op());
|
||||||
std::string op_str = "Unknown op (%source1, %source2, %source3)";
|
std::string op_str = "Unknown op (%source1, %source2, %source3)";
|
||||||
if (op_it != combiner_map.end())
|
if (op_it != combiner_map.end())
|
||||||
op_str = op_it->second;
|
op_str = op_it->second;
|
||||||
|
|
||||||
op_str = ReplacePattern(op_str, "%source1", GetAlphaSourceStr(tev_stage.alpha_source1, tev_stage.alpha_modifier1));
|
op_str = ReplacePattern(op_str, "%source1", GetAlphaSourceStr(tev_stage.alpha_source1(), tev_stage.alpha_modifier1()));
|
||||||
op_str = ReplacePattern(op_str, "%source2", GetAlphaSourceStr(tev_stage.alpha_source2, tev_stage.alpha_modifier2));
|
op_str = ReplacePattern(op_str, "%source2", GetAlphaSourceStr(tev_stage.alpha_source2(), tev_stage.alpha_modifier2()));
|
||||||
return ReplacePattern(op_str, "%source3", GetAlphaSourceStr(tev_stage.alpha_source3, tev_stage.alpha_modifier3));
|
return ReplacePattern(op_str, "%source3", GetAlphaSourceStr(tev_stage.alpha_source3(), tev_stage.alpha_modifier3()));
|
||||||
};
|
};
|
||||||
|
|
||||||
stage_info += "Stage " + std::to_string(index) + ": " + GetColorCombinerStr(tev_stage) + " " + GetAlphaCombinerStr(tev_stage) + "\n";
|
stage_info += "Stage " + std::to_string(index) + ": " + GetColorCombinerStr(tev_stage) + " " + GetAlphaCombinerStr(tev_stage) + "\n";
|
||||||
|
|
|
@ -547,7 +547,7 @@ static void ProcessTriangleInternal(Context& context,
|
||||||
return texture_color[2];
|
return texture_color[2];
|
||||||
|
|
||||||
case Source::Constant:
|
case Source::Constant:
|
||||||
return {tev_stage.const_r, tev_stage.const_g, tev_stage.const_b, tev_stage.const_a};
|
return {tev_stage.const_r()(), tev_stage.const_g()(), tev_stage.const_b()(), tev_stage.const_a()()};
|
||||||
|
|
||||||
case Source::CombinerBuffer:
|
case Source::CombinerBuffer:
|
||||||
return combiner_buffer;
|
return combiner_buffer;
|
||||||
|
@ -731,19 +731,19 @@ static void ProcessTriangleInternal(Context& context,
|
||||||
// combiner_output.rgb(), but instead store it in a temporary variable until
|
// combiner_output.rgb(), but instead store it in a temporary variable until
|
||||||
// alpha combining has been done.
|
// alpha combining has been done.
|
||||||
Math::Vec3<u8> color_result[3] = {
|
Math::Vec3<u8> color_result[3] = {
|
||||||
GetColorModifier(tev_stage.color_modifier1, GetCombinerSource(tev_stage.color_source1)),
|
GetColorModifier(tev_stage.color_modifier1(), GetCombinerSource(tev_stage.color_source1())),
|
||||||
GetColorModifier(tev_stage.color_modifier2, GetCombinerSource(tev_stage.color_source2)),
|
GetColorModifier(tev_stage.color_modifier2(), GetCombinerSource(tev_stage.color_source2())),
|
||||||
GetColorModifier(tev_stage.color_modifier3, GetCombinerSource(tev_stage.color_source3))
|
GetColorModifier(tev_stage.color_modifier3(), GetCombinerSource(tev_stage.color_source3()))
|
||||||
};
|
};
|
||||||
auto color_output = ColorCombine(tev_stage.color_op, color_result);
|
auto color_output = ColorCombine(tev_stage.color_op(), color_result);
|
||||||
|
|
||||||
// alpha combiner
|
// alpha combiner
|
||||||
std::array<u8,3> alpha_result = {
|
std::array<u8,3> alpha_result = {
|
||||||
GetAlphaModifier(tev_stage.alpha_modifier1, GetCombinerSource(tev_stage.alpha_source1)),
|
GetAlphaModifier(tev_stage.alpha_modifier1(), GetCombinerSource(tev_stage.alpha_source1())),
|
||||||
GetAlphaModifier(tev_stage.alpha_modifier2, GetCombinerSource(tev_stage.alpha_source2)),
|
GetAlphaModifier(tev_stage.alpha_modifier2(), GetCombinerSource(tev_stage.alpha_source2())),
|
||||||
GetAlphaModifier(tev_stage.alpha_modifier3, GetCombinerSource(tev_stage.alpha_source3))
|
GetAlphaModifier(tev_stage.alpha_modifier3(), GetCombinerSource(tev_stage.alpha_source3()))
|
||||||
};
|
};
|
||||||
auto alpha_output = AlphaCombine(tev_stage.alpha_op, alpha_result);
|
auto alpha_output = AlphaCombine(tev_stage.alpha_op(), alpha_result);
|
||||||
|
|
||||||
// TODO: Move to pica.h
|
// TODO: Move to pica.h
|
||||||
if (tev_stage_index > 0) {
|
if (tev_stage_index > 0) {
|
||||||
|
@ -770,8 +770,8 @@ static void ProcessTriangleInternal(Context& context,
|
||||||
combiner_output.a() = static_cast<uint8_t>(std::min<unsigned>(255, alpha_output * tev_stage.GetMultiplierA()));
|
combiner_output.a() = static_cast<uint8_t>(std::min<unsigned>(255, alpha_output * tev_stage.GetMultiplierA()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (registers.output_merger.alpha_test.enable && registers.output_merger.alpha_test.function != AlphaTest::Function::Always) {
|
if (registers.output_merger.alpha_test.enable() && registers.output_merger.alpha_test.function() != AlphaTest::Function::Always) {
|
||||||
if (AlphaTestFailed(combiner_output.a(), registers.output_merger.alpha_test.reference, registers.output_merger.alpha_test.function)) {
|
if (AlphaTestFailed(combiner_output.a(), registers.output_merger.alpha_test.reference(), registers.output_merger.alpha_test.function())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1173,7 +1173,7 @@ void Renderer::FinalizeTriangleBatchInternal(Context& context, const VertexShade
|
||||||
|
|
||||||
const auto tev_stages = context.registers.GetTevStages();
|
const auto tev_stages = context.registers.GetTevStages();
|
||||||
for (auto& tev_stage : tev_stages) {
|
for (auto& tev_stage : tev_stages) {
|
||||||
for (uint32_t val : { tev_stage.const_r.Value(), tev_stage.const_g.Value(), tev_stage.const_b.Value(), tev_stage.const_a.Value() }) {
|
for (uint32_t val : { tev_stage.const_r()(), tev_stage.const_g()(), tev_stage.const_b()(), tev_stage.const_a()() }) {
|
||||||
memcpy(ubo_data_ptr, &val, sizeof(val));
|
memcpy(ubo_data_ptr, &val, sizeof(val));
|
||||||
ubo_data_ptr += sizeof(val);
|
ubo_data_ptr += sizeof(val);
|
||||||
}
|
}
|
||||||
|
|
|
@ -349,8 +349,8 @@ std::string GenerateFragmentShader(Context& context) {
|
||||||
using AlphaModifier = Regs::TevStageConfig::AlphaModifier;
|
using AlphaModifier = Regs::TevStageConfig::AlphaModifier;
|
||||||
using Operation = Regs::TevStageConfig::Operation;
|
using Operation = Regs::TevStageConfig::Operation;
|
||||||
|
|
||||||
const bool is_nop_stage_rgb = (tev_stage.color_modifier1 == ColorModifier::SourceColor && tev_stage.color_op == Operation::Replace);
|
const bool is_nop_stage_rgb = (tev_stage.color_modifier1() == ColorModifier::SourceColor && tev_stage.color_op() == Operation::Replace);
|
||||||
const bool is_nop_stage_a = (tev_stage.alpha_modifier1 == AlphaModifier::SourceAlpha && tev_stage.alpha_op == Operation::Replace);
|
const bool is_nop_stage_a = (tev_stage.alpha_modifier1() == AlphaModifier::SourceAlpha && tev_stage.alpha_op() == Operation::Replace);
|
||||||
|
|
||||||
std::string tev_stage_str = "tev" + std::to_string(tev_stage_index) + "_";
|
std::string tev_stage_str = "tev" + std::to_string(tev_stage_index) + "_";
|
||||||
|
|
||||||
|
@ -518,9 +518,9 @@ std::string GenerateFragmentShader(Context& context) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
code += "uvec3 " + tev_stage_str + "rgb_in1 = " + GetModifiedColor(tev_stage.color_modifier1, GetSourceColor(tev_stage.color_source1).c_str()) + ";\n";
|
code += "uvec3 " + tev_stage_str + "rgb_in1 = " + GetModifiedColor(tev_stage.color_modifier1(), GetSourceColor(tev_stage.color_source1()).c_str()) + ";\n";
|
||||||
code += "uvec3 " + tev_stage_str + "rgb_in2 = " + GetModifiedColor(tev_stage.color_modifier2, GetSourceColor(tev_stage.color_source2).c_str()) + ";\n";
|
code += "uvec3 " + tev_stage_str + "rgb_in2 = " + GetModifiedColor(tev_stage.color_modifier2(), GetSourceColor(tev_stage.color_source2()).c_str()) + ";\n";
|
||||||
code += "uvec3 " + tev_stage_str + "rgb_in3 = " + GetModifiedColor(tev_stage.color_modifier3, GetSourceColor(tev_stage.color_source3).c_str()) + ";\n";
|
code += "uvec3 " + tev_stage_str + "rgb_in3 = " + GetModifiedColor(tev_stage.color_modifier3(), GetSourceColor(tev_stage.color_source3()).c_str()) + ";\n";
|
||||||
|
|
||||||
auto CombineRGB = [&](Operation op) -> std::string {
|
auto CombineRGB = [&](Operation op) -> std::string {
|
||||||
switch (op) {
|
switch (op) {
|
||||||
|
@ -582,9 +582,9 @@ std::string GenerateFragmentShader(Context& context) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
code += "uint " + tev_stage_str + "a_in1 = " + GetModifiedAlpha(tev_stage.alpha_modifier1, GetSourceAlpha(tev_stage.alpha_source1).c_str()) + ";\n";
|
code += "uint " + tev_stage_str + "a_in1 = " + GetModifiedAlpha(tev_stage.alpha_modifier1(), GetSourceAlpha(tev_stage.alpha_source1()).c_str()) + ";\n";
|
||||||
code += "uint " + tev_stage_str + "a_in2 = " + GetModifiedAlpha(tev_stage.alpha_modifier2, GetSourceAlpha(tev_stage.alpha_source2).c_str()) + ";\n";
|
code += "uint " + tev_stage_str + "a_in2 = " + GetModifiedAlpha(tev_stage.alpha_modifier2(), GetSourceAlpha(tev_stage.alpha_source2()).c_str()) + ";\n";
|
||||||
code += "uint " + tev_stage_str + "a_in3 = " + GetModifiedAlpha(tev_stage.alpha_modifier3, GetSourceAlpha(tev_stage.alpha_source3).c_str()) + ";\n";
|
code += "uint " + tev_stage_str + "a_in3 = " + GetModifiedAlpha(tev_stage.alpha_modifier3(), GetSourceAlpha(tev_stage.alpha_source3()).c_str()) + ";\n";
|
||||||
|
|
||||||
auto CombineA = [&](Operation op) -> std::string {
|
auto CombineA = [&](Operation op) -> std::string {
|
||||||
switch (op) {
|
switch (op) {
|
||||||
|
@ -628,9 +628,9 @@ std::string GenerateFragmentShader(Context& context) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
code += "uvec3 " + tev_stage_str + "out_rgb = " + CombineRGB(tev_stage.color_op) + ";\n";
|
code += "uvec3 " + tev_stage_str + "out_rgb = " + CombineRGB(tev_stage.color_op()) + ";\n";
|
||||||
|
|
||||||
code += "uint " + tev_stage_str + "out_a = " + CombineA(tev_stage.alpha_op) + ";\n";
|
code += "uint " + tev_stage_str + "out_a = " + CombineA(tev_stage.alpha_op()) + ";\n";
|
||||||
|
|
||||||
// TODO: Move to pica.h
|
// TODO: Move to pica.h
|
||||||
if (tev_stage_index > 0) {
|
if (tev_stage_index > 0) {
|
||||||
|
@ -663,8 +663,8 @@ std::string GenerateFragmentShader(Context& context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& alpha_test = context.registers.output_merger.alpha_test;
|
auto& alpha_test = context.registers.output_merger.alpha_test;
|
||||||
if (alpha_test.enable && alpha_test.function != AlphaTest::Function::Always) {
|
if (alpha_test.enable() && alpha_test.function() != AlphaTest::Function::Always) {
|
||||||
const char* op = std::invoke([func=alpha_test.function.Value()]() {
|
const char* op = std::invoke([func=alpha_test.function()()]() {
|
||||||
// Inverse mapping for finding failing pixels rather than passing ones
|
// Inverse mapping for finding failing pixels rather than passing ones
|
||||||
switch (func) {
|
switch (func) {
|
||||||
case AlphaTest::Function::NotEqual:
|
case AlphaTest::Function::NotEqual:
|
||||||
|
@ -680,7 +680,7 @@ std::string GenerateFragmentShader(Context& context) {
|
||||||
throw std::runtime_error(fmt::format("Unknown alpha test function {:#x}", static_cast<uint32_t>(func)));
|
throw std::runtime_error(fmt::format("Unknown alpha test function {:#x}", static_cast<uint32_t>(func)));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
code += fmt::format("if (combiner_output.a {} {})\n", op, alpha_test.reference.Value());
|
code += fmt::format("if (combiner_output.a {} {})\n", op, alpha_test.reference()());
|
||||||
code += " discard;\n";
|
code += " discard;\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue