mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-08 07:05:40 +12:00
Merge pull request #561 from wheremyfoodat/uniformz
Add SDL resizing & optimize GL shadergen
This commit is contained in:
commit
2abf642922
6 changed files with 26 additions and 23 deletions
|
@ -35,9 +35,6 @@ namespace PICA {
|
||||||
|
|
||||||
BitField<0, 3, FogMode> mode;
|
BitField<0, 3, FogMode> mode;
|
||||||
BitField<3, 1, u32> flipDepth;
|
BitField<3, 1, u32> flipDepth;
|
||||||
BitField<8, 8, u32> fogColorR;
|
|
||||||
BitField<16, 8, u32> fogColorG;
|
|
||||||
BitField<24, 8, u32> fogColorB;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -238,9 +235,6 @@ namespace PICA {
|
||||||
|
|
||||||
if (fogConfig.mode == FogMode::Fog) {
|
if (fogConfig.mode == FogMode::Fog) {
|
||||||
fogConfig.flipDepth = Helpers::getBit<16>(regs[InternalRegs::TexEnvUpdateBuffer]);
|
fogConfig.flipDepth = Helpers::getBit<16>(regs[InternalRegs::TexEnvUpdateBuffer]);
|
||||||
fogConfig.fogColorR = Helpers::getBits<0, 8>(regs[InternalRegs::FogColor]);
|
|
||||||
fogConfig.fogColorG = Helpers::getBits<8, 8>(regs[InternalRegs::FogColor]);
|
|
||||||
fogConfig.fogColorB = Helpers::getBits<16, 8>(regs[InternalRegs::FogColor]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -34,8 +34,10 @@ namespace PICA {
|
||||||
alignas(16) vec4 tevBufferColor;
|
alignas(16) vec4 tevBufferColor;
|
||||||
alignas(16) vec4 clipCoords;
|
alignas(16) vec4 clipCoords;
|
||||||
|
|
||||||
// Note: We upload this as a u32 and decode on GPU
|
// Note: We upload these as a u32 and decode on GPU.
|
||||||
|
// Particularly the fog colour since fog is really uncommon and it doesn't matter if we decode on GPU.
|
||||||
u32 globalAmbientLight;
|
u32 globalAmbientLight;
|
||||||
|
u32 fogColor;
|
||||||
// NOTE: THIS MUST BE LAST so that if lighting is disabled we can potentially omit uploading it
|
// NOTE: THIS MUST BE LAST so that if lighting is disabled we can potentially omit uploading it
|
||||||
LightUniform lightUniforms[8];
|
LightUniform lightUniforms[8];
|
||||||
};
|
};
|
||||||
|
|
|
@ -69,11 +69,11 @@ class RendererGL final : public Renderer {
|
||||||
// The "default" vertex shader to use when using specialized shaders but not PICA vertex shader -> GLSL recompilation
|
// The "default" vertex shader to use when using specialized shaders but not PICA vertex shader -> GLSL recompilation
|
||||||
// We can compile this once and then link it with all other generated fragment shaders
|
// We can compile this once and then link it with all other generated fragment shaders
|
||||||
OpenGL::Shader defaultShadergenVs;
|
OpenGL::Shader defaultShadergenVs;
|
||||||
|
GLuint shadergenFragmentUBO;
|
||||||
|
|
||||||
// Cached recompiled fragment shader
|
// Cached recompiled fragment shader
|
||||||
struct CachedProgram {
|
struct CachedProgram {
|
||||||
OpenGL::Program program;
|
OpenGL::Program program;
|
||||||
uint uboBinding;
|
|
||||||
};
|
};
|
||||||
std::unordered_map<PICA::FragmentConfig, CachedProgram> shaderCache;
|
std::unordered_map<PICA::FragmentConfig, CachedProgram> shaderCache;
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ static constexpr const char* uniformDefinition = R"(
|
||||||
|
|
||||||
// Note: We upload this as a u32 and decode on GPU
|
// Note: We upload this as a u32 and decode on GPU
|
||||||
uint globalAmbientLight;
|
uint globalAmbientLight;
|
||||||
|
uint inFogColor;
|
||||||
LightSource lightSources[8];
|
LightSource lightSources[8];
|
||||||
};
|
};
|
||||||
)";
|
)";
|
||||||
|
@ -656,10 +657,6 @@ void FragmentGenerator::compileFog(std::string& shader, const PICA::FragmentConf
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
float r = config.fogConfig.fogColorR / 255.0f;
|
|
||||||
float g = config.fogConfig.fogColorG / 255.0f;
|
|
||||||
float b = config.fogConfig.fogColorB / 255.0f;
|
|
||||||
|
|
||||||
if (config.fogConfig.flipDepth) {
|
if (config.fogConfig.flipDepth) {
|
||||||
shader += "float fog_index = (1.0 - depth) * 128.0;\n";
|
shader += "float fog_index = (1.0 - depth) * 128.0;\n";
|
||||||
} else {
|
} else {
|
||||||
|
@ -668,7 +665,7 @@ void FragmentGenerator::compileFog(std::string& shader, const PICA::FragmentConf
|
||||||
|
|
||||||
shader += "float clamped_index = clamp(floor(fog_index), 0.0, 127.0);";
|
shader += "float clamped_index = clamp(floor(fog_index), 0.0, 127.0);";
|
||||||
shader += "float delta = fog_index - clamped_index;";
|
shader += "float delta = fog_index - clamped_index;";
|
||||||
shader += "vec3 fog_color = vec3(" + std::to_string(r) + ", " + std::to_string(g) + ", " + std::to_string(b) + ");";
|
shader += "vec3 fog_color = (1.0 / 255.0) * vec3(float(inFogColor & 0xffu), float((inFogColor >> 8u) & 0xffu), float((inFogColor >> 16u) & 0xffu));";
|
||||||
shader += "vec2 value = texelFetch(u_tex_luts, ivec2(int(clamped_index), 24), 0).rg;"; // fog LUT is past the light LUTs
|
shader += "vec2 value = texelFetch(u_tex_luts, ivec2(int(clamped_index), 24), 0).rg;"; // fog LUT is past the light LUTs
|
||||||
shader += "float fog_factor = clamp(value.r + value.g * delta, 0.0, 1.0);";
|
shader += "float fog_factor = clamp(value.r + value.g * delta, 0.0, 1.0);";
|
||||||
shader += "combinerOutput.rgb = mix(fog_color, combinerOutput.rgb, fog_factor);";
|
shader += "combinerOutput.rgb = mix(fog_color, combinerOutput.rgb, fog_factor);";
|
||||||
|
|
|
@ -77,6 +77,11 @@ void RendererGL::initGraphicsContextInternal() {
|
||||||
gl.useProgram(displayProgram);
|
gl.useProgram(displayProgram);
|
||||||
glUniform1i(OpenGL::uniformLocation(displayProgram, "u_texture"), 0); // Init sampler object
|
glUniform1i(OpenGL::uniformLocation(displayProgram, "u_texture"), 0); // Init sampler object
|
||||||
|
|
||||||
|
// Allocate memory for the shadergen fragment uniform UBO
|
||||||
|
glGenBuffers(1, &shadergenFragmentUBO);
|
||||||
|
gl.bindUBO(shadergenFragmentUBO);
|
||||||
|
glBufferData(GL_UNIFORM_BUFFER, sizeof(PICA::FragmentUniforms), nullptr, GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
vbo.createFixedSize(sizeof(Vertex) * vertexBufferSize, GL_STREAM_DRAW);
|
vbo.createFixedSize(sizeof(Vertex) * vertexBufferSize, GL_STREAM_DRAW);
|
||||||
gl.bindVBO(vbo);
|
gl.bindVBO(vbo);
|
||||||
vao.create();
|
vao.create();
|
||||||
|
@ -853,17 +858,12 @@ OpenGL::Program& RendererGL::getSpecializedShader() {
|
||||||
glUniform1i(OpenGL::uniformLocation(program, "u_tex2"), 2);
|
glUniform1i(OpenGL::uniformLocation(program, "u_tex2"), 2);
|
||||||
glUniform1i(OpenGL::uniformLocation(program, "u_tex_luts"), 3);
|
glUniform1i(OpenGL::uniformLocation(program, "u_tex_luts"), 3);
|
||||||
|
|
||||||
// Allocate memory for the program UBO
|
|
||||||
glGenBuffers(1, &programEntry.uboBinding);
|
|
||||||
gl.bindUBO(programEntry.uboBinding);
|
|
||||||
glBufferData(GL_UNIFORM_BUFFER, sizeof(PICA::FragmentUniforms), nullptr, GL_DYNAMIC_DRAW);
|
|
||||||
|
|
||||||
// Set up the binding for our UBO. Sadly we can't specify it in the shader like normal people,
|
// Set up the binding for our UBO. Sadly we can't specify it in the shader like normal people,
|
||||||
// As it's an OpenGL 4.2 feature that MacOS doesn't support...
|
// As it's an OpenGL 4.2 feature that MacOS doesn't support...
|
||||||
uint uboIndex = glGetUniformBlockIndex(program.handle(), "FragmentUniforms");
|
uint uboIndex = glGetUniformBlockIndex(program.handle(), "FragmentUniforms");
|
||||||
glUniformBlockBinding(program.handle(), uboIndex, uboBlockBinding);
|
glUniformBlockBinding(program.handle(), uboIndex, uboBlockBinding);
|
||||||
}
|
}
|
||||||
glBindBufferBase(GL_UNIFORM_BUFFER, uboBlockBinding, programEntry.uboBinding);
|
glBindBufferBase(GL_UNIFORM_BUFFER, uboBlockBinding, shadergenFragmentUBO);
|
||||||
|
|
||||||
// Upload uniform data to our shader's UBO
|
// Upload uniform data to our shader's UBO
|
||||||
PICA::FragmentUniforms uniforms;
|
PICA::FragmentUniforms uniforms;
|
||||||
|
@ -903,6 +903,8 @@ OpenGL::Program& RendererGL::getSpecializedShader() {
|
||||||
vec[3] = float((color >> 24) & 0xFF) / 255.0f;
|
vec[3] = float((color >> 24) & 0xFF) / 255.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uniforms.fogColor = regs[PICA::InternalRegs::FogColor];
|
||||||
|
|
||||||
// Append lighting uniforms
|
// Append lighting uniforms
|
||||||
if (fsConfig.lighting.enable) {
|
if (fsConfig.lighting.enable) {
|
||||||
uniforms.globalAmbientLight = regs[InternalRegs::LightGlobalAmbient];
|
uniforms.globalAmbientLight = regs[InternalRegs::LightGlobalAmbient];
|
||||||
|
@ -945,7 +947,7 @@ OpenGL::Program& RendererGL::getSpecializedShader() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gl.bindUBO(programEntry.uboBinding);
|
gl.bindUBO(shadergenFragmentUBO);
|
||||||
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(PICA::FragmentUniforms), &uniforms);
|
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(PICA::FragmentUniforms), &uniforms);
|
||||||
|
|
||||||
return program;
|
return program;
|
||||||
|
@ -980,7 +982,6 @@ void RendererGL::clearShaderCache() {
|
||||||
for (auto& shader : shaderCache) {
|
for (auto& shader : shaderCache) {
|
||||||
CachedProgram& cachedProgram = shader.second;
|
CachedProgram& cachedProgram = shader.second;
|
||||||
cachedProgram.program.free();
|
cachedProgram.program.free();
|
||||||
glDeleteBuffers(1, &cachedProgram.uboBinding);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
shaderCache.clear();
|
shaderCache.clear();
|
||||||
|
|
|
@ -35,7 +35,7 @@ FrontendSDL::FrontendSDL() : keyboardMappings(InputMappings::defaultKeyboardMapp
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, config.rendererType == RendererType::Software ? 3 : 4);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, config.rendererType == RendererType::Software ? 3 : 4);
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, config.rendererType == RendererType::Software ? 3 : 1);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, config.rendererType == RendererType::Software ? 3 : 1);
|
||||||
window = SDL_CreateWindow("Alber", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 400, 480, SDL_WINDOW_OPENGL);
|
window = SDL_CreateWindow("Alber", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 400, 480, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
|
||||||
|
|
||||||
if (window == nullptr) {
|
if (window == nullptr) {
|
||||||
Helpers::panic("Window creation failed: %s", SDL_GetError());
|
Helpers::panic("Window creation failed: %s", SDL_GetError());
|
||||||
|
@ -55,7 +55,7 @@ FrontendSDL::FrontendSDL() : keyboardMappings(InputMappings::defaultKeyboardMapp
|
||||||
|
|
||||||
#ifdef PANDA3DS_ENABLE_VULKAN
|
#ifdef PANDA3DS_ENABLE_VULKAN
|
||||||
if (config.rendererType == RendererType::Vulkan) {
|
if (config.rendererType == RendererType::Vulkan) {
|
||||||
window = SDL_CreateWindow("Alber", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 400, 480, SDL_WINDOW_VULKAN);
|
window = SDL_CreateWindow("Alber", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 400, 480, SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE);
|
||||||
|
|
||||||
if (window == nullptr) {
|
if (window == nullptr) {
|
||||||
Helpers::warn("Window creation failed: %s", SDL_GetError());
|
Helpers::warn("Window creation failed: %s", SDL_GetError());
|
||||||
|
@ -289,6 +289,15 @@ void FrontendSDL::run() {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case SDL_WINDOWEVENT: {
|
||||||
|
auto type = event.window.event;
|
||||||
|
if (type == SDL_WINDOWEVENT_RESIZED) {
|
||||||
|
const u32 width = event.window.data1;
|
||||||
|
const u32 height = event.window.data2;
|
||||||
|
emu.setOutputSize(width, height);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue