mirror of
https://github.com/open-goal/jak-project.git
synced 2024-10-20 11:26:18 -04:00
[graphics] merc2 fix, texture crash bug fix (#1385)
* [graphics] merc2 fix, texture crash bug fix * still boot if deci2 fails to init
This commit is contained in:
parent
750255e5b2
commit
dad84ec249
|
@ -249,7 +249,7 @@ std::vector<EyeRenderer::SingleEyeDraws> EyeRenderer::get_draws(DmaFollower& dma
|
|||
pair_idx = y0 / SINGLE_EYE_SIZE;
|
||||
l_draw.pair = pair_idx;
|
||||
r_draw.pair = pair_idx;
|
||||
if (tex0->get_data_ptr()) {
|
||||
if (tex0 && tex0->get_data_ptr()) {
|
||||
u32 tex_val;
|
||||
memcpy(&tex_val, tex0->get_data_ptr(), 4);
|
||||
l_draw.clear_color = tex_val;
|
||||
|
@ -280,7 +280,7 @@ std::vector<EyeRenderer::SingleEyeDraws> EyeRenderer::get_draws(DmaFollower& dma
|
|||
AdgifHelper adgif1(adgif1_dma.data + 16);
|
||||
auto tex1 = render_state->texture_pool->lookup_gpu_texture(adgif1.tex0().tbp0());
|
||||
|
||||
{
|
||||
if (tex1 && tex1->get_data_ptr()) {
|
||||
l_draw.pupil = read_eye_draw(dma);
|
||||
r_draw.pupil = read_eye_draw(dma);
|
||||
l_draw.pupil_tex = tex1;
|
||||
|
|
|
@ -151,13 +151,16 @@ SkyBlendStats SkyBlendCPU::do_sky_blends(DmaFollower& dma,
|
|||
}
|
||||
*/
|
||||
if (tex->get_data_ptr()) {
|
||||
if (is_first_draw) {
|
||||
blend_sky_initial_fast(intensity, m_texture_data[buffer_idx].data(), tex->get_data_ptr(),
|
||||
tex->data_size());
|
||||
} else {
|
||||
blend_sky_fast(intensity, m_texture_data[buffer_idx].data(), tex->get_data_ptr(),
|
||||
tex->data_size());
|
||||
if (m_texture_data[buffer_idx].size() == tex->data_size()) {
|
||||
if (is_first_draw) {
|
||||
blend_sky_initial_fast(intensity, m_texture_data[buffer_idx].data(), tex->get_data_ptr(),
|
||||
m_texture_data[buffer_idx].size());
|
||||
} else {
|
||||
blend_sky_fast(intensity, m_texture_data[buffer_idx].data(), tex->get_data_ptr(),
|
||||
m_texture_data[buffer_idx].size());
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer_idx == 0) {
|
||||
if (is_first_draw) {
|
||||
stats.sky_draws++;
|
||||
|
|
|
@ -8,9 +8,23 @@ Merc2::Merc2(const std::string& name, BucketId my_id) : BucketRenderer(name, my_
|
|||
|
||||
glGenBuffers(1, &m_bones_buffer);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, m_bones_buffer);
|
||||
glBufferData(GL_UNIFORM_BUFFER, MAX_SHADER_BONES * sizeof(MercMat), nullptr, GL_DYNAMIC_DRAW);
|
||||
glBufferData(GL_UNIFORM_BUFFER, MAX_SHADER_BONE_VECTORS * sizeof(math::Vector4f), nullptr,
|
||||
GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
|
||||
GLint val;
|
||||
glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &val);
|
||||
if (val <= 16) {
|
||||
// somehow doubt this can happen, but just in case
|
||||
m_opengl_buffer_alignment = 1;
|
||||
} else {
|
||||
m_opengl_buffer_alignment = val / 16; // number of bone vectors
|
||||
if (m_opengl_buffer_alignment * 16 != (u32)val) {
|
||||
ASSERT_MSG(false,
|
||||
fmt::format("opengl uniform buffer alignment is {}, which is strange\n", val));
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_LEVELS; i++) {
|
||||
auto& draws = m_level_draw_buckets.emplace_back();
|
||||
draws.draws.resize(MAX_DRAWS_PER_LEVEL);
|
||||
|
@ -115,48 +129,6 @@ void Merc2::render(DmaFollower& dma, SharedRenderState* render_state, ScopedProf
|
|||
flush_draw_buckets(render_state, prof);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Queue up some bones to be included in the bone buffer.
|
||||
* Returns the index of the first bone.
|
||||
*/
|
||||
u32 Merc2::alloc_bones(int count, float scale) {
|
||||
ASSERT(count + m_next_free_bone <= MAX_SHADER_BONES);
|
||||
|
||||
u32 first_bone = m_next_free_bone;
|
||||
|
||||
// model should have under 128 bones.
|
||||
ASSERT(count <= MAX_SKEL_BONES);
|
||||
|
||||
// iterate over each bone we need
|
||||
for (int i = 0; i < count; i++) {
|
||||
auto& skel_mat = m_skel_matrix_buffer[i];
|
||||
auto& shader_mat = m_shader_matrix_buffer[m_next_free_bone++];
|
||||
|
||||
// scale the transformation matrix (todo: can we move this to the extraction)
|
||||
// and copy to the large bone buffer.
|
||||
for (int j = 0; j < 3; j++) {
|
||||
shader_mat.tmat[j] = skel_mat.tmat[j] * scale;
|
||||
}
|
||||
shader_mat.tmat[3] = skel_mat.tmat[3];
|
||||
|
||||
for (int j = 0; j < 3; j++) {
|
||||
shader_mat.nmat[j] = skel_mat.nmat[j];
|
||||
}
|
||||
|
||||
// we could include the effect of the perspective matrix here.
|
||||
// for (int j = 0; j < 3; j++) {
|
||||
// tbone_buffer[i][j] = vf15.elementwise_multiply(bone_mat[j]);
|
||||
// tbone_buffer[i][j].w() += p.w() * bone_mat[j].z();
|
||||
// tbone_buffer[i][j] *= scale;
|
||||
// }
|
||||
//
|
||||
// tbone_buffer[i][3] = vf15.elementwise_multiply(bone_mat[3]) +
|
||||
// m_low_memory.perspective[3]; tbone_buffer[i][3].w() += p.w() * bone_mat[3].z();
|
||||
}
|
||||
|
||||
return first_bone;
|
||||
}
|
||||
|
||||
u32 Merc2::alloc_lights(const VuLights& lights) {
|
||||
ASSERT(m_next_free_light < MAX_LIGHTS);
|
||||
m_stats.num_lights++;
|
||||
|
@ -404,6 +376,55 @@ void Merc2::handle_merc_chain(DmaFollower& dma,
|
|||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Queue up some bones to be included in the bone buffer.
|
||||
* Returns the index of the first bone vector.
|
||||
*/
|
||||
u32 Merc2::alloc_bones(int count, float scale) {
|
||||
u32 first_bone_vector = m_next_free_bone_vector;
|
||||
ASSERT(count * 8 + first_bone_vector <= MAX_SHADER_BONE_VECTORS);
|
||||
|
||||
// model should have under 128 bones.
|
||||
ASSERT(count <= MAX_SKEL_BONES);
|
||||
|
||||
// iterate over each bone we need
|
||||
for (int i = 0; i < count; i++) {
|
||||
auto& skel_mat = m_skel_matrix_buffer[i];
|
||||
auto* shader_mat = &m_shader_bone_vector_buffer[m_next_free_bone_vector];
|
||||
int bv = 0;
|
||||
|
||||
// scale the transformation matrix (todo: can we move this to the extraction)
|
||||
// and copy to the large bone buffer.
|
||||
for (int j = 0; j < 3; j++) {
|
||||
shader_mat[bv++] = skel_mat.tmat[j] * scale;
|
||||
}
|
||||
shader_mat[bv++] = skel_mat.tmat[3];
|
||||
|
||||
for (int j = 0; j < 3; j++) {
|
||||
shader_mat[bv++] = skel_mat.nmat[j];
|
||||
}
|
||||
|
||||
// we could include the effect of the perspective matrix here.
|
||||
// for (int j = 0; j < 3; j++) {
|
||||
// tbone_buffer[i][j] = vf15.elementwise_multiply(bone_mat[j]);
|
||||
// tbone_buffer[i][j].w() += p.w() * bone_mat[j].z();
|
||||
// tbone_buffer[i][j] *= scale;
|
||||
// }
|
||||
//
|
||||
// tbone_buffer[i][3] = vf15.elementwise_multiply(bone_mat[3]) +
|
||||
// m_low_memory.perspective[3]; tbone_buffer[i][3].w() += p.w() * bone_mat[3].z();
|
||||
|
||||
m_next_free_bone_vector += 8;
|
||||
}
|
||||
|
||||
auto b0 = m_next_free_bone_vector;
|
||||
m_next_free_bone_vector += m_opengl_buffer_alignment - 1;
|
||||
m_next_free_bone_vector /= m_opengl_buffer_alignment;
|
||||
m_next_free_bone_vector *= m_opengl_buffer_alignment;
|
||||
ASSERT(b0 <= m_next_free_bone_vector);
|
||||
ASSERT(first_bone_vector + count * 8 <= m_next_free_bone_vector);
|
||||
return first_bone_vector;
|
||||
}
|
||||
/*!
|
||||
* Flush a model to draw buckets
|
||||
*/
|
||||
|
@ -415,16 +436,16 @@ void Merc2::flush_pending_model(SharedRenderState* render_state, ScopedProfilerN
|
|||
const LevelData* lev = m_current_model->level;
|
||||
const tfrag3::MercModel* model = m_current_model->model;
|
||||
|
||||
int bone_count = (model->max_bones + 31) & (~31); // todo
|
||||
// int bone_count = 128;
|
||||
int bone_count = model->max_bones + 1;
|
||||
|
||||
if (m_next_free_light >= MAX_LIGHTS) {
|
||||
fmt::print("MERC2 out of lights, consider increasing MAX_LIGHTS\n");
|
||||
flush_draw_buckets(render_state, prof);
|
||||
}
|
||||
|
||||
if (m_next_free_bone + bone_count > MAX_SHADER_BONES) {
|
||||
fmt::print("MERC2 out of bones, consider increasing MAX_SHADER_BONES\n");
|
||||
if (m_next_free_bone_vector + m_opengl_buffer_alignment + bone_count * 8 >
|
||||
MAX_SHADER_BONE_VECTORS) {
|
||||
fmt::print("MERC2 out of bones, consider increasing MAX_SHADER_BONE_VECTORS\n");
|
||||
flush_draw_buckets(render_state, prof);
|
||||
}
|
||||
|
||||
|
@ -560,11 +581,11 @@ void Merc2::flush_draw_buckets(SharedRenderState* /*render_state*/, ScopedProfil
|
|||
|
||||
int last_tex = -1;
|
||||
int last_light = -1;
|
||||
m_stats.num_bones_uploaded += m_next_free_bone;
|
||||
m_stats.num_bones_uploaded += m_next_free_bone_vector;
|
||||
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, m_bones_buffer);
|
||||
glBufferSubData(GL_UNIFORM_BUFFER, 0, m_next_free_bone * sizeof(MercMat),
|
||||
m_shader_matrix_buffer);
|
||||
glBufferSubData(GL_UNIFORM_BUFFER, 0, m_next_free_bone_vector * sizeof(math::Vector4f),
|
||||
m_shader_bone_vector_buffer);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
|
||||
for (u32 di = 0; di < lev_bucket.next_free_draw; di++) {
|
||||
|
@ -591,14 +612,14 @@ void Merc2::flush_draw_buckets(SharedRenderState* /*render_state*/, ScopedProfil
|
|||
|
||||
prof.add_draw_call();
|
||||
prof.add_tri(draw.num_triangles);
|
||||
glBindBufferRange(GL_UNIFORM_BUFFER, 1, m_bones_buffer, sizeof(MercMat) * draw.first_bone,
|
||||
128 * sizeof(MercMat));
|
||||
glBindBufferRange(GL_UNIFORM_BUFFER, 1, m_bones_buffer,
|
||||
sizeof(math::Vector4f) * draw.first_bone, 128 * sizeof(ShaderMercMat));
|
||||
glDrawElements(GL_TRIANGLE_STRIP, draw.index_count, GL_UNSIGNED_INT,
|
||||
(void*)(sizeof(u32) * draw.first_index));
|
||||
}
|
||||
}
|
||||
|
||||
m_next_free_light = 0;
|
||||
m_next_free_bone = 0;
|
||||
m_next_free_bone_vector = 0;
|
||||
m_next_free_level_bucket = 0;
|
||||
}
|
||||
|
|
|
@ -65,14 +65,21 @@ class Merc2 : public BucketRenderer {
|
|||
math::Vector4f nmat[3];
|
||||
};
|
||||
|
||||
struct ShaderMercMat {
|
||||
math::Vector4f tmat[4];
|
||||
math::Vector4f nmat[3];
|
||||
math::Vector4f pad;
|
||||
};
|
||||
|
||||
static constexpr int MAX_SKEL_BONES = 128;
|
||||
static constexpr int MAX_SHADER_BONES = 8192;
|
||||
static constexpr int BONE_VECTORS_PER_BONE = 7;
|
||||
static constexpr int MAX_SHADER_BONE_VECTORS = 8192; // ??
|
||||
|
||||
static constexpr int MAX_LEVELS = 3;
|
||||
static constexpr int MAX_DRAWS_PER_LEVEL = 1024;
|
||||
|
||||
MercMat m_shader_matrix_buffer[MAX_SHADER_BONES];
|
||||
MercMat m_skel_matrix_buffer[MAX_SKEL_BONES];
|
||||
math::Vector4f m_shader_bone_vector_buffer[MAX_SHADER_BONE_VECTORS];
|
||||
ShaderMercMat m_skel_matrix_buffer[MAX_SKEL_BONES];
|
||||
|
||||
struct {
|
||||
GLuint light_direction[3];
|
||||
|
@ -137,7 +144,8 @@ class Merc2 : public BucketRenderer {
|
|||
|
||||
std::vector<LevelDrawBucket> m_level_draw_buckets;
|
||||
u32 m_next_free_level_bucket = 0;
|
||||
u32 m_next_free_bone = 0;
|
||||
u32 m_next_free_bone_vector = 0;
|
||||
size_t m_opengl_buffer_alignment = 0;
|
||||
|
||||
void flush_draw_buckets(SharedRenderState* render_state, ScopedProfilerNode& prof);
|
||||
};
|
||||
|
|
|
@ -36,6 +36,7 @@ out float fog;
|
|||
struct MercMatrixData {
|
||||
mat4 X;
|
||||
mat3 R;
|
||||
vec4 pad;
|
||||
};
|
||||
|
||||
layout (std140, binding = 1) uniform ub_bones {
|
||||
|
|
|
@ -86,14 +86,15 @@ void deci2_runner(SystemThreadInterface& iface) {
|
|||
lg::debug("[DECI2] Waiting for EE to register protos");
|
||||
server.wait_for_protos_ready();
|
||||
// then allow the server to accept connections
|
||||
if (!server.init_server()) {
|
||||
ASSERT_MSG(false, "[DECI2] Server not initialized even if protocols are ready, aborting");
|
||||
bool server_ok = server.init_server();
|
||||
if (!server_ok) {
|
||||
lg::error("[DECI2] failed to initialize, REPL will not work.\n");
|
||||
}
|
||||
|
||||
lg::debug("[DECI2] Waiting for listener...");
|
||||
bool saw_listener = false;
|
||||
while (!iface.get_want_exit()) {
|
||||
if (server.is_client_connected()) {
|
||||
if (server_ok && server.is_client_connected()) {
|
||||
if (!saw_listener) {
|
||||
lg::debug("[DECI2] Connected!");
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue