mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-07 22:55:40 +12:00
TEV definitions for shader generator
This commit is contained in:
parent
6f3c7d358b
commit
ef2467bc60
5 changed files with 152 additions and 1 deletions
|
@ -344,4 +344,108 @@ namespace PICA {
|
||||||
GeometryPrimitive = 3,
|
GeometryPrimitive = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TexEnvConfig {
|
||||||
|
enum class Source : u8 {
|
||||||
|
PrimaryColor = 0x0,
|
||||||
|
PrimaryFragmentColor = 0x1,
|
||||||
|
SecondaryFragmentColor = 0x2,
|
||||||
|
Texture0 = 0x3,
|
||||||
|
Texture1 = 0x4,
|
||||||
|
Texture2 = 0x5,
|
||||||
|
Texture3 = 0x6,
|
||||||
|
// TODO: Inbetween values are unknown
|
||||||
|
PreviousBuffer = 0xD,
|
||||||
|
Constant = 0xE,
|
||||||
|
Previous = 0xF,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class ColorOperand : u8 {
|
||||||
|
SourceColor = 0x0,
|
||||||
|
OneMinusSourceColor = 0x1,
|
||||||
|
SourceAlpha = 0x2,
|
||||||
|
OneMinusSourceAlpha = 0x3,
|
||||||
|
SourceRed = 0x4,
|
||||||
|
OneMinusSourceRed = 0x5,
|
||||||
|
// TODO: Inbetween values are unknown
|
||||||
|
SourceGreen = 0x8,
|
||||||
|
OneMinusSourceGreen = 0x9,
|
||||||
|
// Inbetween values are unknown
|
||||||
|
SourceBlue = 0xC,
|
||||||
|
OneMinusSourceBlue = 0xD,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class AlphaOperand : u8 {
|
||||||
|
SourceAlpha = 0x0,
|
||||||
|
OneMinusSourceAlpha = 0x1,
|
||||||
|
SourceRed = 0x2,
|
||||||
|
OneMinusSourceRed = 0x3,
|
||||||
|
SourceGreen = 0x4,
|
||||||
|
OneMinusSourceGreen = 0x5,
|
||||||
|
SourceBlue = 0x6,
|
||||||
|
OneMinusSourceBlue = 0x7,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class Operation : u8 {
|
||||||
|
Replace = 0,
|
||||||
|
Modulate = 1,
|
||||||
|
Add = 2,
|
||||||
|
AddSigned = 3,
|
||||||
|
Lerp = 4,
|
||||||
|
Subtract = 5,
|
||||||
|
Dot3RGB = 6,
|
||||||
|
Dot3RGBA = 7,
|
||||||
|
MultiplyAdd = 8,
|
||||||
|
AddMultiply = 9,
|
||||||
|
};
|
||||||
|
|
||||||
|
// RGB sources
|
||||||
|
Source colorSource1, colorSource2, colorSource3;
|
||||||
|
// Alpha sources
|
||||||
|
Source alphaSource1, alphaSource2, alphaSource3;
|
||||||
|
|
||||||
|
// RGB operands
|
||||||
|
ColorOperand colorOperand1, colorOperand2, colorOperand3;
|
||||||
|
// Alpha operands
|
||||||
|
AlphaOperand alphaOperand1, alphaOperand2, alphaOperand3;
|
||||||
|
|
||||||
|
// Texture environment operations for this stage
|
||||||
|
Operation colorOp, alphaOp;
|
||||||
|
|
||||||
|
u32 constColor;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// These are the only private members since their value doesn't actually reflect the scale
|
||||||
|
// So we make them public so we'll always use the appropriate member functions instead
|
||||||
|
u8 colorScale;
|
||||||
|
u8 alphaScale;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Create texture environment object from TEV registers
|
||||||
|
TexEnvConfig(u32 source, u32 operand, u32 combiner, u32 color, u32 scale) : constColor(color) {
|
||||||
|
colorSource1 = Helpers::getBits<0, 4, Source>(source);
|
||||||
|
colorSource2 = Helpers::getBits<4, 4, Source>(source);
|
||||||
|
colorSource3 = Helpers::getBits<8, 4, Source>(source);
|
||||||
|
|
||||||
|
alphaSource1 = Helpers::getBits<16, 4, Source>(source);
|
||||||
|
alphaSource2 = Helpers::getBits<20, 4, Source>(source);
|
||||||
|
alphaSource3 = Helpers::getBits<24, 4, Source>(source);
|
||||||
|
|
||||||
|
colorOperand1 = Helpers::getBits<0, 4, ColorOperand>(operand);
|
||||||
|
colorOperand2 = Helpers::getBits<4, 4, ColorOperand>(operand);
|
||||||
|
colorOperand3 = Helpers::getBits<8, 4, ColorOperand>(operand);
|
||||||
|
|
||||||
|
alphaOperand1 = Helpers::getBits<12, 3, AlphaOperand>(operand);
|
||||||
|
alphaOperand2 = Helpers::getBits<16, 3, AlphaOperand>(operand);
|
||||||
|
alphaOperand3 = Helpers::getBits<20, 3, AlphaOperand>(operand);
|
||||||
|
|
||||||
|
colorOp = Helpers::getBits<0, 4, Operation>(combiner);
|
||||||
|
alphaOp = Helpers::getBits<16, 4, Operation>(combiner);
|
||||||
|
|
||||||
|
colorScale = Helpers::getBits<0, 2>(scale);
|
||||||
|
alphaScale = Helpers::getBits<16, 2>(scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 getColorScale() { return (colorScale <= 2) ? (1 << colorScale) : 1; }
|
||||||
|
u32 getAlphaScale() { return (alphaScale <= 2) ? (1 << alphaScale) : 1; }
|
||||||
|
};
|
||||||
} // namespace PICA
|
} // namespace PICA
|
||||||
|
|
|
@ -17,6 +17,8 @@ namespace PICA::ShaderGen {
|
||||||
API api;
|
API api;
|
||||||
Language language;
|
Language language;
|
||||||
|
|
||||||
|
void compileTEV(std::string& shader, int stage, const PICARegs& regs);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FragmentGenerator(API api, Language language) : api(api), language(language) {}
|
FragmentGenerator(API api, Language language) : api(api), language(language) {}
|
||||||
std::string generate(const PICARegs& regs);
|
std::string generate(const PICARegs& regs);
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "PICA/float_types.hpp"
|
#include "PICA/float_types.hpp"
|
||||||
#include "PICA/pica_vertex.hpp"
|
#include "PICA/pica_vertex.hpp"
|
||||||
#include "PICA/regs.hpp"
|
#include "PICA/regs.hpp"
|
||||||
|
#include "PICA/shader_gen.hpp"
|
||||||
#include "gl_state.hpp"
|
#include "gl_state.hpp"
|
||||||
#include "helpers.hpp"
|
#include "helpers.hpp"
|
||||||
#include "logger.hpp"
|
#include "logger.hpp"
|
||||||
|
@ -60,6 +61,8 @@ class RendererGL final : public Renderer {
|
||||||
OpenGL::Framebuffer getColourFBO();
|
OpenGL::Framebuffer getColourFBO();
|
||||||
OpenGL::Texture getTexture(Texture& tex);
|
OpenGL::Texture getTexture(Texture& tex);
|
||||||
|
|
||||||
|
PICA::ShaderGen::FragmentGenerator fragShaderGen;
|
||||||
|
|
||||||
MAKE_LOG_FUNCTION(log, rendererLogger)
|
MAKE_LOG_FUNCTION(log, rendererLogger)
|
||||||
void setupBlending();
|
void setupBlending();
|
||||||
void setupStencilTest(bool stencilEnable);
|
void setupStencilTest(bool stencilEnable);
|
||||||
|
@ -71,7 +74,7 @@ class RendererGL final : public Renderer {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RendererGL(GPU& gpu, const std::array<u32, regNum>& internalRegs, const std::array<u32, extRegNum>& externalRegs)
|
RendererGL(GPU& gpu, const std::array<u32, regNum>& internalRegs, const std::array<u32, extRegNum>& externalRegs)
|
||||||
: Renderer(gpu, internalRegs, externalRegs) {}
|
: Renderer(gpu, internalRegs, externalRegs), fragShaderGen(PICA::ShaderGen::API::GL, PICA::ShaderGen::Language::GLSL) {}
|
||||||
~RendererGL() override;
|
~RendererGL() override;
|
||||||
|
|
||||||
void reset() override;
|
void reset() override;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "PICA/shader_gen.hpp"
|
#include "PICA/shader_gen.hpp"
|
||||||
|
using namespace PICA;
|
||||||
using namespace PICA::ShaderGen;
|
using namespace PICA::ShaderGen;
|
||||||
|
|
||||||
std::string FragmentGenerator::generate(const PICARegs& regs) {
|
std::string FragmentGenerator::generate(const PICARegs& regs) {
|
||||||
|
@ -10,6 +11,8 @@ std::string FragmentGenerator::generate(const PICARegs& regs) {
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool unimplementedFlag = false;
|
||||||
|
|
||||||
// Input and output attributes
|
// Input and output attributes
|
||||||
ret += R"(
|
ret += R"(
|
||||||
in vec3 v_tangent;
|
in vec3 v_tangent;
|
||||||
|
@ -24,7 +27,45 @@ std::string FragmentGenerator::generate(const PICARegs& regs) {
|
||||||
flat in vec4 v_textureEnvBufferColor;
|
flat in vec4 v_textureEnvBufferColor;
|
||||||
|
|
||||||
out vec4 fragColour;
|
out vec4 fragColour;
|
||||||
|
uniform sampler2D u_tex0;
|
||||||
|
uniform sampler2D u_tex1;
|
||||||
|
uniform sampler2D u_tex2;
|
||||||
|
uniform sampler1DArray u_tex_lighting_lut;
|
||||||
|
|
||||||
|
vec4 tevSources[16];
|
||||||
|
vec4 tevNextPreviousBuffer;
|
||||||
|
|
||||||
|
vec3 regToColor(uint reg) {
|
||||||
|
// Normalization scale to convert from [0...255] to [0.0...1.0]
|
||||||
|
const float scale = 1.0 / 255.0;
|
||||||
|
|
||||||
|
return scale * vec3(float(bitfieldExtract(reg, 20, 8)), float(bitfieldExtract(reg, 10, 8)), float(bitfieldExtract(reg, 00, 8)));
|
||||||
|
}
|
||||||
)";
|
)";
|
||||||
|
|
||||||
|
// Emit main function for fragment shader
|
||||||
|
// When not initialized, source 13 is set to vec4(0.0) and 15 is set to the vertex colour
|
||||||
|
ret += R"(
|
||||||
|
void main() {
|
||||||
|
tevSources[0] = v_colour;
|
||||||
|
tevSources[13] = vec4(0.0); // Previous buffer colour
|
||||||
|
tevSources[15] = v_colour; // Previous combiner
|
||||||
|
)";
|
||||||
|
|
||||||
|
for (int i = 0; i < 6; i++) {
|
||||||
|
compileTEV(ret, i, regs);
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
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,
|
||||||
|
};
|
||||||
|
|
||||||
|
const u32 ioBase = ioBases[stage];
|
||||||
|
TexEnvConfig tev(regs[ioBase], regs[ioBase + 1], regs[ioBase + 2], regs[ioBase + 3], regs[ioBase + 4]);
|
||||||
|
}
|
|
@ -388,6 +388,7 @@ void RendererGL::drawVertices(PICA::PrimType primType, std::span<const Vertex> v
|
||||||
OpenGL::TriangleFan,
|
OpenGL::TriangleFan,
|
||||||
OpenGL::Triangle,
|
OpenGL::Triangle,
|
||||||
};
|
};
|
||||||
|
std::cout << fragShaderGen.generate(regs);
|
||||||
|
|
||||||
const auto primitiveTopology = primTypes[static_cast<usize>(primType)];
|
const auto primitiveTopology = primTypes[static_cast<usize>(primType)];
|
||||||
gl.disableScissor();
|
gl.disableScissor();
|
||||||
|
|
Loading…
Add table
Reference in a new issue