mirror of
https://github.com/Lime3DS/Lime3DS
synced 2024-12-25 16:42:39 -06:00
gl_rasterizer: Inline texture buffer uploads.
This commit is contained in:
parent
8a8c6f059f
commit
298ebe3752
2 changed files with 78 additions and 112 deletions
|
@ -1725,21 +1725,6 @@ void RasterizerOpenGL::SyncFogColor() {
|
||||||
uniform_block_data.dirty = true;
|
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() {
|
void RasterizerOpenGL::SyncProcTexNoise() {
|
||||||
const auto& regs = Pica::g_state.regs.texturing;
|
const auto& regs = Pica::g_state.regs.texturing;
|
||||||
uniform_block_data.data.proctex_noise_f = {
|
uniform_block_data.data.proctex_noise_f = {
|
||||||
|
@ -1758,70 +1743,6 @@ void RasterizerOpenGL::SyncProcTexNoise() {
|
||||||
uniform_block_data.dirty = true;
|
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() {
|
void RasterizerOpenGL::SyncAlphaTest() {
|
||||||
const auto& regs = Pica::g_state.regs;
|
const auto& regs = Pica::g_state.regs;
|
||||||
if (regs.framebuffer.output_merger.alpha_test.ref != uniform_block_data.data.alphatest_ref) {
|
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) {
|
void RasterizerOpenGL::SyncLightSpecular0(int light_index) {
|
||||||
auto color = PicaToGL::LightColor(Pica::g_state.regs.lighting.light[light_index].specular_0);
|
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) {
|
if (color != uniform_block_data.data.light_src[light_index].specular_0) {
|
||||||
|
@ -2028,44 +1934,115 @@ void RasterizerOpenGL::SyncAndUploadLUTs() {
|
||||||
// Sync the lighting luts
|
// Sync the lighting luts
|
||||||
for (unsigned index = 0; index < uniform_block_data.lut_dirty.size(); index++) {
|
for (unsigned index = 0; index < uniform_block_data.lut_dirty.size(); index++) {
|
||||||
if (uniform_block_data.lut_dirty[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;
|
uniform_block_data.lut_dirty[index] = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sync the fog lut
|
// Sync the fog lut
|
||||||
if (uniform_block_data.fog_lut_dirty) {
|
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;
|
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
|
// Sync the proctex noise lut
|
||||||
if (uniform_block_data.proctex_noise_lut_dirty) {
|
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;
|
uniform_block_data.proctex_noise_lut_dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sync the proctex color map
|
// Sync the proctex color map
|
||||||
if (uniform_block_data.proctex_color_map_dirty) {
|
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;
|
uniform_block_data.proctex_color_map_dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sync the proctex alpha map
|
// Sync the proctex alpha map
|
||||||
if (uniform_block_data.proctex_alpha_map_dirty) {
|
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;
|
uniform_block_data.proctex_alpha_map_dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sync the proctex lut
|
// Sync the proctex lut
|
||||||
if (uniform_block_data.proctex_lut_dirty) {
|
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;
|
uniform_block_data.proctex_lut_dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sync the proctex difference lut
|
// Sync the proctex difference lut
|
||||||
if (uniform_block_data.proctex_diff_lut_dirty) {
|
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;
|
uniform_block_data.proctex_diff_lut_dirty = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,18 +148,10 @@ private:
|
||||||
|
|
||||||
/// Syncs the fog states to match the PICA register
|
/// Syncs the fog states to match the PICA register
|
||||||
void SyncFogColor();
|
void SyncFogColor();
|
||||||
void SyncFogLUT();
|
|
||||||
|
|
||||||
/// Sync the procedural texture noise configuration to match the PICA register
|
/// Sync the procedural texture noise configuration to match the PICA register
|
||||||
void SyncProcTexNoise();
|
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
|
/// Syncs the alpha test states to match the PICA register
|
||||||
void SyncAlphaTest();
|
void SyncAlphaTest();
|
||||||
|
|
||||||
|
@ -190,9 +182,6 @@ private:
|
||||||
/// Syncs the lighting global ambient color to match the PICA register
|
/// Syncs the lighting global ambient color to match the PICA register
|
||||||
void SyncGlobalAmbient();
|
void SyncGlobalAmbient();
|
||||||
|
|
||||||
/// Syncs the lighting lookup tables
|
|
||||||
void SyncLightingLUT(unsigned index);
|
|
||||||
|
|
||||||
/// Syncs the specified light's specular 0 color to match the PICA register
|
/// Syncs the specified light's specular 0 color to match the PICA register
|
||||||
void SyncLightSpecular0(int light_index);
|
void SyncLightSpecular0(int light_index);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue