mirror of
https://github.com/open-goal/jak-project
synced 2026-06-05 19:28:31 -04:00
f0b46ff2e5
A few minor fixes: - Fix crash in overlord3 during final boss https://github.com/open-goal/jak-project/issues/3605 - Update goal_src for `scene-actor.gc`, which was not updated after a bug fix for decompiling skelgroups, making some cutscene actors invisible due to using the wrong joint for culling checks. - Stop using `-1` as an invalid value for texture id's in Merc.cpp. This could sometimes cause Merc2.cpp to accidentally skip updating the OpenGL texture. This fixes the bug where skull gems sometimes didn't have the animated textures.
125 lines
4.5 KiB
C++
125 lines
4.5 KiB
C++
#include "TextureUploadHandler.h"
|
|
|
|
#include "common/global_profiler/GlobalProfiler.h"
|
|
#include "common/log/log.h"
|
|
|
|
#include "game/graphics/opengl_renderer/EyeRenderer.h"
|
|
#include "game/graphics/pipelines/opengl.h"
|
|
|
|
#include "fmt/core.h"
|
|
#include "third-party/imgui/imgui.h"
|
|
|
|
TextureUploadHandler::TextureUploadHandler(const std::string& name,
|
|
int my_id,
|
|
std::shared_ptr<TextureAnimator> texture_animator,
|
|
bool add_direct)
|
|
: BucketRenderer(name, my_id), m_texture_animator(texture_animator) {
|
|
if (add_direct) {
|
|
m_direct = std::make_unique<DirectRenderer>(name, my_id, 1024 * 6);
|
|
m_direct->set_mipmap(false); // try rm
|
|
}
|
|
}
|
|
|
|
void TextureUploadHandler::render(DmaFollower& dma,
|
|
SharedRenderState* render_state,
|
|
ScopedProfilerNode& prof) {
|
|
// this is the data we get from the PC Port modification.
|
|
m_upload_count = 0;
|
|
std::vector<TextureUpload> uploads;
|
|
if (m_direct) {
|
|
m_direct->reset_state();
|
|
}
|
|
// loop through all data, grabbing buckets
|
|
while (dma.current_tag_offset() != render_state->next_bucket) {
|
|
auto dma_tag = dma.current_tag();
|
|
|
|
auto vif0 = dma.current_tag_vifcode0();
|
|
if (vif0.kind == VifCode::Kind::PC_PORT) {
|
|
if (vif0.immediate == 12) {
|
|
dma.read_and_advance();
|
|
auto p = scoped_prof("texture-animator");
|
|
// note: if both uploads and animator write to the pool, do uploads before the animator.
|
|
flush_uploads(uploads, render_state);
|
|
uploads.clear();
|
|
if (m_direct) {
|
|
m_direct->flush_pending(render_state, prof);
|
|
}
|
|
m_texture_animator->handle_texture_anim_data(dma, (const u8*)render_state->ee_main_memory,
|
|
render_state->texture_pool.get(),
|
|
render_state->frame_idx);
|
|
if (m_direct) {
|
|
m_direct->lookup_textures_again(render_state);
|
|
m_direct->reinitialize_gl_state();
|
|
}
|
|
}
|
|
}
|
|
// does it look like data to do eye rendering?
|
|
if (dma_tag.qwc == (128 / 16)) {
|
|
// note: these uploads may have texture that we need for eye rendering.
|
|
flush_uploads(uploads, render_state);
|
|
render_state->eye_renderer->handle_eye_dma2(dma, render_state, prof);
|
|
uploads.clear();
|
|
}
|
|
|
|
auto data = dma.read_and_advance();
|
|
if (data.size_bytes == 0 && data.vif0() == 0 && data.vif1() == 0) {
|
|
continue;
|
|
}
|
|
|
|
if (data.size_bytes == 16 && data.vifcode0().kind == VifCode::Kind::PC_PORT &&
|
|
data.vif1() == 3) {
|
|
TextureUpload upload_data;
|
|
memcpy(&upload_data, data.data, sizeof(upload_data));
|
|
uploads.push_back(upload_data);
|
|
continue;
|
|
}
|
|
|
|
if (dma_tag.kind == DmaTag::Kind::CALL) {
|
|
dma.read_and_advance(); // call
|
|
dma.read_and_advance(); // cnt
|
|
dma.read_and_advance(); // ret
|
|
// on next
|
|
ASSERT(dma.current_tag_offset() == render_state->next_bucket);
|
|
} else if (m_direct) {
|
|
if (data.vifcode0().kind == VifCode::Kind::DIRECT ||
|
|
data.vifcode1().kind == VifCode::Kind::DIRECT) {
|
|
m_direct->render_vif(data.vif0(), data.vif1(), data.data, data.size_bytes, render_state,
|
|
prof);
|
|
}
|
|
}
|
|
}
|
|
|
|
flush_uploads(uploads, render_state);
|
|
if (m_direct) {
|
|
m_direct->flush_pending(render_state, prof);
|
|
}
|
|
}
|
|
|
|
void TextureUploadHandler::flush_uploads(std::vector<TextureUpload>& uploads,
|
|
SharedRenderState* render_state) {
|
|
auto p = scoped_prof("flush-uploads");
|
|
if (m_fake_uploads) {
|
|
uploads.clear();
|
|
} else {
|
|
m_upload_count += uploads.size();
|
|
// NOTE: we don't actually copy the textures in the dma chain copying because they aren't
|
|
// reference by DMA tag. So there's the potential for race conditions if the game gets messed
|
|
// up and corrupts the texture memory.
|
|
const u8* ee_mem = (const u8*)render_state->ee_main_memory;
|
|
for (auto& upload : uploads) {
|
|
render_state->texture_pool->handle_upload_now(ee_mem + upload.page, upload.mode, ee_mem,
|
|
render_state->offset_of_s7, m_my_id == 999);
|
|
}
|
|
}
|
|
}
|
|
void TextureUploadHandler::draw_debug_window() {
|
|
ImGui::Checkbox("Fake Uploads", &m_fake_uploads);
|
|
ImGui::Text("Uploads: %d", m_upload_count);
|
|
if (m_direct) {
|
|
m_direct->draw_debug_window();
|
|
}
|
|
}
|
|
|
|
bool TextureUploadHandler::empty() const {
|
|
return m_upload_count == 0;
|
|
} |