mirror of
https://github.com/citra-emu/citra.git
synced 2024-12-18 23:00:04 +00:00
gl_rasterizer: Inline texture buffer uploads.
This commit is contained in:
parent
8a8c6f059f
commit
298ebe3752
@ -1725,21 +1725,6 @@ void RasterizerOpenGL::SyncFogColor() {
|
||||
uniform_block_data.dirty = true;
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncFogLUT() {
|
||||
std::array<GLvec2, 128> new_data;
|
||||
|
||||
std::transform(Pica::g_state.fog.lut.begin(), Pica::g_state.fog.lut.end(), new_data.begin(),
|
||||
[](const auto& entry) {
|
||||
return GLvec2{entry.ToFloat(), entry.DiffToFloat()};
|
||||
});
|
||||
|
||||
if (new_data != fog_lut_data) {
|
||||
fog_lut_data = new_data;
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, fog_lut_buffer.handle);
|
||||
glBufferSubData(GL_TEXTURE_BUFFER, 0, new_data.size() * sizeof(GLvec2), new_data.data());
|
||||
}
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncProcTexNoise() {
|
||||
const auto& regs = Pica::g_state.regs.texturing;
|
||||
uniform_block_data.data.proctex_noise_f = {
|
||||
@ -1758,70 +1743,6 @@ void RasterizerOpenGL::SyncProcTexNoise() {
|
||||
uniform_block_data.dirty = true;
|
||||
}
|
||||
|
||||
// helper function for SyncProcTexNoiseLUT/ColorMap/AlphaMap
|
||||
static void SyncProcTexValueLUT(const std::array<Pica::State::ProcTex::ValueEntry, 128>& lut,
|
||||
std::array<GLvec2, 128>& lut_data, GLuint buffer) {
|
||||
std::array<GLvec2, 128> new_data;
|
||||
std::transform(lut.begin(), lut.end(), new_data.begin(), [](const auto& entry) {
|
||||
return GLvec2{entry.ToFloat(), entry.DiffToFloat()};
|
||||
});
|
||||
|
||||
if (new_data != lut_data) {
|
||||
lut_data = new_data;
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, buffer);
|
||||
glBufferSubData(GL_TEXTURE_BUFFER, 0, new_data.size() * sizeof(GLvec2), new_data.data());
|
||||
}
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncProcTexNoiseLUT() {
|
||||
SyncProcTexValueLUT(Pica::g_state.proctex.noise_table, proctex_noise_lut_data,
|
||||
proctex_noise_lut_buffer.handle);
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncProcTexColorMap() {
|
||||
SyncProcTexValueLUT(Pica::g_state.proctex.color_map_table, proctex_color_map_data,
|
||||
proctex_color_map_buffer.handle);
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncProcTexAlphaMap() {
|
||||
SyncProcTexValueLUT(Pica::g_state.proctex.alpha_map_table, proctex_alpha_map_data,
|
||||
proctex_alpha_map_buffer.handle);
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncProcTexLUT() {
|
||||
std::array<GLvec4, 256> new_data;
|
||||
|
||||
std::transform(Pica::g_state.proctex.color_table.begin(),
|
||||
Pica::g_state.proctex.color_table.end(), new_data.begin(),
|
||||
[](const auto& entry) {
|
||||
auto rgba = entry.ToVector() / 255.0f;
|
||||
return GLvec4{rgba.r(), rgba.g(), rgba.b(), rgba.a()};
|
||||
});
|
||||
|
||||
if (new_data != proctex_lut_data) {
|
||||
proctex_lut_data = new_data;
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, proctex_lut_buffer.handle);
|
||||
glBufferSubData(GL_TEXTURE_BUFFER, 0, new_data.size() * sizeof(GLvec4), new_data.data());
|
||||
}
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncProcTexDiffLUT() {
|
||||
std::array<GLvec4, 256> new_data;
|
||||
|
||||
std::transform(Pica::g_state.proctex.color_diff_table.begin(),
|
||||
Pica::g_state.proctex.color_diff_table.end(), new_data.begin(),
|
||||
[](const auto& entry) {
|
||||
auto rgba = entry.ToVector() / 255.0f;
|
||||
return GLvec4{rgba.r(), rgba.g(), rgba.b(), rgba.a()};
|
||||
});
|
||||
|
||||
if (new_data != proctex_diff_lut_data) {
|
||||
proctex_diff_lut_data = new_data;
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, proctex_diff_lut_buffer.handle);
|
||||
glBufferSubData(GL_TEXTURE_BUFFER, 0, new_data.size() * sizeof(GLvec4), new_data.data());
|
||||
}
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncAlphaTest() {
|
||||
const auto& regs = Pica::g_state.regs;
|
||||
if (regs.framebuffer.output_merger.alpha_test.ref != uniform_block_data.data.alphatest_ref) {
|
||||
@ -1919,21 +1840,6 @@ void RasterizerOpenGL::SyncGlobalAmbient() {
|
||||
}
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncLightingLUT(unsigned lut_index) {
|
||||
std::array<GLvec2, 256> new_data;
|
||||
const auto& source_lut = Pica::g_state.lighting.luts[lut_index];
|
||||
std::transform(source_lut.begin(), source_lut.end(), new_data.begin(), [](const auto& entry) {
|
||||
return GLvec2{entry.ToFloat(), entry.DiffToFloat()};
|
||||
});
|
||||
|
||||
if (new_data != lighting_lut_data[lut_index]) {
|
||||
lighting_lut_data[lut_index] = new_data;
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, lighting_lut_buffer.handle);
|
||||
glBufferSubData(GL_TEXTURE_BUFFER, lut_index * new_data.size() * sizeof(GLvec2),
|
||||
new_data.size() * sizeof(GLvec2), new_data.data());
|
||||
}
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncLightSpecular0(int light_index) {
|
||||
auto color = PicaToGL::LightColor(Pica::g_state.regs.lighting.light[light_index].specular_0);
|
||||
if (color != uniform_block_data.data.light_src[light_index].specular_0) {
|
||||
@ -2028,44 +1934,115 @@ void RasterizerOpenGL::SyncAndUploadLUTs() {
|
||||
// Sync the lighting luts
|
||||
for (unsigned index = 0; index < uniform_block_data.lut_dirty.size(); index++) {
|
||||
if (uniform_block_data.lut_dirty[index]) {
|
||||
SyncLightingLUT(index);
|
||||
std::array<GLvec2, 256> new_data;
|
||||
const auto& source_lut = Pica::g_state.lighting.luts[index];
|
||||
std::transform(source_lut.begin(), source_lut.end(), new_data.begin(),
|
||||
[](const auto& entry) {
|
||||
return GLvec2{entry.ToFloat(), entry.DiffToFloat()};
|
||||
});
|
||||
|
||||
if (new_data != lighting_lut_data[index]) {
|
||||
lighting_lut_data[index] = new_data;
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, lighting_lut_buffer.handle);
|
||||
glBufferSubData(GL_TEXTURE_BUFFER, index * new_data.size() * sizeof(GLvec2),
|
||||
new_data.size() * sizeof(GLvec2), new_data.data());
|
||||
}
|
||||
uniform_block_data.lut_dirty[index] = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Sync the fog lut
|
||||
if (uniform_block_data.fog_lut_dirty) {
|
||||
SyncFogLUT();
|
||||
std::array<GLvec2, 128> new_data;
|
||||
|
||||
std::transform(Pica::g_state.fog.lut.begin(), Pica::g_state.fog.lut.end(), new_data.begin(),
|
||||
[](const auto& entry) {
|
||||
return GLvec2{entry.ToFloat(), entry.DiffToFloat()};
|
||||
});
|
||||
|
||||
if (new_data != fog_lut_data) {
|
||||
fog_lut_data = new_data;
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, fog_lut_buffer.handle);
|
||||
glBufferSubData(GL_TEXTURE_BUFFER, 0, new_data.size() * sizeof(GLvec2),
|
||||
new_data.data());
|
||||
}
|
||||
uniform_block_data.fog_lut_dirty = false;
|
||||
}
|
||||
|
||||
// helper function for SyncProcTexNoiseLUT/ColorMap/AlphaMap
|
||||
auto SyncProcTexValueLUT = [](const std::array<Pica::State::ProcTex::ValueEntry, 128>& lut,
|
||||
std::array<GLvec2, 128>& lut_data, GLuint buffer) {
|
||||
std::array<GLvec2, 128> new_data;
|
||||
std::transform(lut.begin(), lut.end(), new_data.begin(), [](const auto& entry) {
|
||||
return GLvec2{entry.ToFloat(), entry.DiffToFloat()};
|
||||
});
|
||||
|
||||
if (new_data != lut_data) {
|
||||
lut_data = new_data;
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, buffer);
|
||||
glBufferSubData(GL_TEXTURE_BUFFER, 0, new_data.size() * sizeof(GLvec2),
|
||||
new_data.data());
|
||||
}
|
||||
};
|
||||
|
||||
// Sync the proctex noise lut
|
||||
if (uniform_block_data.proctex_noise_lut_dirty) {
|
||||
SyncProcTexNoiseLUT();
|
||||
SyncProcTexValueLUT(Pica::g_state.proctex.noise_table, proctex_noise_lut_data,
|
||||
proctex_noise_lut_buffer.handle);
|
||||
uniform_block_data.proctex_noise_lut_dirty = false;
|
||||
}
|
||||
|
||||
// Sync the proctex color map
|
||||
if (uniform_block_data.proctex_color_map_dirty) {
|
||||
SyncProcTexColorMap();
|
||||
SyncProcTexValueLUT(Pica::g_state.proctex.color_map_table, proctex_color_map_data,
|
||||
proctex_color_map_buffer.handle);
|
||||
uniform_block_data.proctex_color_map_dirty = false;
|
||||
}
|
||||
|
||||
// Sync the proctex alpha map
|
||||
if (uniform_block_data.proctex_alpha_map_dirty) {
|
||||
SyncProcTexAlphaMap();
|
||||
SyncProcTexValueLUT(Pica::g_state.proctex.alpha_map_table, proctex_alpha_map_data,
|
||||
proctex_alpha_map_buffer.handle);
|
||||
uniform_block_data.proctex_alpha_map_dirty = false;
|
||||
}
|
||||
|
||||
// Sync the proctex lut
|
||||
if (uniform_block_data.proctex_lut_dirty) {
|
||||
SyncProcTexLUT();
|
||||
std::array<GLvec4, 256> new_data;
|
||||
|
||||
std::transform(Pica::g_state.proctex.color_table.begin(),
|
||||
Pica::g_state.proctex.color_table.end(), new_data.begin(),
|
||||
[](const auto& entry) {
|
||||
auto rgba = entry.ToVector() / 255.0f;
|
||||
return GLvec4{rgba.r(), rgba.g(), rgba.b(), rgba.a()};
|
||||
});
|
||||
|
||||
if (new_data != proctex_lut_data) {
|
||||
proctex_lut_data = new_data;
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, proctex_lut_buffer.handle);
|
||||
glBufferSubData(GL_TEXTURE_BUFFER, 0, new_data.size() * sizeof(GLvec4),
|
||||
new_data.data());
|
||||
}
|
||||
uniform_block_data.proctex_lut_dirty = false;
|
||||
}
|
||||
|
||||
// Sync the proctex difference lut
|
||||
if (uniform_block_data.proctex_diff_lut_dirty) {
|
||||
SyncProcTexDiffLUT();
|
||||
std::array<GLvec4, 256> new_data;
|
||||
|
||||
std::transform(Pica::g_state.proctex.color_diff_table.begin(),
|
||||
Pica::g_state.proctex.color_diff_table.end(), new_data.begin(),
|
||||
[](const auto& entry) {
|
||||
auto rgba = entry.ToVector() / 255.0f;
|
||||
return GLvec4{rgba.r(), rgba.g(), rgba.b(), rgba.a()};
|
||||
});
|
||||
|
||||
if (new_data != proctex_diff_lut_data) {
|
||||
proctex_diff_lut_data = new_data;
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, proctex_diff_lut_buffer.handle);
|
||||
glBufferSubData(GL_TEXTURE_BUFFER, 0, new_data.size() * sizeof(GLvec4),
|
||||
new_data.data());
|
||||
}
|
||||
uniform_block_data.proctex_diff_lut_dirty = false;
|
||||
}
|
||||
}
|
||||
|
@ -148,18 +148,10 @@ private:
|
||||
|
||||
/// Syncs the fog states to match the PICA register
|
||||
void SyncFogColor();
|
||||
void SyncFogLUT();
|
||||
|
||||
/// Sync the procedural texture noise configuration to match the PICA register
|
||||
void SyncProcTexNoise();
|
||||
|
||||
/// Sync the procedural texture lookup tables
|
||||
void SyncProcTexNoiseLUT();
|
||||
void SyncProcTexColorMap();
|
||||
void SyncProcTexAlphaMap();
|
||||
void SyncProcTexLUT();
|
||||
void SyncProcTexDiffLUT();
|
||||
|
||||
/// Syncs the alpha test states to match the PICA register
|
||||
void SyncAlphaTest();
|
||||
|
||||
@ -190,9 +182,6 @@ private:
|
||||
/// Syncs the lighting global ambient color to match the PICA register
|
||||
void SyncGlobalAmbient();
|
||||
|
||||
/// Syncs the lighting lookup tables
|
||||
void SyncLightingLUT(unsigned index);
|
||||
|
||||
/// Syncs the specified light's specular 0 color to match the PICA register
|
||||
void SyncLightSpecular0(int light_index);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user