mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-12 09:09:47 +12:00
Remove dependency of PICA regs in fragment config
This commit is contained in:
parent
eb7e02fbc2
commit
ce4146f9ba
4 changed files with 90 additions and 90 deletions
|
@ -81,6 +81,11 @@ namespace PICA {
|
|||
LightingLUTConfig rg{};
|
||||
LightingLUTConfig rb{};
|
||||
|
||||
u32 config1;
|
||||
u32 lutAbs;
|
||||
u32 lutScale;
|
||||
u32 lutSelect;
|
||||
|
||||
std::array<Light, 8> lights{};
|
||||
|
||||
LightingConfig(const std::array<u32, 0x300>& regs) {
|
||||
|
@ -90,9 +95,13 @@ namespace PICA {
|
|||
}
|
||||
|
||||
const u32 config0 = regs[InternalRegs::LightConfig0];
|
||||
const u32 config1 = regs[InternalRegs::LightConfig1];
|
||||
const u32 totalLightCount = Helpers::getBits<0, 3>(regs[InternalRegs::LightNumber]) + 1;
|
||||
|
||||
config1 = regs[InternalRegs::LightConfig1];
|
||||
lutAbs = regs[InternalRegs::LightLUTAbs];
|
||||
lutScale = regs[InternalRegs::LightLUTScale];
|
||||
lutSelect = regs[InternalRegs::LightLUTSelect];
|
||||
|
||||
enable = 1;
|
||||
lightNum = totalLightCount;
|
||||
|
||||
|
@ -195,7 +204,31 @@ namespace PICA {
|
|||
return std::memcmp(this, &config, sizeof(FragmentConfig)) == 0;
|
||||
}
|
||||
|
||||
FragmentConfig(const std::array<u32, 0x300>& regs) : lighting(regs) {}
|
||||
FragmentConfig(const std::array<u32, 0x300>& regs) : lighting(regs)
|
||||
{
|
||||
auto alphaTestConfig = regs[InternalRegs::AlphaTestConfig];
|
||||
auto alphaTestFunction = Helpers::getBits<4, 3>(alphaTestConfig);
|
||||
|
||||
outConfig.alphaTestFunction = (alphaTestConfig & 1) ? static_cast<PICA::CompareFunction>(alphaTestFunction) : PICA::CompareFunction::Always;
|
||||
outConfig.depthMapEnable = regs[InternalRegs::DepthmapEnable] & 1;
|
||||
|
||||
texConfig.texUnitConfig = regs[InternalRegs::TexUnitCfg];
|
||||
texConfig.texEnvUpdateBuffer = regs[InternalRegs::TexEnvUpdateBuffer];
|
||||
|
||||
// Set up TEV stages. Annoyingly we can't just memcpy as the TEV registers are arranged like
|
||||
// {Source, Operand, Combiner, Color, Scale} and we want to skip the color register since it's uploaded via UBO
|
||||
#define setupTevStage(stage) \
|
||||
std::memcpy(&texConfig.tevConfigs[stage * 4], ®s[InternalRegs::TexEnv##stage##Source], 3 * sizeof(u32)); \
|
||||
texConfig.tevConfigs[stage * 4 + 3] = regs[InternalRegs::TexEnv##stage##Source + 5];
|
||||
|
||||
setupTevStage(0);
|
||||
setupTevStage(1);
|
||||
setupTevStage(2);
|
||||
setupTevStage(3);
|
||||
setupTevStage(4);
|
||||
setupTevStage(5);
|
||||
#undef setupTevStage
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(
|
||||
|
|
|
@ -14,27 +14,24 @@ namespace PICA::ShaderGen {
|
|||
enum class Language { GLSL };
|
||||
|
||||
class FragmentGenerator {
|
||||
using PICARegs = std::array<u32, 0x300>;
|
||||
API api;
|
||||
Language language;
|
||||
|
||||
void compileTEV(std::string& shader, int stage, const PICARegs& regs);
|
||||
void getSource(std::string& shader, PICA::TexEnvConfig::Source source, int index);
|
||||
void getColorOperand(std::string& shader, PICA::TexEnvConfig::Source source, PICA::TexEnvConfig::ColorOperand color, int index);
|
||||
void getAlphaOperand(std::string& shader, PICA::TexEnvConfig::Source source, PICA::TexEnvConfig::AlphaOperand alpha, int index);
|
||||
void compileTEV(std::string& shader, int stage, const PICA::FragmentConfig& config);
|
||||
void getSource(std::string& shader, PICA::TexEnvConfig::Source source, int index, const PICA::FragmentConfig& config);
|
||||
void getColorOperand(std::string& shader, PICA::TexEnvConfig::Source source, PICA::TexEnvConfig::ColorOperand color, int index, const PICA::FragmentConfig& config);
|
||||
void getAlphaOperand(std::string& shader, PICA::TexEnvConfig::Source source, PICA::TexEnvConfig::AlphaOperand alpha, int index, const PICA::FragmentConfig& config);
|
||||
void getColorOperation(std::string& shader, PICA::TexEnvConfig::Operation op);
|
||||
void getAlphaOperation(std::string& shader, PICA::TexEnvConfig::Operation op);
|
||||
|
||||
void applyAlphaTest(std::string& shader, const PICARegs& regs);
|
||||
void compileLights(std::string& shader, const PICA::FragmentConfig& config, const PICARegs& regs);
|
||||
void compileLUTLookup(std::string& shader, const PICA::FragmentConfig& config, const PICARegs& regs, u32 lightIndex, u32 lutID);
|
||||
void applyAlphaTest(std::string& shader, const PICA::FragmentConfig& config);
|
||||
void compileLights(std::string& shader, const PICA::FragmentConfig& config);
|
||||
void compileLUTLookup(std::string& shader, const PICA::FragmentConfig& config, u32 lightIndex, u32 lutID);
|
||||
bool isSamplerEnabled(u32 environmentID, u32 lutID);
|
||||
|
||||
u32 textureConfig = 0;
|
||||
|
||||
public:
|
||||
FragmentGenerator(API api, Language language) : api(api), language(language) {}
|
||||
std::string generate(const PICARegs& regs, const PICA::FragmentConfig& config);
|
||||
std::string generate(const PICA::FragmentConfig& config);
|
||||
std::string getDefaultVertexShader();
|
||||
|
||||
void setTarget(API api, Language language) {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include "PICA/regs.hpp"
|
||||
#include "PICA/shader_gen.hpp"
|
||||
using namespace PICA;
|
||||
using namespace PICA::ShaderGen;
|
||||
|
@ -101,7 +102,7 @@ std::string FragmentGenerator::getDefaultVertexShader() {
|
|||
return ret;
|
||||
}
|
||||
|
||||
std::string FragmentGenerator::generate(const PICARegs& regs, const FragmentConfig& config) {
|
||||
std::string FragmentGenerator::generate(const FragmentConfig& config) {
|
||||
std::string ret = "";
|
||||
|
||||
switch (api) {
|
||||
|
@ -168,7 +169,7 @@ std::string FragmentGenerator::generate(const PICARegs& regs, const FragmentConf
|
|||
vec4 secondaryColor = vec4(0.0);
|
||||
)";
|
||||
|
||||
compileLights(ret, config, regs);
|
||||
compileLights(ret, config);
|
||||
|
||||
ret += R"(
|
||||
vec3 colorOp1 = vec3(0.0);
|
||||
|
@ -187,44 +188,39 @@ std::string FragmentGenerator::generate(const PICARegs& regs, const FragmentConf
|
|||
float depth = z_over_w * depthScale + depthOffset;
|
||||
)";
|
||||
|
||||
if ((regs[InternalRegs::DepthmapEnable] & 1) == 0) {
|
||||
if (!config.outConfig.depthMapEnable) {
|
||||
ret += "depth /= gl_FragCoord.w;\n";
|
||||
}
|
||||
|
||||
ret += "gl_FragDepth = depth;\n";
|
||||
|
||||
textureConfig = regs[InternalRegs::TexUnitCfg];
|
||||
for (int i = 0; i < 6; i++) {
|
||||
compileTEV(ret, i, regs);
|
||||
compileTEV(ret, i, config);
|
||||
}
|
||||
|
||||
applyAlphaTest(ret, regs);
|
||||
applyAlphaTest(ret, config);
|
||||
|
||||
ret += "fragColor = combinerOutput;\n}"; // End of main function
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void FragmentGenerator::compileTEV(std::string& shader, int stage, const PICARegs& regs) {
|
||||
// Base address for each TEV stage's configuration
|
||||
static constexpr std::array<u32, 6> ioBases = {
|
||||
InternalRegs::TexEnv0Source, InternalRegs::TexEnv1Source, InternalRegs::TexEnv2Source,
|
||||
InternalRegs::TexEnv3Source, InternalRegs::TexEnv4Source, InternalRegs::TexEnv5Source,
|
||||
};
|
||||
void FragmentGenerator::compileTEV(std::string& shader, int stage, const PICA::FragmentConfig& config) {
|
||||
const u32* tevValues = config.texConfig.tevConfigs.data() + stage * 4;
|
||||
|
||||
const u32 ioBase = ioBases[stage];
|
||||
TexEnvConfig tev(regs[ioBase], regs[ioBase + 1], regs[ioBase + 2], regs[ioBase + 3], regs[ioBase + 4]);
|
||||
// Pass a 0 to constColor here, as it doesn't matter for compilation
|
||||
TexEnvConfig tev(tevValues[0], tevValues[1], tevValues[2], 0, tevValues[3]);
|
||||
|
||||
if (!tev.isPassthroughStage()) {
|
||||
// Get color operands
|
||||
shader += "colorOp1 = ";
|
||||
getColorOperand(shader, tev.colorSource1, tev.colorOperand1, stage);
|
||||
getColorOperand(shader, tev.colorSource1, tev.colorOperand1, stage, config);
|
||||
|
||||
shader += ";\ncolorOp2 = ";
|
||||
getColorOperand(shader, tev.colorSource2, tev.colorOperand2, stage);
|
||||
getColorOperand(shader, tev.colorSource2, tev.colorOperand2, stage, config);
|
||||
|
||||
shader += ";\ncolorOp3 = ";
|
||||
getColorOperand(shader, tev.colorSource3, tev.colorOperand3, stage);
|
||||
getColorOperand(shader, tev.colorSource3, tev.colorOperand3, stage, config);
|
||||
|
||||
shader += ";\nvec3 outputColor" + std::to_string(stage) + " = clamp(";
|
||||
getColorOperation(shader, tev.colorOp);
|
||||
|
@ -236,13 +232,13 @@ void FragmentGenerator::compileTEV(std::string& shader, int stage, const PICAReg
|
|||
} else {
|
||||
// Get alpha operands
|
||||
shader += "alphaOp1 = ";
|
||||
getAlphaOperand(shader, tev.alphaSource1, tev.alphaOperand1, stage);
|
||||
getAlphaOperand(shader, tev.alphaSource1, tev.alphaOperand1, stage, config);
|
||||
|
||||
shader += ";\nalphaOp2 = ";
|
||||
getAlphaOperand(shader, tev.alphaSource2, tev.alphaOperand2, stage);
|
||||
getAlphaOperand(shader, tev.alphaSource2, tev.alphaOperand2, stage, config);
|
||||
|
||||
shader += ";\nalphaOp3 = ";
|
||||
getAlphaOperand(shader, tev.alphaSource3, tev.alphaOperand3, stage);
|
||||
getAlphaOperand(shader, tev.alphaSource3, tev.alphaOperand3, stage, config);
|
||||
|
||||
shader += ";\nfloat outputAlpha" + std::to_string(stage) + " = clamp(";
|
||||
getAlphaOperation(shader, tev.alphaOp);
|
||||
|
@ -258,7 +254,7 @@ void FragmentGenerator::compileTEV(std::string& shader, int stage, const PICAReg
|
|||
shader += "previousBuffer = tevNextPreviousBuffer;\n\n";
|
||||
|
||||
// Update the "next previous buffer" if necessary
|
||||
const u32 textureEnvUpdateBuffer = regs[InternalRegs::TexEnvUpdateBuffer];
|
||||
const u32 textureEnvUpdateBuffer = config.texConfig.texEnvUpdateBuffer;
|
||||
if (stage < 4) {
|
||||
// Check whether to update rgb
|
||||
if ((textureEnvUpdateBuffer & (0x100 << stage))) {
|
||||
|
@ -272,7 +268,7 @@ void FragmentGenerator::compileTEV(std::string& shader, int stage, const PICAReg
|
|||
}
|
||||
}
|
||||
|
||||
void FragmentGenerator::getColorOperand(std::string& shader, TexEnvConfig::Source source, TexEnvConfig::ColorOperand color, int index) {
|
||||
void FragmentGenerator::getColorOperand(std::string& shader, TexEnvConfig::Source source, TexEnvConfig::ColorOperand color, int index, const PICA::FragmentConfig& config) {
|
||||
using OperandType = TexEnvConfig::ColorOperand;
|
||||
|
||||
// For inverting operands, add the 1.0 - x subtraction
|
||||
|
@ -284,31 +280,31 @@ void FragmentGenerator::getColorOperand(std::string& shader, TexEnvConfig::Sourc
|
|||
switch (color) {
|
||||
case OperandType::SourceColor:
|
||||
case OperandType::OneMinusSourceColor:
|
||||
getSource(shader, source, index);
|
||||
getSource(shader, source, index, config);
|
||||
shader += ".rgb";
|
||||
break;
|
||||
|
||||
case OperandType::SourceRed:
|
||||
case OperandType::OneMinusSourceRed:
|
||||
getSource(shader, source, index);
|
||||
getSource(shader, source, index, config);
|
||||
shader += ".rrr";
|
||||
break;
|
||||
|
||||
case OperandType::SourceGreen:
|
||||
case OperandType::OneMinusSourceGreen:
|
||||
getSource(shader, source, index);
|
||||
getSource(shader, source, index, config);
|
||||
shader += ".ggg";
|
||||
break;
|
||||
|
||||
case OperandType::SourceBlue:
|
||||
case OperandType::OneMinusSourceBlue:
|
||||
getSource(shader, source, index);
|
||||
getSource(shader, source, index, config);
|
||||
shader += ".bbb";
|
||||
break;
|
||||
|
||||
case OperandType::SourceAlpha:
|
||||
case OperandType::OneMinusSourceAlpha:
|
||||
getSource(shader, source, index);
|
||||
getSource(shader, source, index, config);
|
||||
shader += ".aaa";
|
||||
break;
|
||||
|
||||
|
@ -319,7 +315,7 @@ void FragmentGenerator::getColorOperand(std::string& shader, TexEnvConfig::Sourc
|
|||
}
|
||||
}
|
||||
|
||||
void FragmentGenerator::getAlphaOperand(std::string& shader, TexEnvConfig::Source source, TexEnvConfig::AlphaOperand color, int index) {
|
||||
void FragmentGenerator::getAlphaOperand(std::string& shader, TexEnvConfig::Source source, TexEnvConfig::AlphaOperand color, int index, const PICA::FragmentConfig& config) {
|
||||
using OperandType = TexEnvConfig::AlphaOperand;
|
||||
|
||||
// For inverting operands, add the 1.0 - x subtraction
|
||||
|
@ -331,25 +327,25 @@ void FragmentGenerator::getAlphaOperand(std::string& shader, TexEnvConfig::Sourc
|
|||
switch (color) {
|
||||
case OperandType::SourceRed:
|
||||
case OperandType::OneMinusSourceRed:
|
||||
getSource(shader, source, index);
|
||||
getSource(shader, source, index, config);
|
||||
shader += ".r";
|
||||
break;
|
||||
|
||||
case OperandType::SourceGreen:
|
||||
case OperandType::OneMinusSourceGreen:
|
||||
getSource(shader, source, index);
|
||||
getSource(shader, source, index, config);
|
||||
shader += ".g";
|
||||
break;
|
||||
|
||||
case OperandType::SourceBlue:
|
||||
case OperandType::OneMinusSourceBlue:
|
||||
getSource(shader, source, index);
|
||||
getSource(shader, source, index, config);
|
||||
shader += ".b";
|
||||
break;
|
||||
|
||||
case OperandType::SourceAlpha:
|
||||
case OperandType::OneMinusSourceAlpha:
|
||||
getSource(shader, source, index);
|
||||
getSource(shader, source, index, config);
|
||||
shader += ".a";
|
||||
break;
|
||||
|
||||
|
@ -360,14 +356,14 @@ void FragmentGenerator::getAlphaOperand(std::string& shader, TexEnvConfig::Sourc
|
|||
}
|
||||
}
|
||||
|
||||
void FragmentGenerator::getSource(std::string& shader, TexEnvConfig::Source source, int index) {
|
||||
void FragmentGenerator::getSource(std::string& shader, TexEnvConfig::Source source, int index, const PICA::FragmentConfig& config) {
|
||||
switch (source) {
|
||||
case TexEnvConfig::Source::PrimaryColor: shader += "v_colour"; break;
|
||||
case TexEnvConfig::Source::Texture0: shader += "texture(u_tex0, v_texcoord0.xy)"; break;
|
||||
case TexEnvConfig::Source::Texture1: shader += "texture(u_tex1, v_texcoord1)"; break;
|
||||
case TexEnvConfig::Source::Texture2: {
|
||||
// If bit 13 in texture config is set then we use the texcoords for texture 1, otherwise for texture 2
|
||||
if (Helpers::getBit<13>(textureConfig)) {
|
||||
if (Helpers::getBit<13>(config.texConfig.texUnitConfig)) {
|
||||
shader += "texture(u_tex2, v_texcoord1)";
|
||||
} else {
|
||||
shader += "texture(u_tex2, v_texcoord2)";
|
||||
|
@ -428,12 +424,11 @@ void FragmentGenerator::getAlphaOperation(std::string& shader, TexEnvConfig::Ope
|
|||
}
|
||||
}
|
||||
|
||||
void FragmentGenerator::applyAlphaTest(std::string& shader, const PICARegs& regs) {
|
||||
const u32 alphaConfig = regs[InternalRegs::AlphaTestConfig];
|
||||
const auto function = static_cast<CompareFunction>(Helpers::getBits<4, 3>(alphaConfig));
|
||||
void FragmentGenerator::applyAlphaTest(std::string& shader, const PICA::FragmentConfig& config) {
|
||||
const CompareFunction function = config.outConfig.alphaTestFunction;
|
||||
|
||||
// Alpha test disabled
|
||||
if (Helpers::getBit<0>(alphaConfig) == 0 || function == CompareFunction::Always) {
|
||||
if (function == CompareFunction::Always) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -458,7 +453,7 @@ void FragmentGenerator::applyAlphaTest(std::string& shader, const PICARegs& regs
|
|||
shader += ") { discard; }\n";
|
||||
}
|
||||
|
||||
void FragmentGenerator::compileLights(std::string& shader, const PICA::FragmentConfig& config, const PICARegs& regs) {
|
||||
void FragmentGenerator::compileLights(std::string& shader, const PICA::FragmentConfig& config) {
|
||||
if (!config.lighting.enable) {
|
||||
return;
|
||||
}
|
||||
|
@ -516,27 +511,27 @@ void FragmentGenerator::compileLights(std::string& shader, const PICA::FragmentC
|
|||
", int(clamp(floor(distance_att_delta * 256.0), 0.0, 255.0)));\n";
|
||||
}
|
||||
|
||||
compileLUTLookup(shader, config, regs, lightID, spotlightLutIndex);
|
||||
compileLUTLookup(shader, config, lightID, spotlightLutIndex);
|
||||
shader += "spotlight_attenuation = lut_lookup_result;\n";
|
||||
|
||||
compileLUTLookup(shader, config, regs, lightID, PICA::Lights::LUT_D0);
|
||||
compileLUTLookup(shader, config, lightID, PICA::Lights::LUT_D0);
|
||||
shader += "specular0_dist = lut_lookup_result;\n";
|
||||
|
||||
compileLUTLookup(shader, config, regs, lightID, PICA::Lights::LUT_D1);
|
||||
compileLUTLookup(shader, config, lightID, PICA::Lights::LUT_D1);
|
||||
shader += "specular1_dist = lut_lookup_result;\n";
|
||||
|
||||
compileLUTLookup(shader, config, regs, lightID, PICA::Lights::LUT_RR);
|
||||
compileLUTLookup(shader, config, lightID, PICA::Lights::LUT_RR);
|
||||
shader += "reflected_color.r = lut_lookup_result;\n";
|
||||
|
||||
if (isSamplerEnabled(config.lighting.config, PICA::Lights::LUT_RG)) {
|
||||
compileLUTLookup(shader, config, regs, lightID, PICA::Lights::LUT_RG);
|
||||
compileLUTLookup(shader, config, lightID, PICA::Lights::LUT_RG);
|
||||
shader += "reflected_color.g = lut_lookup_result;\n";
|
||||
} else {
|
||||
shader += "reflected_color.g = reflected_color.r;\n";
|
||||
}
|
||||
|
||||
if (isSamplerEnabled(config.lighting.config, PICA::Lights::LUT_RB)) {
|
||||
compileLUTLookup(shader, config, regs, lightID, PICA::Lights::LUT_RB);
|
||||
compileLUTLookup(shader, config, lightID, PICA::Lights::LUT_RB);
|
||||
shader += "reflected_color.b = lut_lookup_result;\n";
|
||||
} else {
|
||||
shader += "reflected_color.b = reflected_color.r;\n";
|
||||
|
@ -565,7 +560,7 @@ void FragmentGenerator::compileLights(std::string& shader, const PICA::FragmentC
|
|||
}
|
||||
|
||||
if (config.lighting.enablePrimaryAlpha || config.lighting.enableSecondaryAlpha) {
|
||||
compileLUTLookup(shader, config, regs, lightID, PICA::Lights::LUT_FR);
|
||||
compileLUTLookup(shader, config, lightID, PICA::Lights::LUT_FR);
|
||||
shader += "float fresnel_factor = lut_lookup_result;\n";
|
||||
}
|
||||
|
||||
|
@ -602,7 +597,7 @@ bool FragmentGenerator::isSamplerEnabled(u32 environmentID, u32 lutID) {
|
|||
return samplerEnabled[environmentID * 7 + lutID];
|
||||
}
|
||||
|
||||
void FragmentGenerator::compileLUTLookup(std::string& shader, const PICA::FragmentConfig& config, const PICARegs& regs, u32 lightIndex, u32 lutID) {
|
||||
void FragmentGenerator::compileLUTLookup(std::string& shader, const PICA::FragmentConfig& config, u32 lightIndex, u32 lutID) {
|
||||
uint lutIndex = 0;
|
||||
int bitInConfig1 = 0;
|
||||
|
||||
|
@ -618,7 +613,7 @@ void FragmentGenerator::compileLUTLookup(std::string& shader, const PICA::Fragme
|
|||
}
|
||||
|
||||
const bool samplerEnabled = isSamplerEnabled(config.lighting.config, lutID);
|
||||
const u32 config1 = regs[InternalRegs::LightConfig1];
|
||||
const u32 config1 = config.lighting.config1;
|
||||
|
||||
if (!samplerEnabled || ((config1 >> bitInConfig1) & 1)) {
|
||||
shader += "lut_lookup_result = 1.0;\n";
|
||||
|
@ -626,9 +621,9 @@ void FragmentGenerator::compileLUTLookup(std::string& shader, const PICA::Fragme
|
|||
}
|
||||
|
||||
static constexpr float scales[] = {1.0f, 2.0f, 4.0f, 8.0f, 0.0f, 0.0f, 0.25f, 0.5f};
|
||||
const u32 lutAbs = regs[InternalRegs::LightLUTAbs];
|
||||
const u32 lutSelect = regs[InternalRegs::LightLUTSelect];
|
||||
const u32 lutScale = regs[InternalRegs::LightLUTScale];
|
||||
const u32 lutAbs = config.lighting.lutAbs;
|
||||
const u32 lutSelect = config.lighting.lutSelect;
|
||||
const u32 lutScale = config.lighting.lutScale;
|
||||
|
||||
// The way these bitfields are encoded is so cursed
|
||||
float scale = scales[(lutScale >> (4 * lutID)) & 0x7];
|
||||
|
|
|
@ -784,37 +784,12 @@ OpenGL::Program& RendererGL::getSpecializedShader() {
|
|||
constexpr uint uboBlockBinding = 2;
|
||||
|
||||
PICA::FragmentConfig fsConfig(regs);
|
||||
auto& outConfig = fsConfig.outConfig;
|
||||
auto& texConfig = fsConfig.texConfig;
|
||||
|
||||
auto alphaTestConfig = regs[InternalRegs::AlphaTestConfig];
|
||||
auto alphaTestFunction = Helpers::getBits<4, 3>(alphaTestConfig);
|
||||
|
||||
outConfig.alphaTestFunction = (alphaTestConfig & 1) ? static_cast<PICA::CompareFunction>(alphaTestFunction) : PICA::CompareFunction::Always;
|
||||
outConfig.depthMapEnable = regs[InternalRegs::DepthmapEnable] & 1;
|
||||
|
||||
texConfig.texUnitConfig = regs[InternalRegs::TexUnitCfg];
|
||||
texConfig.texEnvUpdateBuffer = regs[InternalRegs::TexEnvUpdateBuffer];
|
||||
|
||||
// Set up TEV stages. Annoyingly we can't just memcpy as the TEV registers are arranged like
|
||||
// {Source, Operand, Combiner, Color, Scale} and we want to skip the color register since it's uploaded via UBO
|
||||
#define setupTevStage(stage) \
|
||||
std::memcpy(&texConfig.tevConfigs[stage * 4], ®s[InternalRegs::TexEnv##stage##Source], 3 * sizeof(u32)); \
|
||||
texConfig.tevConfigs[stage * 4 + 3] = regs[InternalRegs::TexEnv##stage##Source + 5];
|
||||
|
||||
setupTevStage(0);
|
||||
setupTevStage(1);
|
||||
setupTevStage(2);
|
||||
setupTevStage(3);
|
||||
setupTevStage(4);
|
||||
setupTevStage(5);
|
||||
#undef setupTevStage
|
||||
|
||||
CachedProgram& programEntry = shaderCache[fsConfig];
|
||||
OpenGL::Program& program = programEntry.program;
|
||||
|
||||
if (!program.exists()) {
|
||||
std::string fs = fragShaderGen.generate(regs, fsConfig);
|
||||
std::string fs = fragShaderGen.generate(fsConfig);
|
||||
|
||||
OpenGL::Shader fragShader({fs.c_str(), fs.size()}, OpenGL::Fragment);
|
||||
program.create({defaultShadergenVs, fragShader});
|
||||
|
|
Loading…
Add table
Reference in a new issue