mirror of
https://github.com/PabloMK7/citra.git
synced 2024-11-24 08:24:18 +00:00
video_core: Use source3 when GPU_PREVIOUS is used in first stage (#7411)
This commit is contained in:
parent
d5a1bd07f3
commit
106364e01e
7 changed files with 83 additions and 101 deletions
|
@ -846,7 +846,7 @@ void RasterizerAccelerated::SyncTextureBorderColor(int tex_index) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerAccelerated::SyncClipPlane() {
|
void RasterizerAccelerated::SyncClipPlane() {
|
||||||
const bool enable_clip1 = regs.rasterizer.clip_enable != 0;
|
const u32 enable_clip1 = regs.rasterizer.clip_enable != 0;
|
||||||
const auto raw_clip_coef = regs.rasterizer.GetClipCoef();
|
const auto raw_clip_coef = regs.rasterizer.GetClipCoef();
|
||||||
const Common::Vec4f new_clip_coef = {raw_clip_coef.x.ToFloat32(), raw_clip_coef.y.ToFloat32(),
|
const Common::Vec4f new_clip_coef = {raw_clip_coef.x.ToFloat32(), raw_clip_coef.y.ToFloat32(),
|
||||||
raw_clip_coef.z.ToFloat32(), raw_clip_coef.w.ToFloat32()};
|
raw_clip_coef.z.ToFloat32(), raw_clip_coef.w.ToFloat32()};
|
||||||
|
|
|
@ -695,7 +695,7 @@ Common::Vec4<u8> RasterizerSoftware::WriteTevConfig(
|
||||||
* with some basic arithmetic. Alpha combiners can be configured separately but work
|
* with some basic arithmetic. Alpha combiners can be configured separately but work
|
||||||
* analogously.
|
* analogously.
|
||||||
**/
|
**/
|
||||||
Common::Vec4<u8> combiner_output = primary_color;
|
Common::Vec4<u8> combiner_output = {0, 0, 0, 0};
|
||||||
Common::Vec4<u8> combiner_buffer = {0, 0, 0, 0};
|
Common::Vec4<u8> combiner_buffer = {0, 0, 0, 0};
|
||||||
Common::Vec4<u8> next_combiner_buffer =
|
Common::Vec4<u8> next_combiner_buffer =
|
||||||
Common::MakeVec(regs.texturing.tev_combiner_buffer_color.r.Value(),
|
Common::MakeVec(regs.texturing.tev_combiner_buffer_color.r.Value(),
|
||||||
|
@ -746,9 +746,15 @@ Common::Vec4<u8> RasterizerSoftware::WriteTevConfig(
|
||||||
* 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.
|
||||||
**/
|
**/
|
||||||
|
const auto source1 = tev_stage_index == 0 && tev_stage.color_source1 == Source::Previous
|
||||||
|
? tev_stage.color_source3.Value()
|
||||||
|
: tev_stage.color_source1.Value();
|
||||||
|
const auto source2 = tev_stage_index == 0 && tev_stage.color_source2 == Source::Previous
|
||||||
|
? tev_stage.color_source3.Value()
|
||||||
|
: tev_stage.color_source2.Value();
|
||||||
const std::array<Common::Vec3<u8>, 3> color_result = {
|
const std::array<Common::Vec3<u8>, 3> color_result = {
|
||||||
GetColorModifier(tev_stage.color_modifier1, get_source(tev_stage.color_source1)),
|
GetColorModifier(tev_stage.color_modifier1, get_source(source1)),
|
||||||
GetColorModifier(tev_stage.color_modifier2, get_source(tev_stage.color_source2)),
|
GetColorModifier(tev_stage.color_modifier2, get_source(source2)),
|
||||||
GetColorModifier(tev_stage.color_modifier3, get_source(tev_stage.color_source3)),
|
GetColorModifier(tev_stage.color_modifier3, get_source(tev_stage.color_source3)),
|
||||||
};
|
};
|
||||||
const Common::Vec3<u8> color_output = ColorCombine(tev_stage.color_op, color_result);
|
const Common::Vec3<u8> color_output = ColorCombine(tev_stage.color_op, color_result);
|
||||||
|
|
|
@ -143,7 +143,7 @@ vec4 secondary_fragment_color = vec4(0.0);
|
||||||
|
|
||||||
out += "vec4 combiner_buffer = vec4(0.0);\n"
|
out += "vec4 combiner_buffer = vec4(0.0);\n"
|
||||||
"vec4 next_combiner_buffer = tev_combiner_buffer_color;\n"
|
"vec4 next_combiner_buffer = tev_combiner_buffer_color;\n"
|
||||||
"vec4 combiner_output = rounded_primary_color;\n";
|
"vec4 combiner_output = vec4(0.0);\n";
|
||||||
|
|
||||||
out += "vec3 color_results_1 = vec3(0.0);\n"
|
out += "vec3 color_results_1 = vec3(0.0);\n"
|
||||||
"vec3 color_results_2 = vec3(0.0);\n"
|
"vec3 color_results_2 = vec3(0.0);\n"
|
||||||
|
@ -225,96 +225,75 @@ void FragmentModule::WriteScissor() {
|
||||||
"gl_FragCoord.y < float(scissor_y2))) discard;\n";
|
"gl_FragCoord.y < float(scissor_y2))) discard;\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void FragmentModule::AppendSource(Pica::TexturingRegs::TevStageConfig::Source source,
|
std::string FragmentModule::GetSource(Pica::TexturingRegs::TevStageConfig::Source source,
|
||||||
u32 tev_index) {
|
u32 tev_index) {
|
||||||
using Source = Pica::TexturingRegs::TevStageConfig::Source;
|
using Source = Pica::TexturingRegs::TevStageConfig::Source;
|
||||||
switch (source) {
|
switch (source) {
|
||||||
case Source::PrimaryColor:
|
case Source::PrimaryColor:
|
||||||
out += "rounded_primary_color";
|
return "rounded_primary_color";
|
||||||
break;
|
|
||||||
case Source::PrimaryFragmentColor:
|
case Source::PrimaryFragmentColor:
|
||||||
out += "primary_fragment_color";
|
return "primary_fragment_color";
|
||||||
break;
|
|
||||||
case Source::SecondaryFragmentColor:
|
case Source::SecondaryFragmentColor:
|
||||||
out += "secondary_fragment_color";
|
return "secondary_fragment_color";
|
||||||
break;
|
|
||||||
case Source::Texture0:
|
case Source::Texture0:
|
||||||
out += "sampleTexUnit0()";
|
return "sampleTexUnit0()";
|
||||||
break;
|
|
||||||
case Source::Texture1:
|
case Source::Texture1:
|
||||||
out += "sampleTexUnit1()";
|
return "sampleTexUnit1()";
|
||||||
break;
|
|
||||||
case Source::Texture2:
|
case Source::Texture2:
|
||||||
out += "sampleTexUnit2()";
|
return "sampleTexUnit2()";
|
||||||
break;
|
|
||||||
case Source::Texture3:
|
case Source::Texture3:
|
||||||
out += "sampleTexUnit3()";
|
return "sampleTexUnit3()";
|
||||||
break;
|
|
||||||
case Source::PreviousBuffer:
|
case Source::PreviousBuffer:
|
||||||
out += "combiner_buffer";
|
return "combiner_buffer";
|
||||||
break;
|
|
||||||
case Source::Constant:
|
case Source::Constant:
|
||||||
out += fmt::format("const_color[{}]", tev_index);
|
return fmt::format("const_color[{}]", tev_index);
|
||||||
break;
|
|
||||||
case Source::Previous:
|
case Source::Previous:
|
||||||
out += "combiner_output";
|
return "combiner_output";
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
out += "vec4(0.0)";
|
|
||||||
LOG_CRITICAL(Render, "Unknown source op {}", source);
|
LOG_CRITICAL(Render, "Unknown source op {}", source);
|
||||||
break;
|
return "vec4(0.0)";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FragmentModule::AppendColorModifier(
|
void FragmentModule::AppendColorModifier(
|
||||||
Pica::TexturingRegs::TevStageConfig::ColorModifier modifier,
|
Pica::TexturingRegs::TevStageConfig::ColorModifier modifier,
|
||||||
Pica::TexturingRegs::TevStageConfig::Source source, u32 tev_index) {
|
Pica::TexturingRegs::TevStageConfig::Source source, u32 tev_index) {
|
||||||
|
using Source = Pica::TexturingRegs::TevStageConfig::Source;
|
||||||
using ColorModifier = Pica::TexturingRegs::TevStageConfig::ColorModifier;
|
using ColorModifier = Pica::TexturingRegs::TevStageConfig::ColorModifier;
|
||||||
|
const TexturingRegs::TevStageConfig stage = config.texture.tev_stages[tev_index];
|
||||||
|
const bool force_source3 = tev_index == 0 && source == Source::Previous;
|
||||||
|
const auto color_source =
|
||||||
|
GetSource(force_source3 ? stage.color_source3.Value() : source, tev_index);
|
||||||
switch (modifier) {
|
switch (modifier) {
|
||||||
case ColorModifier::SourceColor:
|
case ColorModifier::SourceColor:
|
||||||
AppendSource(source, tev_index);
|
out += fmt::format("{}.rgb", color_source);
|
||||||
out += ".rgb";
|
|
||||||
break;
|
break;
|
||||||
case ColorModifier::OneMinusSourceColor:
|
case ColorModifier::OneMinusSourceColor:
|
||||||
out += "vec3(1.0) - ";
|
out += fmt::format("vec3(1.0) - {}.rgb", color_source);
|
||||||
AppendSource(source, tev_index);
|
|
||||||
out += ".rgb";
|
|
||||||
break;
|
break;
|
||||||
case ColorModifier::SourceAlpha:
|
case ColorModifier::SourceAlpha:
|
||||||
AppendSource(source, tev_index);
|
out += fmt::format("{}.aaa", color_source);
|
||||||
out += ".aaa";
|
|
||||||
break;
|
break;
|
||||||
case ColorModifier::OneMinusSourceAlpha:
|
case ColorModifier::OneMinusSourceAlpha:
|
||||||
out += "vec3(1.0) - ";
|
out += fmt::format("vec3(1.0) - {}.aaa", color_source);
|
||||||
AppendSource(source, tev_index);
|
|
||||||
out += ".aaa";
|
|
||||||
break;
|
break;
|
||||||
case ColorModifier::SourceRed:
|
case ColorModifier::SourceRed:
|
||||||
AppendSource(source, tev_index);
|
out += fmt::format("{}.rrr", color_source);
|
||||||
out += ".rrr";
|
|
||||||
break;
|
break;
|
||||||
case ColorModifier::OneMinusSourceRed:
|
case ColorModifier::OneMinusSourceRed:
|
||||||
out += "vec3(1.0) - ";
|
out += fmt::format("vec3(1.0) - {}.rrr", color_source);
|
||||||
AppendSource(source, tev_index);
|
|
||||||
out += ".rrr";
|
|
||||||
break;
|
break;
|
||||||
case ColorModifier::SourceGreen:
|
case ColorModifier::SourceGreen:
|
||||||
AppendSource(source, tev_index);
|
out += fmt::format("{}.ggg", color_source);
|
||||||
out += ".ggg";
|
|
||||||
break;
|
break;
|
||||||
case ColorModifier::OneMinusSourceGreen:
|
case ColorModifier::OneMinusSourceGreen:
|
||||||
out += "vec3(1.0) - ";
|
out += fmt::format("vec3(1.0) - {}.ggg", color_source);
|
||||||
AppendSource(source, tev_index);
|
|
||||||
out += ".ggg";
|
|
||||||
break;
|
break;
|
||||||
case ColorModifier::SourceBlue:
|
case ColorModifier::SourceBlue:
|
||||||
AppendSource(source, tev_index);
|
out += fmt::format("{}.bbb", color_source);
|
||||||
out += ".bbb";
|
|
||||||
break;
|
break;
|
||||||
case ColorModifier::OneMinusSourceBlue:
|
case ColorModifier::OneMinusSourceBlue:
|
||||||
out += "vec3(1.0) - ";
|
out += fmt::format("vec3(1.0) - {}.bbb", color_source);
|
||||||
AppendSource(source, tev_index);
|
|
||||||
out += ".bbb";
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
out += "vec3(0.0)";
|
out += "vec3(0.0)";
|
||||||
|
@ -326,43 +305,36 @@ void FragmentModule::AppendColorModifier(
|
||||||
void FragmentModule::AppendAlphaModifier(
|
void FragmentModule::AppendAlphaModifier(
|
||||||
Pica::TexturingRegs::TevStageConfig::AlphaModifier modifier,
|
Pica::TexturingRegs::TevStageConfig::AlphaModifier modifier,
|
||||||
Pica::TexturingRegs::TevStageConfig::Source source, u32 tev_index) {
|
Pica::TexturingRegs::TevStageConfig::Source source, u32 tev_index) {
|
||||||
|
using Source = Pica::TexturingRegs::TevStageConfig::Source;
|
||||||
using AlphaModifier = Pica::TexturingRegs::TevStageConfig::AlphaModifier;
|
using AlphaModifier = Pica::TexturingRegs::TevStageConfig::AlphaModifier;
|
||||||
|
const TexturingRegs::TevStageConfig stage = config.texture.tev_stages[tev_index];
|
||||||
|
const bool force_source3 = tev_index == 0 && source == Source::Previous;
|
||||||
|
const auto alpha_source =
|
||||||
|
GetSource(force_source3 ? stage.alpha_source3.Value() : source, tev_index);
|
||||||
switch (modifier) {
|
switch (modifier) {
|
||||||
case AlphaModifier::SourceAlpha:
|
case AlphaModifier::SourceAlpha:
|
||||||
AppendSource(source, tev_index);
|
out += fmt::format("{}.a", alpha_source);
|
||||||
out += ".a";
|
|
||||||
break;
|
break;
|
||||||
case AlphaModifier::OneMinusSourceAlpha:
|
case AlphaModifier::OneMinusSourceAlpha:
|
||||||
out += "1.0 - ";
|
out += fmt::format("1.0 - {}.a", alpha_source);
|
||||||
AppendSource(source, tev_index);
|
|
||||||
out += ".a";
|
|
||||||
break;
|
break;
|
||||||
case AlphaModifier::SourceRed:
|
case AlphaModifier::SourceRed:
|
||||||
AppendSource(source, tev_index);
|
out += fmt::format("{}.r", alpha_source);
|
||||||
out += ".r";
|
|
||||||
break;
|
break;
|
||||||
case AlphaModifier::OneMinusSourceRed:
|
case AlphaModifier::OneMinusSourceRed:
|
||||||
out += "1.0 - ";
|
out += fmt::format("1.0 - {}.r", alpha_source);
|
||||||
AppendSource(source, tev_index);
|
|
||||||
out += ".r";
|
|
||||||
break;
|
break;
|
||||||
case AlphaModifier::SourceGreen:
|
case AlphaModifier::SourceGreen:
|
||||||
AppendSource(source, tev_index);
|
out += fmt::format("{}.g", alpha_source);
|
||||||
out += ".g";
|
|
||||||
break;
|
break;
|
||||||
case AlphaModifier::OneMinusSourceGreen:
|
case AlphaModifier::OneMinusSourceGreen:
|
||||||
out += "1.0 - ";
|
out += fmt::format("1.0 - {}.g", alpha_source);
|
||||||
AppendSource(source, tev_index);
|
|
||||||
out += ".g";
|
|
||||||
break;
|
break;
|
||||||
case AlphaModifier::SourceBlue:
|
case AlphaModifier::SourceBlue:
|
||||||
AppendSource(source, tev_index);
|
out += fmt::format("{}.b", alpha_source);
|
||||||
out += ".b";
|
|
||||||
break;
|
break;
|
||||||
case AlphaModifier::OneMinusSourceBlue:
|
case AlphaModifier::OneMinusSourceBlue:
|
||||||
out += "1.0 - ";
|
out += fmt::format("1.0 - {}.b", alpha_source);
|
||||||
AppendSource(source, tev_index);
|
|
||||||
out += ".b";
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
out += "0.0";
|
out += "0.0";
|
||||||
|
@ -384,12 +356,11 @@ void FragmentModule::AppendColorCombiner(Pica::TexturingRegs::TevStageConfig::Op
|
||||||
case Operation::AddSigned:
|
case Operation::AddSigned:
|
||||||
return "color_results_1 + color_results_2 - vec3(0.5)";
|
return "color_results_1 + color_results_2 - vec3(0.5)";
|
||||||
case Operation::Lerp:
|
case Operation::Lerp:
|
||||||
return "color_results_1 * color_results_3 + color_results_2 * (vec3(1.0) - "
|
return "mix(color_results_2, color_results_1, color_results_3)";
|
||||||
"color_results_3)";
|
|
||||||
case Operation::Subtract:
|
case Operation::Subtract:
|
||||||
return "color_results_1 - color_results_2";
|
return "color_results_1 - color_results_2";
|
||||||
case Operation::MultiplyThenAdd:
|
case Operation::MultiplyThenAdd:
|
||||||
return "color_results_1 * color_results_2 + color_results_3";
|
return "fma(color_results_1, color_results_2, color_results_3)";
|
||||||
case Operation::AddThenMultiply:
|
case Operation::AddThenMultiply:
|
||||||
return "min(color_results_1 + color_results_2, vec3(1.0)) * color_results_3";
|
return "min(color_results_1 + color_results_2, vec3(1.0)) * color_results_3";
|
||||||
case Operation::Dot3_RGB:
|
case Operation::Dot3_RGB:
|
||||||
|
@ -416,11 +387,11 @@ void FragmentModule::AppendAlphaCombiner(Pica::TexturingRegs::TevStageConfig::Op
|
||||||
case Operation::AddSigned:
|
case Operation::AddSigned:
|
||||||
return "alpha_results_1 + alpha_results_2 - 0.5";
|
return "alpha_results_1 + alpha_results_2 - 0.5";
|
||||||
case Operation::Lerp:
|
case Operation::Lerp:
|
||||||
return "alpha_results_1 * alpha_results_3 + alpha_results_2 * (1.0 - alpha_results_3)";
|
return "mix(alpha_results_2, alpha_results_1, alpha_results_3)";
|
||||||
case Operation::Subtract:
|
case Operation::Subtract:
|
||||||
return "alpha_results_1 - alpha_results_2";
|
return "alpha_results_1 - alpha_results_2";
|
||||||
case Operation::MultiplyThenAdd:
|
case Operation::MultiplyThenAdd:
|
||||||
return "alpha_results_1 * alpha_results_2 + alpha_results_3";
|
return "fma(alpha_results_1, alpha_results_2, alpha_results_3)";
|
||||||
case Operation::AddThenMultiply:
|
case Operation::AddThenMultiply:
|
||||||
return "min(alpha_results_1 + alpha_results_2, 1.0) * alpha_results_3";
|
return "min(alpha_results_1 + alpha_results_2, 1.0) * alpha_results_3";
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -41,8 +41,8 @@ private:
|
||||||
/// Writes the code to emulate PICA min/max blending factors
|
/// Writes the code to emulate PICA min/max blending factors
|
||||||
void WriteBlending();
|
void WriteBlending();
|
||||||
|
|
||||||
/// Writes the specified TEV stage source component(s)
|
/// Returns the specified TEV stage source component(s)
|
||||||
void AppendSource(Pica::TexturingRegs::TevStageConfig::Source source, u32 tev_index);
|
std::string GetSource(Pica::TexturingRegs::TevStageConfig::Source source, u32 tev_index);
|
||||||
|
|
||||||
/// Writes the color components to use for the specified TEV stage color modifier
|
/// Writes the color components to use for the specified TEV stage color modifier
|
||||||
void AppendColorModifier(Pica::TexturingRegs::TevStageConfig::ColorModifier modifier,
|
void AppendColorModifier(Pica::TexturingRegs::TevStageConfig::ColorModifier modifier,
|
||||||
|
|
|
@ -86,7 +86,7 @@ struct PicaUniformsData {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VSUniformData {
|
struct VSUniformData {
|
||||||
bool enable_clip1;
|
u32 enable_clip1;
|
||||||
alignas(16) Common::Vec4f clip_coef;
|
alignas(16) Common::Vec4f clip_coef;
|
||||||
};
|
};
|
||||||
static_assert(sizeof(VSUniformData) == 32,
|
static_assert(sizeof(VSUniformData) == 32,
|
||||||
|
|
|
@ -55,7 +55,7 @@ void FragmentModule::Generate() {
|
||||||
|
|
||||||
combiner_buffer = ConstF32(0.f, 0.f, 0.f, 0.f);
|
combiner_buffer = ConstF32(0.f, 0.f, 0.f, 0.f);
|
||||||
next_combiner_buffer = GetShaderDataMember(vec_ids.Get(4), ConstS32(26));
|
next_combiner_buffer = GetShaderDataMember(vec_ids.Get(4), ConstS32(26));
|
||||||
last_tex_env_out = rounded_primary_color;
|
combiner_output = ConstF32(0.f, 0.f, 0.f, 0.f);
|
||||||
|
|
||||||
// Write shader bytecode to emulate PICA TEV stages
|
// Write shader bytecode to emulate PICA TEV stages
|
||||||
for (u32 index = 0; index < config.texture.tev_stages.size(); ++index) {
|
for (u32 index = 0; index < config.texture.tev_stages.size(); ++index) {
|
||||||
|
@ -76,7 +76,7 @@ void FragmentModule::Generate() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Id color{Byteround(last_tex_env_out, 4)};
|
Id color{Byteround(combiner_output, 4)};
|
||||||
switch (config.framebuffer.logic_op) {
|
switch (config.framebuffer.logic_op) {
|
||||||
case FramebufferRegs::LogicOp::Clear:
|
case FramebufferRegs::LogicOp::Clear:
|
||||||
color = ConstF32(0.f, 0.f, 0.f, 0.f);
|
color = ConstF32(0.f, 0.f, 0.f, 0.f);
|
||||||
|
@ -184,12 +184,12 @@ void FragmentModule::WriteFog() {
|
||||||
|
|
||||||
// Blend the fog
|
// Blend the fog
|
||||||
const Id tex_env_rgb{
|
const Id tex_env_rgb{
|
||||||
OpVectorShuffle(vec_ids.Get(3), last_tex_env_out, last_tex_env_out, 0, 1, 2)};
|
OpVectorShuffle(vec_ids.Get(3), combiner_output, combiner_output, 0, 1, 2)};
|
||||||
const Id fog_color{GetShaderDataMember(vec_ids.Get(3), ConstS32(19))};
|
const Id fog_color{GetShaderDataMember(vec_ids.Get(3), ConstS32(19))};
|
||||||
const Id fog_factor_rgb{
|
const Id fog_factor_rgb{
|
||||||
OpCompositeConstruct(vec_ids.Get(3), fog_factor, fog_factor, fog_factor)};
|
OpCompositeConstruct(vec_ids.Get(3), fog_factor, fog_factor, fog_factor)};
|
||||||
const Id fog_result{OpFMix(vec_ids.Get(3), fog_color, tex_env_rgb, fog_factor_rgb)};
|
const Id fog_result{OpFMix(vec_ids.Get(3), fog_color, tex_env_rgb, fog_factor_rgb)};
|
||||||
last_tex_env_out = OpVectorShuffle(vec_ids.Get(4), fog_result, last_tex_env_out, 0, 1, 2, 6);
|
combiner_output = OpVectorShuffle(vec_ids.Get(4), fog_result, combiner_output, 0, 1, 2, 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FragmentModule::WriteGas() {
|
void FragmentModule::WriteGas() {
|
||||||
|
@ -630,8 +630,7 @@ void FragmentModule::WriteLighting() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FragmentModule::WriteTevStage(s32 index) {
|
void FragmentModule::WriteTevStage(s32 index) {
|
||||||
const TexturingRegs::TevStageConfig stage =
|
const TexturingRegs::TevStageConfig stage = config.texture.tev_stages[index];
|
||||||
static_cast<const TexturingRegs::TevStageConfig>(config.texture.tev_stages[index]);
|
|
||||||
|
|
||||||
// Detects if a TEV stage is configured to be skipped (to avoid generating unnecessary code)
|
// Detects if a TEV stage is configured to be skipped (to avoid generating unnecessary code)
|
||||||
const auto is_passthrough_tev_stage = [](const TevStageConfig& stage) {
|
const auto is_passthrough_tev_stage = [](const TevStageConfig& stage) {
|
||||||
|
@ -674,18 +673,18 @@ void FragmentModule::WriteTevStage(s32 index) {
|
||||||
alpha_output =
|
alpha_output =
|
||||||
OpFMul(f32_id, alpha_output, ConstF32(static_cast<float>(stage.GetAlphaMultiplier())));
|
OpFMul(f32_id, alpha_output, ConstF32(static_cast<float>(stage.GetAlphaMultiplier())));
|
||||||
alpha_output = OpFClamp(f32_id, alpha_output, ConstF32(0.f), ConstF32(1.f));
|
alpha_output = OpFClamp(f32_id, alpha_output, ConstF32(0.f), ConstF32(1.f));
|
||||||
last_tex_env_out = OpCompositeConstruct(vec_ids.Get(4), color_output, alpha_output);
|
combiner_output = OpCompositeConstruct(vec_ids.Get(4), color_output, alpha_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
combiner_buffer = next_combiner_buffer;
|
combiner_buffer = next_combiner_buffer;
|
||||||
if (config.TevStageUpdatesCombinerBufferColor(index)) {
|
if (config.TevStageUpdatesCombinerBufferColor(index)) {
|
||||||
next_combiner_buffer =
|
next_combiner_buffer =
|
||||||
OpVectorShuffle(vec_ids.Get(4), last_tex_env_out, next_combiner_buffer, 0, 1, 2, 7);
|
OpVectorShuffle(vec_ids.Get(4), combiner_output, next_combiner_buffer, 0, 1, 2, 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.TevStageUpdatesCombinerBufferAlpha(index)) {
|
if (config.TevStageUpdatesCombinerBufferAlpha(index)) {
|
||||||
next_combiner_buffer =
|
next_combiner_buffer =
|
||||||
OpVectorShuffle(vec_ids.Get(4), next_combiner_buffer, last_tex_env_out, 0, 1, 2, 7);
|
OpVectorShuffle(vec_ids.Get(4), next_combiner_buffer, combiner_output, 0, 1, 2, 7);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -728,7 +727,7 @@ void FragmentModule::WriteAlphaTestCondition(FramebufferRegs::CompareFunc func)
|
||||||
case CompareFunc::GreaterThan:
|
case CompareFunc::GreaterThan:
|
||||||
case CompareFunc::GreaterThanOrEqual: {
|
case CompareFunc::GreaterThanOrEqual: {
|
||||||
const Id alpha_scaled{
|
const Id alpha_scaled{
|
||||||
OpFMul(f32_id, OpCompositeExtract(f32_id, last_tex_env_out, 3), ConstF32(255.f))};
|
OpFMul(f32_id, OpCompositeExtract(f32_id, combiner_output, 3), ConstF32(255.f))};
|
||||||
const Id alpha_int{OpConvertFToS(i32_id, alpha_scaled)};
|
const Id alpha_int{OpConvertFToS(i32_id, alpha_scaled)};
|
||||||
const Id alphatest_ref{GetShaderDataMember(i32_id, ConstS32(1))};
|
const Id alphatest_ref{GetShaderDataMember(i32_id, ConstS32(1))};
|
||||||
const Id alpha_comp_ref{compare(alpha_int, alphatest_ref)};
|
const Id alpha_comp_ref{compare(alpha_int, alphatest_ref)};
|
||||||
|
@ -1280,7 +1279,7 @@ Id FragmentModule::LookupLightingLUT(Id lut_index, Id index, Id delta) {
|
||||||
return OpFma(f32_id, entry_g, delta, entry_r);
|
return OpFma(f32_id, entry_g, delta, entry_r);
|
||||||
}
|
}
|
||||||
|
|
||||||
Id FragmentModule::AppendSource(TevStageConfig::Source source, s32 index) {
|
Id FragmentModule::GetSource(TevStageConfig::Source source, s32 index) {
|
||||||
using Source = TevStageConfig::Source;
|
using Source = TevStageConfig::Source;
|
||||||
switch (source) {
|
switch (source) {
|
||||||
case Source::PrimaryColor:
|
case Source::PrimaryColor:
|
||||||
|
@ -1302,7 +1301,7 @@ Id FragmentModule::AppendSource(TevStageConfig::Source source, s32 index) {
|
||||||
case Source::Constant:
|
case Source::Constant:
|
||||||
return GetShaderDataMember(vec_ids.Get(4), ConstS32(25), ConstS32(index));
|
return GetShaderDataMember(vec_ids.Get(4), ConstS32(25), ConstS32(index));
|
||||||
case Source::Previous:
|
case Source::Previous:
|
||||||
return last_tex_env_out;
|
return combiner_output;
|
||||||
default:
|
default:
|
||||||
LOG_CRITICAL(Render, "Unknown source op {}", source);
|
LOG_CRITICAL(Render, "Unknown source op {}", source);
|
||||||
return ConstF32(0.f, 0.f, 0.f, 0.f);
|
return ConstF32(0.f, 0.f, 0.f, 0.f);
|
||||||
|
@ -1311,8 +1310,11 @@ Id FragmentModule::AppendSource(TevStageConfig::Source source, s32 index) {
|
||||||
|
|
||||||
Id FragmentModule::AppendColorModifier(TevStageConfig::ColorModifier modifier,
|
Id FragmentModule::AppendColorModifier(TevStageConfig::ColorModifier modifier,
|
||||||
TevStageConfig::Source source, s32 index) {
|
TevStageConfig::Source source, s32 index) {
|
||||||
|
using Source = TevStageConfig::Source;
|
||||||
using ColorModifier = TevStageConfig::ColorModifier;
|
using ColorModifier = TevStageConfig::ColorModifier;
|
||||||
const Id source_color{AppendSource(source, index)};
|
const TexturingRegs::TevStageConfig stage = config.texture.tev_stages[index];
|
||||||
|
const bool force_source3 = index == 0 && source == Source::Previous;
|
||||||
|
const Id source_color{GetSource(force_source3 ? stage.color_source3.Value() : source, index)};
|
||||||
const Id one_vec{ConstF32(1.f, 1.f, 1.f)};
|
const Id one_vec{ConstF32(1.f, 1.f, 1.f)};
|
||||||
|
|
||||||
const auto shuffle = [&](s32 r, s32 g, s32 b) -> Id {
|
const auto shuffle = [&](s32 r, s32 g, s32 b) -> Id {
|
||||||
|
@ -1348,11 +1350,14 @@ Id FragmentModule::AppendColorModifier(TevStageConfig::ColorModifier modifier,
|
||||||
|
|
||||||
Id FragmentModule::AppendAlphaModifier(TevStageConfig::AlphaModifier modifier,
|
Id FragmentModule::AppendAlphaModifier(TevStageConfig::AlphaModifier modifier,
|
||||||
TevStageConfig::Source source, s32 index) {
|
TevStageConfig::Source source, s32 index) {
|
||||||
|
using Source = TevStageConfig::Source;
|
||||||
using AlphaModifier = TevStageConfig::AlphaModifier;
|
using AlphaModifier = TevStageConfig::AlphaModifier;
|
||||||
const Id source_color{AppendSource(source, index)};
|
const TexturingRegs::TevStageConfig stage = config.texture.tev_stages[index];
|
||||||
|
const bool force_source3 = index == 0 && source == Source::Previous;
|
||||||
|
const Id source_alpha{GetSource(force_source3 ? stage.alpha_source3.Value() : source, index)};
|
||||||
const Id one_f32{ConstF32(1.f)};
|
const Id one_f32{ConstF32(1.f)};
|
||||||
|
|
||||||
const auto component = [&](s32 c) -> Id { return OpCompositeExtract(f32_id, source_color, c); };
|
const auto component = [&](s32 c) -> Id { return OpCompositeExtract(f32_id, source_alpha, c); };
|
||||||
|
|
||||||
switch (modifier) {
|
switch (modifier) {
|
||||||
case AlphaModifier::SourceAlpha:
|
case AlphaModifier::SourceAlpha:
|
||||||
|
|
|
@ -99,13 +99,13 @@ private:
|
||||||
/// Lookups the lighting LUT at the provided lut_index
|
/// Lookups the lighting LUT at the provided lut_index
|
||||||
[[nodiscard]] Id LookupLightingLUT(Id lut_index, Id index, Id delta);
|
[[nodiscard]] Id LookupLightingLUT(Id lut_index, Id index, Id delta);
|
||||||
|
|
||||||
/// Writes the specified TEV stage source component(s)
|
/// Returns the specified TEV stage source component(s)
|
||||||
[[nodiscard]] Id AppendSource(Pica::TexturingRegs::TevStageConfig::Source source, s32 index);
|
[[nodiscard]] Id GetSource(Pica::TexturingRegs::TevStageConfig::Source source, s32 index);
|
||||||
|
|
||||||
/// Writes the color components to use for the specified TEV stage color modifier
|
/// Writes the color components to use for the specified TEV stage color modifier
|
||||||
[[nodiscard]] Id AppendColorModifier(
|
[[nodiscard]] Id AppendColorModifier(
|
||||||
Pica::TexturingRegs::TevStageConfig::ColorModifier modifier,
|
Pica::TexturingRegs::TevStageConfig::ColorModifier modifier,
|
||||||
Pica::TexturingRegs::TevStageConfig::Source source, s32 index);
|
Pica::TexturingRegs::TevStageConfig::Source source, s32 tev_index);
|
||||||
|
|
||||||
/// Writes the alpha component to use for the specified TEV stage alpha modifier
|
/// Writes the alpha component to use for the specified TEV stage alpha modifier
|
||||||
[[nodiscard]] Id AppendAlphaModifier(
|
[[nodiscard]] Id AppendAlphaModifier(
|
||||||
|
@ -272,7 +272,7 @@ private:
|
||||||
Id secondary_fragment_color{};
|
Id secondary_fragment_color{};
|
||||||
Id combiner_buffer{};
|
Id combiner_buffer{};
|
||||||
Id next_combiner_buffer{};
|
Id next_combiner_buffer{};
|
||||||
Id last_tex_env_out{};
|
Id combiner_output{};
|
||||||
|
|
||||||
Id color_results_1{};
|
Id color_results_1{};
|
||||||
Id color_results_2{};
|
Id color_results_2{};
|
||||||
|
|
Loading…
Reference in a new issue