Skip to content

Commit

Permalink
VDP2 cache WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
rtoumazet committed Mar 14, 2024
1 parent 5d38a1e commit f1cfdc7
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 44 deletions.
158 changes: 114 additions & 44 deletions saturnin/src/video/opengl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -412,9 +412,15 @@ void Opengl::displayFramebuffer(core::EmulatorContext& state) {
}

void Opengl::renderToAvailableFbo(const FboKey& key, const PartsList& parts_list) {
const auto index = getAvailableFboIndex();
const auto& [priority, layer] = key;
const auto index = getAvailableFboIndex();
if (!index) { return; }

bindFbo(fbo_pool_[*index].first);
renderParts(parts_list);
unbindFbo();

fbo_pool_status_[*index] = FboStatus::reuse;
fbo_key_to_fbo_pool_index_[key] = *index;
}

void Opengl::clearFbos() {
Expand Down Expand Up @@ -461,6 +467,59 @@ auto Opengl::getAvailableFboIndex() -> std::optional<u8> {
}
}

void Opengl::renderParts(const PartsList& parts_list) {
if (!parts_list.empty()) {
const auto [vao, vertex_buffer] = initializeVao(ShaderName::textured);

glUseProgram(program_shader_);
glBindVertexArray(vao); // binding VAO
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); // binding vertex buffer

// Calculating the ortho projection matrix
const auto proj_matrix = calculateDisplayViewportMatrix();

// Sending the ortho projection matrix to the shader
const auto uni_proj_matrix = glGetUniformLocation(program_shader_, "proj_matrix");
glUniformMatrix4fv(uni_proj_matrix, 1, GL_FALSE, glm::value_ptr(proj_matrix));

glActiveTexture(GLenum::GL_TEXTURE0);
const auto sampler_loc = glGetUniformLocation(program_shader_, "sampler");

glUniform1i(sampler_loc, 0);
glBindTexture(GL_TEXTURE_2D_ARRAY, texture_array_id_);

const auto texture_used_loc = glGetUniformLocation(program_shader_, "is_texture_used");

auto elements_buffer = u32{};
glGenBuffers(1, &elements_buffer); // This buffer will be used to send indices data to the GPU
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elements_buffer);

const auto&& [indices, draw_ranges] = generateVertexIndicesAndDrawRanges(parts_list);
const auto vertexes = readVertexes(parts_list);

// Sending data to the GPU
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(u32) * indices.size(), indices.data(), GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * vertexes.size(), vertexes.data(), GL_STATIC_DRAW);

for (const auto& range : draw_ranges) {
const auto is_texture_used = GLboolean(range.is_textured);
glUniform1i(texture_used_loc, is_texture_used);

glDrawRangeElements(range.primitive,
range.vertex_array_start,
range.vertex_array_end,
range.indices_nb,
GL_UNSIGNED_INT,
static_cast<GLuint*>(nullptr) + range.indices_array_start);
}

gl::glDeleteBuffers(1, &vertex_buffer);
gl::glDeleteVertexArrays(1, &vao);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
gl::glDeleteBuffers(1, &elements_buffer);
}
}

void Opengl::render() {
if constexpr (uses_fbo) {
GlobalPartsList global_parts_list;
Expand All @@ -480,13 +539,23 @@ void Opengl::render() {
renderToAvailableFbo(key, parts);
}

// :TODO: Render the FBOs to the framebuffer
preRender();

{
// :TODO: Render the FBOs to the current framebuffer
std::ranges::reverse_view rv{fbo_key_to_fbo_pool_index_};
for (const auto& [key, index] : rv) {
fbo_pool_[index].second;
}

postRender();

const auto notifyMainThread = [&]() {
std::lock_guard lk(parts_list_mutex_);
GlobalPartsList().swap(global_parts_list);
data_condition_.notify_one();
}
};

notifyMainThread();

} else {
PartsList parts_list;
Expand All @@ -497,57 +566,58 @@ void Opengl::render() {
if (!parts_list_.empty()) { parts_list = std::move(parts_list_); }
}

if (!parts_list.empty()) {
const auto [vao, vertex_buffer] = initializeVao(ShaderName::textured);
renderParts(parts_list);
// if (!parts_list.empty()) {
// const auto [vao, vertex_buffer] = initializeVao(ShaderName::textured);

glUseProgram(program_shader_);
glBindVertexArray(vao); // binding VAO
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); // binding vertex buffer
// glUseProgram(program_shader_);
// glBindVertexArray(vao); // binding VAO
// glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); // binding vertex buffer

// Calculating the ortho projection matrix
const auto proj_matrix = calculateDisplayViewportMatrix();
// // Calculating the ortho projection matrix
// const auto proj_matrix = calculateDisplayViewportMatrix();

// Sending the ortho projection matrix to the shader
const auto uni_proj_matrix = glGetUniformLocation(program_shader_, "proj_matrix");
glUniformMatrix4fv(uni_proj_matrix, 1, GL_FALSE, glm::value_ptr(proj_matrix));
// // Sending the ortho projection matrix to the shader
// const auto uni_proj_matrix = glGetUniformLocation(program_shader_, "proj_matrix");
// glUniformMatrix4fv(uni_proj_matrix, 1, GL_FALSE, glm::value_ptr(proj_matrix));

glActiveTexture(GLenum::GL_TEXTURE0);
const auto sampler_loc = glGetUniformLocation(program_shader_, "sampler");
// glActiveTexture(GLenum::GL_TEXTURE0);
// const auto sampler_loc = glGetUniformLocation(program_shader_, "sampler");

glUniform1i(sampler_loc, 0);
glBindTexture(GL_TEXTURE_2D_ARRAY, texture_array_id_);
// glUniform1i(sampler_loc, 0);
// glBindTexture(GL_TEXTURE_2D_ARRAY, texture_array_id_);

const auto texture_used_loc = glGetUniformLocation(program_shader_, "is_texture_used");
// const auto texture_used_loc = glGetUniformLocation(program_shader_, "is_texture_used");

auto elements_buffer = u32{};
glGenBuffers(1, &elements_buffer); // This buffer will be used to send indices data to the GPU
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elements_buffer);
// auto elements_buffer = u32{};
// glGenBuffers(1, &elements_buffer); // This buffer will be used to send indices data to the GPU
// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elements_buffer);

const auto&& [indices, draw_ranges] = generateVertexIndicesAndDrawRanges(parts_list);
const auto vertexes = readVertexes(parts_list);
// const auto&& [indices, draw_ranges] = generateVertexIndicesAndDrawRanges(parts_list);
// const auto vertexes = readVertexes(parts_list);

// Sending data to the GPU
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(u32) * indices.size(), indices.data(), GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * vertexes.size(), vertexes.data(), GL_STATIC_DRAW);
// // Sending data to the GPU
// glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(u32) * indices.size(), indices.data(), GL_STATIC_DRAW);
// glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * vertexes.size(), vertexes.data(), GL_STATIC_DRAW);

for (const auto& range : draw_ranges) {
const auto is_texture_used = GLboolean(range.is_textured);
glUniform1i(texture_used_loc, is_texture_used);
// for (const auto& range : draw_ranges) {
// const auto is_texture_used = GLboolean(range.is_textured);
// glUniform1i(texture_used_loc, is_texture_used);

glDrawRangeElements(range.primitive,
range.vertex_array_start,
range.vertex_array_end,
range.indices_nb,
GL_UNSIGNED_INT,
static_cast<GLuint*>(nullptr) + range.indices_array_start);
}
// glDrawRangeElements(range.primitive,
// range.vertex_array_start,
// range.vertex_array_end,
// range.indices_nb,
// GL_UNSIGNED_INT,
// static_cast<GLuint*>(nullptr) + range.indices_array_start);
// }

gl::glDeleteBuffers(1, &vertex_buffer);
gl::glDeleteVertexArrays(1, &vao);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
gl::glDeleteBuffers(1, &elements_buffer);
// Texture::cleanCache(this);
}
// gl::glDeleteBuffers(1, &vertex_buffer);
// gl::glDeleteVertexArrays(1, &vao);
// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
// gl::glDeleteBuffers(1, &elements_buffer);
// // Texture::cleanCache(this);
//}

{
std::lock_guard lk(parts_list_mutex_);
Expand Down
13 changes: 13 additions & 0 deletions saturnin/src/video/opengl.h
Original file line number Diff line number Diff line change
Expand Up @@ -865,6 +865,19 @@ class Opengl {

auto getAvailableFboIndex() -> std::optional<u8>;

////////////////////////////////////////////////////////////////////////////////////////////////////
/// \fn void Opengl::renderParts(const PartsList& parts_list);
///
/// \brief Renders the parts described by parts_list to the previously bound FBO.
///
/// \author Runik
/// \date 09/03/2024
///
/// \param parts_list List of parts.
////////////////////////////////////////////////////////////////////////////////////////////////////

void renderParts(const PartsList& parts_list);

core::Config* config_; ///< Configuration object.

FboGlobalList fbo_global_list_; ///< List of framebuffer objects used in the program.
Expand Down

0 comments on commit f1cfdc7

Please sign in to comment.