mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-18 03:31:31 +12:00
[OpenGL renderer] Fewer uniform uploads
This commit is contained in:
parent
3e18281a99
commit
c282a44c27
2 changed files with 18 additions and 43 deletions
|
@ -23,8 +23,6 @@ class Renderer {
|
||||||
|
|
||||||
OpenGL::VertexArray vao;
|
OpenGL::VertexArray vao;
|
||||||
OpenGL::VertexBuffer vbo;
|
OpenGL::VertexBuffer vbo;
|
||||||
GLint alphaControlLoc = -1;
|
|
||||||
GLint texUnitConfigLoc = -1;
|
|
||||||
|
|
||||||
// TEV configuration uniform locations
|
// TEV configuration uniform locations
|
||||||
GLint textureEnvSourceLoc = -1;
|
GLint textureEnvSourceLoc = -1;
|
||||||
|
@ -41,9 +39,6 @@ class Renderer {
|
||||||
GLint depthScaleLoc = -1;
|
GLint depthScaleLoc = -1;
|
||||||
GLint depthmapEnableLoc = -1;
|
GLint depthmapEnableLoc = -1;
|
||||||
|
|
||||||
u32 oldAlphaControl = 0;
|
|
||||||
u32 oldTexUnitConfig = 0;
|
|
||||||
|
|
||||||
float oldDepthScale = -1.0;
|
float oldDepthScale = -1.0;
|
||||||
float oldDepthOffset = 0.0;
|
float oldDepthOffset = 0.0;
|
||||||
bool oldDepthmapEnable = false;
|
bool oldDepthmapEnable = false;
|
||||||
|
|
|
@ -35,11 +35,11 @@ const char* vertexShader = R"(
|
||||||
// TEV uniforms
|
// TEV uniforms
|
||||||
uniform uint u_textureEnvColor[6];
|
uniform uint u_textureEnvColor[6];
|
||||||
uniform uint u_textureEnvBufferColor;
|
uniform uint u_textureEnvBufferColor;
|
||||||
uniform uint u_picaRegs[0x200 - 0x47];
|
uniform uint u_picaRegs[0x200 - 0x48];
|
||||||
|
|
||||||
// Helper so that the implementation of u_pica_regs can be changed later
|
// Helper so that the implementation of u_pica_regs can be changed later
|
||||||
uint readPicaReg(uint reg_addr){
|
uint readPicaReg(uint reg_addr){
|
||||||
return u_picaRegs[reg_addr - 0x47];
|
return u_picaRegs[reg_addr - 0x48];
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 abgr8888ToVec4(uint abgr) {
|
vec4 abgr8888ToVec4(uint abgr) {
|
||||||
|
@ -131,9 +131,6 @@ const char* fragmentShader = R"(
|
||||||
|
|
||||||
out vec4 fragColour;
|
out vec4 fragColour;
|
||||||
|
|
||||||
uniform uint u_alphaControl;
|
|
||||||
uniform uint u_textureConfig;
|
|
||||||
|
|
||||||
// TEV uniforms
|
// TEV uniforms
|
||||||
uniform uint u_textureEnvSource[6];
|
uniform uint u_textureEnvSource[6];
|
||||||
uniform uint u_textureEnvOperand[6];
|
uniform uint u_textureEnvOperand[6];
|
||||||
|
@ -151,11 +148,11 @@ const char* fragmentShader = R"(
|
||||||
uniform sampler2D u_tex2;
|
uniform sampler2D u_tex2;
|
||||||
uniform sampler1DArray u_tex_lighting_lut;
|
uniform sampler1DArray u_tex_lighting_lut;
|
||||||
|
|
||||||
uniform uint u_picaRegs[0x200 - 0x47];
|
uniform uint u_picaRegs[0x200 - 0x48];
|
||||||
|
|
||||||
// Helper so that the implementation of u_pica_regs can be changed later
|
// Helper so that the implementation of u_pica_regs can be changed later
|
||||||
uint readPicaReg(uint reg_addr){
|
uint readPicaReg(uint reg_addr){
|
||||||
return u_picaRegs[reg_addr - 0x47];
|
return u_picaRegs[reg_addr - 0x48];
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 tevSources[16];
|
vec4 tevSources[16];
|
||||||
|
@ -453,16 +450,17 @@ const char* fragmentShader = R"(
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec2 tex2UV = (u_textureConfig & (1u << 13)) != 0u ? v_texcoord1 : v_texcoord2;
|
|
||||||
|
|
||||||
// TODO: what do invalid sources and disabled textures read as?
|
// TODO: what do invalid sources and disabled textures read as?
|
||||||
// And what does the "previous combiner" source read initially?
|
// And what does the "previous combiner" source read initially?
|
||||||
tevSources[0] = v_colour; // Primary/vertex color
|
tevSources[0] = v_colour; // Primary/vertex color
|
||||||
calcLighting(tevSources[1],tevSources[2]);
|
calcLighting(tevSources[1],tevSources[2]);
|
||||||
|
|
||||||
if ((u_textureConfig & 1u) != 0u) tevSources[3] = texture(u_tex0, v_texcoord0.xy);
|
uint textureConfig = readPicaReg(0x80);
|
||||||
if ((u_textureConfig & 2u) != 0u) tevSources[4] = texture(u_tex1, v_texcoord1);
|
vec2 tex2UV = (textureConfig & (1u << 13)) != 0u ? v_texcoord1 : v_texcoord2;
|
||||||
if ((u_textureConfig & 4u) != 0u) tevSources[5] = texture(u_tex2, tex2UV);
|
|
||||||
|
if ((textureConfig & 1u) != 0u) tevSources[3] = texture(u_tex0, v_texcoord0.xy);
|
||||||
|
if ((textureConfig & 2u) != 0u) tevSources[4] = texture(u_tex1, v_texcoord1);
|
||||||
|
if ((textureConfig & 4u) != 0u) tevSources[5] = texture(u_tex2, tex2UV);
|
||||||
tevSources[13] = vec4(0.0); // Previous buffer
|
tevSources[13] = vec4(0.0); // Previous buffer
|
||||||
tevSources[15] = vec4(0.0); // Previous combiner
|
tevSources[15] = vec4(0.0); // Previous combiner
|
||||||
|
|
||||||
|
@ -503,9 +501,11 @@ const char* fragmentShader = R"(
|
||||||
// Write final fragment depth
|
// Write final fragment depth
|
||||||
gl_FragDepth = depth;
|
gl_FragDepth = depth;
|
||||||
|
|
||||||
if ((u_alphaControl & 1u) != 0u) { // Check if alpha test is on
|
// Perform alpha test
|
||||||
uint func = (u_alphaControl >> 4u) & 7u;
|
uint alphaControl = readPicaReg(0x104);
|
||||||
float reference = float((u_alphaControl >> 8u) & 0xffu) / 255.0;
|
if ((alphaControl & 1u) != 0u) { // Check if alpha test is on
|
||||||
|
uint func = (alphaControl >> 4u) & 7u;
|
||||||
|
float reference = float((alphaControl >> 8u) & 0xffu) / 255.0;
|
||||||
float alpha = fragColour.a;
|
float alpha = fragColour.a;
|
||||||
|
|
||||||
switch (func) {
|
switch (func) {
|
||||||
|
@ -593,15 +593,11 @@ void Renderer::reset() {
|
||||||
const auto oldProgram = OpenGL::getProgram();
|
const auto oldProgram = OpenGL::getProgram();
|
||||||
|
|
||||||
gl.useProgram(triangleProgram);
|
gl.useProgram(triangleProgram);
|
||||||
oldAlphaControl = 0; // Default alpha control to 0
|
|
||||||
oldTexUnitConfig = 0; // Default tex unit config to 0
|
|
||||||
|
|
||||||
oldDepthScale = -1.0; // Default depth scale to -1.0, which is what games typically use
|
oldDepthScale = -1.0; // Default depth scale to -1.0, which is what games typically use
|
||||||
oldDepthOffset = 0.0; // Default depth offset to 0
|
oldDepthOffset = 0.0; // Default depth offset to 0
|
||||||
oldDepthmapEnable = false; // Enable w buffering
|
oldDepthmapEnable = false; // Enable w buffering
|
||||||
|
|
||||||
glUniform1ui(alphaControlLoc, oldAlphaControl);
|
|
||||||
glUniform1ui(texUnitConfigLoc, oldTexUnitConfig);
|
|
||||||
glUniform1f(depthScaleLoc, oldDepthScale);
|
glUniform1f(depthScaleLoc, oldDepthScale);
|
||||||
glUniform1f(depthOffsetLoc, oldDepthOffset);
|
glUniform1f(depthOffsetLoc, oldDepthOffset);
|
||||||
glUniform1i(depthmapEnableLoc, oldDepthmapEnable);
|
glUniform1i(depthmapEnableLoc, oldDepthmapEnable);
|
||||||
|
@ -615,9 +611,6 @@ void Renderer::initGraphicsContext() {
|
||||||
OpenGL::Shader frag(fragmentShader, OpenGL::Fragment);
|
OpenGL::Shader frag(fragmentShader, OpenGL::Fragment);
|
||||||
triangleProgram.create({ vert, frag });
|
triangleProgram.create({ vert, frag });
|
||||||
gl.useProgram(triangleProgram);
|
gl.useProgram(triangleProgram);
|
||||||
|
|
||||||
alphaControlLoc = OpenGL::uniformLocation(triangleProgram, "u_alphaControl");
|
|
||||||
texUnitConfigLoc = OpenGL::uniformLocation(triangleProgram, "u_textureConfig");
|
|
||||||
|
|
||||||
textureEnvSourceLoc = OpenGL::uniformLocation(triangleProgram, "u_textureEnvSource");
|
textureEnvSourceLoc = OpenGL::uniformLocation(triangleProgram, "u_textureEnvSource");
|
||||||
textureEnvOperandLoc = OpenGL::uniformLocation(triangleProgram, "u_textureEnvOperand");
|
textureEnvOperandLoc = OpenGL::uniformLocation(triangleProgram, "u_textureEnvOperand");
|
||||||
|
@ -815,14 +808,8 @@ void Renderer::bindTexturesToSlots() {
|
||||||
glActiveTexture(GL_TEXTURE0 + 3);
|
glActiveTexture(GL_TEXTURE0 + 3);
|
||||||
glBindTexture(GL_TEXTURE_1D_ARRAY, lightLUTTextureArray);
|
glBindTexture(GL_TEXTURE_1D_ARRAY, lightLUTTextureArray);
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
// Update the texture unit configuration uniform if it changed
|
|
||||||
const u32 texUnitConfig = regs[PICA::InternalRegs::TexUnitCfg];
|
|
||||||
if (oldTexUnitConfig != texUnitConfig) {
|
|
||||||
oldTexUnitConfig = texUnitConfig;
|
|
||||||
glUniform1ui(texUnitConfigLoc, texUnitConfig);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::updateLightingLUT(){
|
void Renderer::updateLightingLUT(){
|
||||||
std::array<u16, GPU::LightingLutSize> u16_lightinglut;
|
std::array<u16, GPU::LightingLutSize> u16_lightinglut;
|
||||||
|
|
||||||
|
@ -854,13 +841,6 @@ void Renderer::drawVertices(PICA::PrimType primType, std::span<const Vertex> ver
|
||||||
gl.bindVAO(vao);
|
gl.bindVAO(vao);
|
||||||
gl.useProgram(triangleProgram);
|
gl.useProgram(triangleProgram);
|
||||||
|
|
||||||
// Adjust alpha test if necessary
|
|
||||||
const u32 alphaControl = regs[PICA::InternalRegs::AlphaTestConfig];
|
|
||||||
if (alphaControl != oldAlphaControl) {
|
|
||||||
oldAlphaControl = alphaControl;
|
|
||||||
glUniform1ui(alphaControlLoc, alphaControl);
|
|
||||||
}
|
|
||||||
|
|
||||||
OpenGL::enableClipPlane(0); // Clipping plane 0 is always enabled
|
OpenGL::enableClipPlane(0); // Clipping plane 0 is always enabled
|
||||||
if (regs[PICA::InternalRegs::ClipEnable] & 1) {
|
if (regs[PICA::InternalRegs::ClipEnable] & 1) {
|
||||||
OpenGL::enableClipPlane(1);
|
OpenGL::enableClipPlane(1);
|
||||||
|
@ -904,9 +884,9 @@ void Renderer::drawVertices(PICA::PrimType primType, std::span<const Vertex> ver
|
||||||
setupTextureEnvState();
|
setupTextureEnvState();
|
||||||
bindTexturesToSlots();
|
bindTexturesToSlots();
|
||||||
|
|
||||||
// Upload PICA Registers as a single uniform. The shader needs access to the rasterizer registers (for depth, starting from index 0x47)
|
// Upload PICA Registers as a single uniform. The shader needs access to the rasterizer registers (for depth, starting from index 0x48)
|
||||||
// The texturing and the fragment lighting registers. Therefore we upload them all in one go to avoid multiple slow uniform updates
|
// The texturing and the fragment lighting registers. Therefore we upload them all in one go to avoid multiple slow uniform updates
|
||||||
glUniform1uiv(picaRegLoc, 0x200 - 0x47, ®s[0x47]);
|
glUniform1uiv(picaRegLoc, 0x200 - 0x48, ®s[0x48]);
|
||||||
|
|
||||||
if (gpu.lightingLUTDirty) {
|
if (gpu.lightingLUTDirty) {
|
||||||
updateLightingLUT();
|
updateLightingLUT();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue