use common ocean renderer for mid too (#1241)

This commit is contained in:
water111 2022-03-18 20:58:53 -04:00 committed by GitHub
parent da00b1ff13
commit 44459757b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 417 additions and 224 deletions

View File

@ -4010,7 +4010,16 @@
[249, "a0", "(pointer gs-reg64)"],
[251, "a0", "(pointer gs-alpha)"],
[253, "a0", "(pointer gs-reg64)"],
[[270, 273], "v1", "dma-packet"]
[[270, 273], "v1", "dma-packet"],
[[312, 316], "a0", "dma-packet"],
[[322, 325], "a0", "gs-gif-tag"],
[330, "a0", "(pointer gs-zbuf)"],
[332, "a0", "(pointer gs-reg)"],
[334, "a0", "(pointer gs-test)"],
[336, "a0", "(pointer gs-reg64)"],
[338, "a0", "(pointer gs-alpha)"],
[340, "a0", "(pointer gs-reg64)"],
[[357, 360], "v1", "dma-packet"]
],
"(event target-racing-start)": [

View File

@ -266,7 +266,7 @@ void CommonOceanRenderer::handle_near_adgif(const u8* data, u32 offset, u32 coun
}
}
void CommonOceanRenderer::flush(SharedRenderState* render_state, ScopedProfilerNode& prof) {
void CommonOceanRenderer::flush_near(SharedRenderState* render_state, ScopedProfilerNode& prof) {
glBindVertexArray(m_ogl.vao);
glBindBuffer(GL_ARRAY_BUFFER, m_ogl.vertex_buffer);
glEnable(GL_PRIMITIVE_RESTART);
@ -334,4 +334,191 @@ void CommonOceanRenderer::flush(SharedRenderState* render_state, ScopedProfilerN
prof.add_draw_call();
prof.add_tri(m_next_free_index[bucket]);
}
}
void CommonOceanRenderer::kick_from_mid(const u8* data) {
bool eop = false;
u32 offset = 0;
while (!eop) {
GifTag tag(data + offset);
offset += 16;
// unpack registers.
// faster to do it once outside of the nloop loop.
GifTag::RegisterDescriptor reg_desc[16];
u32 nreg = tag.nreg();
for (u32 i = 0; i < nreg; i++) {
reg_desc[i] = tag.reg(i);
}
auto format = tag.flg();
if (format == GifTag::Format::PACKED) {
if (tag.nreg() == 1) {
ASSERT(!tag.pre());
ASSERT(tag.nloop() == 5);
handle_mid_adgif(data, offset);
offset += 5 * 16;
} else {
ASSERT(tag.nreg() == 3);
ASSERT(tag.pre());
m_current_bucket = GsPrim(tag.prim()).abe() ? 1 : 0;
int count = tag.nloop();
if (GsPrim(tag.prim()).kind() == GsPrim::Kind::TRI_STRIP) {
handle_near_vertex_gif_data_strip(data, offset, tag.nloop());
} else {
handle_near_vertex_gif_data_fan(data, offset, tag.nloop());
}
offset += 3 * 16 * count;
// todo handle.
}
} else {
ASSERT(false); // format not packed or reglist.
}
eop = tag.eop();
}
}
void CommonOceanRenderer::handle_mid_adgif(const u8* data, u32 offset) {
u32 most_recent_tbp = 0;
for (u32 i = 0; i < 5; i++) {
u64 value;
GsRegisterAddress addr;
memcpy(&value, data + offset + 16 * i, sizeof(u64));
memcpy(&addr, data + offset + 16 * i + 8, sizeof(GsRegisterAddress));
switch (addr) {
case GsRegisterAddress::MIPTBP1_1:
case GsRegisterAddress::MIPTBP2_1:
// ignore this, it's just mipmapping settings
break;
case GsRegisterAddress::TEX1_1: {
GsTex1 reg(value);
ASSERT(reg.mmag());
} break;
case GsRegisterAddress::CLAMP_1: {
bool s = value & 0b001;
bool t = value & 0b100;
ASSERT(s == t);
} break;
case GsRegisterAddress::TEX0_1: {
GsTex0 reg(value);
ASSERT(reg.tfx() == GsTex0::TextureFunction::MODULATE);
most_recent_tbp = reg.tbp0();
} break;
case GsRegisterAddress::ALPHA_1: {
} break;
default:
fmt::print("reg: {}\n", register_address_name(addr));
break;
}
}
if (most_recent_tbp != 8160) {
m_envmap_tex = most_recent_tbp;
}
if (m_vertices.size() - 128 < m_next_free_vertex) {
ASSERT(false); // add more vertices.
}
}
void CommonOceanRenderer::init_for_mid() {
m_next_free_vertex = 0;
for (auto& x : m_next_free_index) {
x = 0;
}
}
void reverse_indices(u32* indices, u32 count) {
if (count) {
for (u32 a = 0, b = count - 1; a < b; a++, b--) {
std::swap(indices[a], indices[b]);
}
}
}
void CommonOceanRenderer::flush_mid(SharedRenderState* render_state, ScopedProfilerNode& prof) {
glBindVertexArray(m_ogl.vao);
glBindBuffer(GL_ARRAY_BUFFER, m_ogl.vertex_buffer);
glEnable(GL_PRIMITIVE_RESTART);
glPrimitiveRestartIndex(UINT32_MAX);
glBufferData(GL_ARRAY_BUFFER, m_next_free_vertex * sizeof(Vertex), m_vertices.data(),
GL_STREAM_DRAW);
render_state->shaders[ShaderId::OCEAN_COMMON].activate();
glUniform4f(glGetUniformLocation(render_state->shaders[ShaderId::OCEAN_COMMON].id(), "fog_color"),
render_state->fog_color[0], render_state->fog_color[1], render_state->fog_color[2],
render_state->fog_intensity);
glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_ALWAYS);
glDisable(GL_BLEND);
// note:
// there are some places where the game draws the same section of ocean twice, in this order:
// - low poly mesh with ocean texture
// - low poly mesh with envmap texture
// - high poly mesh with ocean texture (overwrites previous draw)
// - high poly mesh with envmap texture (overwrites previous draw)
// we draw all ocean textures together and all envmap textures togther. luckily, there's a trick
// we can use to get the same result.
// first, we'll draw all ocean textures. The high poly mesh is drawn second, so it wins.
// then, we'll draw all envmaps, but with two changes:
// - first, we draw it in reverse, so the high poly versions are drawn first
// - second, we'll modify the shader to set alpha = 0 of the destination. when the low poly
// version is drawn on top, it won't draw at all because of the blending mode
// (s_factor = DST_ALPHA, d_factor = 1)
// draw it in reverse
reverse_indices(m_indices[1].data(), m_next_free_index[1]);
for (int bucket = 0; bucket < 2; bucket++) {
switch (bucket) {
case 0: {
auto tex = render_state->texture_pool->lookup(8160);
if (!tex) {
tex = render_state->texture_pool->get_placeholder_texture();
}
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, *tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glUniform1i(
glGetUniformLocation(render_state->shaders[ShaderId::OCEAN_COMMON].id(), "tex_T0"), 0);
glUniform1i(
glGetUniformLocation(render_state->shaders[ShaderId::OCEAN_COMMON].id(), "bucket"), 3);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
break;
case 1:
glEnable(GL_BLEND);
auto tex = render_state->texture_pool->lookup(m_envmap_tex);
if (!tex) {
tex = render_state->texture_pool->get_placeholder_texture();
}
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, *tex);
glBlendFuncSeparate(GL_DST_ALPHA, GL_ONE, GL_ONE, GL_ZERO);
glBlendEquation(GL_FUNC_ADD);
glUniform1i(
glGetUniformLocation(render_state->shaders[ShaderId::OCEAN_COMMON].id(), "bucket"), 4);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
break;
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ogl.index_buffer[bucket]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_next_free_index[bucket] * sizeof(u32),
m_indices[bucket].data(), GL_STREAM_DRAW);
glDrawElements(GL_TRIANGLE_STRIP, m_next_free_index[bucket], GL_UNSIGNED_INT, nullptr);
prof.add_draw_call();
prof.add_tri(m_next_free_index[bucket]);
}
}

View File

@ -8,7 +8,11 @@ class CommonOceanRenderer {
void init_for_near();
void kick_from_near(const u8* data);
void flush(SharedRenderState* render_state, ScopedProfilerNode& prof);
void flush_near(SharedRenderState* render_state, ScopedProfilerNode& prof);
void init_for_mid();
void kick_from_mid(const u8* data);
void flush_mid(SharedRenderState* render_state, ScopedProfilerNode& prof);
private:
void handle_near_vertex_gif_data_fan(const u8* data, u32 offset, u32 loop);
@ -16,6 +20,8 @@ class CommonOceanRenderer {
void handle_near_adgif(const u8* data, u32 offset, u32 count);
void handle_mid_adgif(const u8* data, u32 offset);
enum VertexBucket {
RGB_TEXTURE = 0,
ALPHA = 1,

View File

@ -12,10 +12,8 @@ OceanMid::OceanMid() {
vu.vf25 = Vf(1, 1, 1, 1);
}
void OceanMid::run(DmaFollower& dma,
SharedRenderState* render_state,
ScopedProfilerNode& prof,
DirectRenderer& direct) {
void OceanMid::run(DmaFollower& dma, SharedRenderState* render_state, ScopedProfilerNode& prof) {
m_common_ocean_renderer.init_for_mid();
// first is setting base and offset
{
auto base_offset_tag = dma.read_and_advance();
@ -97,26 +95,24 @@ void OceanMid::run(DmaFollower& dma,
memcpy(m_vu_data + addr + addr_off, temp, 16);
}
ASSERT(8 * v1.num == data.size_bytes);
// TODO
} else if (v0.kind == VifCode::Kind::STCYCL && v0.immediate == 0x404 &&
v1.kind == VifCode::Kind::MSCALF) {
switch (v1.immediate) {
case 46:
run_call46_vu2c(render_state, prof, direct);
run_call46_vu2c();
break;
case 73:
run_call73_vu2c(render_state, prof, direct);
run_call73_vu2c();
break;
case 107:
run_call107_vu2c(render_state, prof, direct);
run_call107_vu2c();
break;
case 275:
run_call275_vu2c(render_state, prof, direct);
run_call275_vu2c();
break;
default:
fmt::print("unknown call1: {}\n", v1.immediate);
}
// TODO
} else if (v0.kind == VifCode::Kind::MSCALF && v1.kind == VifCode::Kind::FLUSHA) {
switch (v0.immediate) {
case 41:
@ -129,17 +125,18 @@ void OceanMid::run(DmaFollower& dma,
fmt::print("unknown call2: {}\n", v0.immediate);
ASSERT(false);
}
// TODO
}
else {
} else {
fmt::print("{} {}\n", data.vifcode0().print(), data.vifcode1().print());
ASSERT(false);
}
}
m_common_ocean_renderer.flush_mid(render_state, prof);
}
void OceanMid::run_call0() {
run_call0_vu2c();
}
void OceanMid::xgkick(u16 addr) {
m_common_ocean_renderer.kick_from_mid((const u8*)&m_vu_data[addr]);
}

View File

@ -3,48 +3,31 @@
#include "game/graphics/opengl_renderer/BucketRenderer.h"
#include "game/graphics/opengl_renderer/DirectRenderer.h"
#include "game/common/vu.h"
#include "game/graphics/opengl_renderer/ocean/CommonOceanRenderer.h"
class OceanMid {
public:
OceanMid();
void run(DmaFollower& dma,
SharedRenderState* render_state,
ScopedProfilerNode& prof,
DirectRenderer& direct);
void run(DmaFollower& dma, SharedRenderState* render_state, ScopedProfilerNode& prof);
private:
void run_call0();
void run_call0_vu2c();
void run_call41_vu2c();
void run_call43_vu2c();
void run_call46_vu2c(SharedRenderState* render_state,
ScopedProfilerNode& prof,
DirectRenderer& direct);
void run_call73_vu2c(SharedRenderState* render_state,
ScopedProfilerNode& prof,
DirectRenderer& direct);
void run_call107_vu2c(SharedRenderState* render_state,
ScopedProfilerNode& prof,
DirectRenderer& direct);
void run_call275_vu2c(SharedRenderState* render_state,
ScopedProfilerNode& prof,
DirectRenderer& direct);
void xgkick(u16 addr,
SharedRenderState* render_state,
ScopedProfilerNode& prof,
DirectRenderer& direct);
void run_call46_vu2c();
void run_call73_vu2c();
void run_call107_vu2c();
void run_call275_vu2c();
void xgkick(u16 addr);
void run_L26_vu2c();
void run_L32_vu2c();
void run_L38_vu2c(SharedRenderState* render_state,
ScopedProfilerNode& prof,
DirectRenderer& direct);
void run_L43_vu2c(SharedRenderState* render_state,
ScopedProfilerNode& prof,
DirectRenderer& direct);
void run_L38_vu2c();
void run_L43_vu2c();
void run_L45_vu2c();
CommonOceanRenderer m_common_ocean_renderer;
bool m_buffer_toggle = false;
static constexpr int VU1_INPUT_BUFFER_BASE = 0;
static constexpr int VU1_INPUT_BUFFER_OFFSET = 0x76;

View File

@ -97,7 +97,7 @@ void OceanMidAndFar::handle_ocean_mid(DmaFollower& dma,
SharedRenderState* render_state,
ScopedProfilerNode& prof) {
if (dma.current_tag_vifcode0().kind == VifCode::Kind::BASE) {
m_mid_renderer.run(dma, render_state, prof, m_direct);
m_mid_renderer.run(dma, render_state, prof);
} else {
// not drawing
return;

View File

@ -54,13 +54,6 @@ static inline REALLY_INLINE float erleng(const Vf& in) {
}
} // namespace
void OceanMid::xgkick(u16 addr,
SharedRenderState* render_state,
ScopedProfilerNode& prof,
DirectRenderer& direct) {
direct.render_gif((const u8*)&m_vu_data[addr], UINT32_MAX, render_state, prof);
}
void OceanMid::run_call0_vu2c() {
bool bc;
// lq.xyzw vf01, 733(vi00) | nop 0
@ -209,9 +202,7 @@ void OceanMid::run_call43_vu2c() {
return;
}
void OceanMid::run_call46_vu2c(SharedRenderState* render_state,
ScopedProfilerNode& prof,
DirectRenderer& direct) {
void OceanMid::run_call46_vu2c() {
bool bc;
// xtop vi02 | nop 46
vu.vi02 = xtop();
@ -272,7 +263,7 @@ L10:
// iaddiu vi01, vi00, 0x318 | nop 66
vu.vi01 = 0x318; /* 792 */
// xgkick vi09 | nop 67
xgkick(vu.vi09, render_state, prof, direct);
xgkick(vu.vi09);
// isub vi09, vi01, vi09 | nop 68
vu.vi09 = vu.vi01 - vu.vi09;
L11:
@ -292,9 +283,7 @@ L11:
return;
}
void OceanMid::run_call73_vu2c(SharedRenderState* render_state,
ScopedProfilerNode& prof,
DirectRenderer& direct) {
void OceanMid::run_call73_vu2c() {
bool bc;
// xtop vi02 | nop 73
vu.vi02 = xtop();
@ -363,7 +352,7 @@ L14:
// iaddiu vi01, vi00, 0x318 | nop 97
vu.vi01 = 0x318; /* 792 */
// xgkick vi09 | nop 98
xgkick(vu.vi09, render_state, prof, direct); // draws envmapped ocean
xgkick(vu.vi09); // draws envmapped ocean
// BRANCH!
// ibeq vi00, vi14, L15 | nop 99
bc = (vu.vi14 == 0);
@ -379,7 +368,7 @@ L14:
// nop | nop 102
// if (bc) { goto L38; }
run_L38_vu2c(render_state, prof, direct);
run_L38_vu2c();
L15:
// BRANCH!
@ -398,9 +387,7 @@ L15:
return;
}
void OceanMid::run_call107_vu2c(SharedRenderState* render_state,
ScopedProfilerNode& prof,
DirectRenderer& direct) {
void OceanMid::run_call107_vu2c() {
bool bc;
// xtop vi02 | nop 107
vu.vi02 = xtop();
@ -657,7 +644,7 @@ L18:
// iaddiu vi06, vi06, 0x4000 | nop 214
vu.vi06 = vu.vi06 + 0x4000; /* 16384 */
// if (bc) { goto L43; }
run_L43_vu2c(render_state, prof, direct);
run_L43_vu2c();
L19:
// BRANCH!
@ -794,7 +781,7 @@ L20:
// iaddiu vi06, vi06, 0x4000 | nop 270
vu.vi06 = vu.vi06 + 0x4000; /* 16384 */
// if (bc) { goto L43; }
run_L43_vu2c(render_state, prof, direct);
run_L43_vu2c();
L21:
// BRANCH!
@ -813,9 +800,7 @@ L21:
return;
}
void OceanMid::run_call275_vu2c(SharedRenderState* render_state,
ScopedProfilerNode& prof,
DirectRenderer& direct) {
void OceanMid::run_call275_vu2c() {
bool bc;
// fmt::print("call 275\n");
// xtop vi02 | nop 275
@ -1005,7 +990,7 @@ L23:
// if (bc) {
// goto L43;
// }
run_L43_vu2c(render_state, prof, direct);
run_L43_vu2c();
// ior vi03, vi00, vi00 | nop 350
vu.vi03 = 0;
@ -1101,7 +1086,7 @@ L24:
// if (bc) {
// goto L43;
// }
run_L43_vu2c(render_state, prof, direct);
run_L43_vu2c();
L25:
// nop | nop :e 389
@ -1848,9 +1833,7 @@ L37:
// nop | nop 613
}
void OceanMid::run_L38_vu2c(SharedRenderState* render_state,
ScopedProfilerNode& prof,
DirectRenderer& direct) {
void OceanMid::run_L38_vu2c() {
bool bc;
// lq.xyzw vf31, 734(vi00) | nop 614
@ -2089,7 +2072,7 @@ L41:
// iaddiu vi06, vi06, 0x4000 | nop 705
vu.vi06 = vu.vi06 + 0x4000; /* 16384 */
// if (bc) { goto L43; }
run_L43_vu2c(render_state, prof, direct);
run_L43_vu2c();
// iaddi vi08, vi10, 0x7 | nop 706
vu.vi08 = vu.vi10 + 7;
@ -2175,7 +2158,7 @@ L41:
// iaddiu vi06, vi06, 0x4000 | nop 744
vu.vi06 = vu.vi06 + 0x4000; /* 16384 */
// if (bc) { goto L43; }
run_L43_vu2c(render_state, prof, direct);
run_L43_vu2c();
L42:
// BRANCH!
@ -2190,9 +2173,7 @@ L42:
// jr vi15 | nop 747
// nop | nop 748
}
void OceanMid::run_L43_vu2c(SharedRenderState* render_state,
ScopedProfilerNode& prof,
DirectRenderer& direct) {
void OceanMid::run_L43_vu2c() {
bool bc;
// sq.xyzw vf07, -1(vi08) | nop 749
sq_buffer(Mask::xyzw, vu.vf07, vu.vi08 + -1);
@ -2285,7 +2266,7 @@ L44:
// iaddiu vi01, vi00, 0x4d3 | nop 789
vu.vi01 = 0x4d3; /* 1235 */
// xgkick vi10 | nop 790
xgkick(vu.vi10, render_state, prof, direct);
xgkick(vu.vi10);
// jr vi13 | nop 791
// ASSERT(false);
// isub vi10, vi01, vi10 | nop 792

View File

@ -2,16 +2,13 @@
#include "third-party/imgui/imgui.h"
OceanNear::OceanNear(const std::string& name, BucketId my_id)
: BucketRenderer(name, my_id), m_texture_renderer(false), m_direct(name, my_id, 0x4000) {
: BucketRenderer(name, my_id), m_texture_renderer(false) {
for (auto& a : m_vu_data) {
a.fill(0);
}
}
void OceanNear::draw_debug_window() {
ImGui::Checkbox("New", &m_use_new);
m_direct.draw_debug_window();
}
void OceanNear::draw_debug_window() {}
void OceanNear::init_textures(TexturePool& pool) {
m_texture_renderer.init_textures(pool);
@ -65,19 +62,11 @@ void OceanNear::render(DmaFollower& dma,
// direct setup
{
if (m_use_new) {
m_common_ocean_renderer.init_for_near();
} else {
m_direct.reset_state();
}
m_common_ocean_renderer.init_for_near();
auto setup = dma.read_and_advance();
ASSERT(setup.vifcode0().kind == VifCode::Kind::NOP);
ASSERT(setup.vifcode1().kind == VifCode::Kind::DIRECT);
ASSERT(setup.size_bytes == 32);
if (m_use_new) {
} else {
m_direct.render_gif(setup.data, 32, render_state, prof);
}
}
// oofset and base
@ -110,7 +99,7 @@ void OceanNear::render(DmaFollower& dma,
run_call0_vu2c();
break;
case 39:
run_call39_vu2c(render_state, prof);
run_call39_vu2c();
break;
default:
fmt::print("unknown ocean near call: {}\n", v0.immediate);
@ -123,17 +112,9 @@ void OceanNear::render(DmaFollower& dma,
dma.read_and_advance();
}
if (m_use_new) {
m_common_ocean_renderer.flush(render_state, prof);
} else {
m_direct.flush_pending(render_state, prof);
}
m_common_ocean_renderer.flush_near(render_state, prof);
}
void OceanNear::xgkick(u16 addr, SharedRenderState* render_state, ScopedProfilerNode& prof) {
if (m_use_new) {
m_common_ocean_renderer.kick_from_near((const u8*)&m_vu_data[addr]);
} else {
m_direct.render_gif((const u8*)&m_vu_data[addr], UINT32_MAX, render_state, prof);
}
void OceanNear::xgkick(u16 addr) {
m_common_ocean_renderer.kick_from_near((const u8*)&m_vu_data[addr]);
}

View File

@ -14,25 +14,22 @@ class OceanNear : public BucketRenderer {
private:
void run_call0_vu2c();
void run_call39_vu2c(SharedRenderState* render_state, ScopedProfilerNode& prof);
void run_call39_vu2c();
void run_L15_vu2c();
void run_L21_vu2c();
void run_L23_vu2c();
void run_L25_vu2c(SharedRenderState* render_state, ScopedProfilerNode& prof);
void run_L25_vu2c();
void run_L30_vu2c();
void run_L32_vu2c();
OceanTexture m_texture_renderer;
DirectRenderer m_direct;
CommonOceanRenderer m_common_ocean_renderer;
bool m_buffer_toggle = false;
static constexpr int VU1_INPUT_BUFFER_BASE = 0;
static constexpr int VU1_INPUT_BUFFER_OFFSET = 0x10;
bool m_use_new = true;
void xgkick(u16 addr, SharedRenderState* render_state, ScopedProfilerNode& prof);
void xgkick(u16 addr);
u16 xtop() {
m_buffer_toggle = !m_buffer_toggle;

View File

@ -110,7 +110,7 @@ L4:
// nop | nop 38
}
void OceanNear::run_call39_vu2c(SharedRenderState* render_state, ScopedProfilerNode& prof) {
void OceanNear::run_call39_vu2c() {
bool bc;
// xtop vi02 | nop 39
vu.vi02 = xtop();
@ -363,11 +363,11 @@ L9:
// sq.xyzw vf07, 6(vi09) | nop 138
sq_buffer(Mask::xyzw, vu.vf07, vu.vi09 + 6);
// xgkick vi09 | nop 139
xgkick(vu.vi09, render_state, prof);
xgkick(vu.vi09);
// lq.xyzw vf07, 980(vi00) | nop 140
lq_buffer(Mask::xyzw, vu.vf07, 980);
// xgkick vi08 | nop 141
xgkick(vu.vi08, render_state, prof);
xgkick(vu.vi08);
// sq.xyzw vf07, 6(vi09) | nop 142
sq_buffer(Mask::xyzw, vu.vf07, vu.vi09 + 6);
// iaddi vi08, vi09, 0x6 | nop 143
@ -375,13 +375,13 @@ L9:
// nop | nop 144
// xgkick vi08 | nop 145
xgkick(vu.vi08, render_state, prof);
xgkick(vu.vi08);
// iaddiu vi08, vi00, 0x3d5 | nop 146
vu.vi08 = 0x3d5; /* 981 */
// nop | nop 147
// xgkick vi08 | nop 148
xgkick(vu.vi08, render_state, prof);
xgkick(vu.vi08);
// BRANCH!
// bal vi15, L21 | nop 149
// ASSERT(false);
@ -405,7 +405,7 @@ L9:
// nop | nop 154
// if (bc) { goto L25; }
run_L25_vu2c(render_state, prof);
run_L25_vu2c();
L10:
// BRANCH!
@ -421,7 +421,7 @@ L10:
// iaddiu vi01, vi00, 0x4b2 | nop 158
vu.vi01 = 0x4b2; /* 1202 */
// xgkick vi08 | nop 159
xgkick(vu.vi08, render_state, prof);
xgkick(vu.vi08);
// isub vi09, vi01, vi09 | nop 160
vu.vi09 = vu.vi01 - vu.vi09;
L11:
@ -479,11 +479,11 @@ L12:
// sq.xyzw vf07, 6(vi09) | nop 179
sq_buffer(Mask::xyzw, vu.vf07, vu.vi09 + 6);
// xgkick vi09 | nop 180
xgkick(vu.vi09, render_state, prof);
xgkick(vu.vi09);
// lq.xyzw vf07, 980(vi00) | nop 181
lq_buffer(Mask::xyzw, vu.vf07, 980);
// xgkick vi08 | nop 182
xgkick(vu.vi08, render_state, prof);
xgkick(vu.vi08);
// sq.xyzw vf07, 6(vi09) | nop 183
sq_buffer(Mask::xyzw, vu.vf07, vu.vi09 + 6);
// iaddi vi08, vi09, 0x6 | nop 184
@ -491,13 +491,13 @@ L12:
// nop | nop 185
// xgkick vi08 | nop 186
xgkick(vu.vi08, render_state, prof);
xgkick(vu.vi08);
// iaddiu vi08, vi00, 0x3d5 | nop 187
vu.vi08 = 0x3d5; /* 981 */
// nop | nop 188
// xgkick vi08 | nop 189
xgkick(vu.vi08, render_state, prof);
xgkick(vu.vi08);
// BRANCH!
// bal vi15, L21 | nop 190
// ASSERT(false);
@ -521,7 +521,7 @@ L12:
// nop | nop 195
// if (bc) { goto L25; }
run_L25_vu2c(render_state, prof);
run_L25_vu2c();
L13:
// BRANCH!
@ -539,7 +539,7 @@ L13:
// nop | nop 200
// xgkick vi08 | nop 201
xgkick(vu.vi08, render_state, prof);
xgkick(vu.vi08);
// isub vi09, vi01, vi09 | nop 202
vu.vi09 = vu.vi01 - vu.vi09;
L14:
@ -1362,7 +1362,7 @@ L24:
// nop | nop 468
}
void OceanNear::run_L25_vu2c(SharedRenderState* render_state, ScopedProfilerNode& prof) {
void OceanNear::run_L25_vu2c() {
bool bc;
// lq.xyzw vf31, 952(vi00) | nop 469
lq_buffer(Mask::xyzw, vu.vf31, 952);
@ -1529,11 +1529,11 @@ L28:
// iaddiu vi08, vi00, 0x3d1 | nop 535
vu.vi08 = 0x3d1; /* 977 */
// xgkick vi10 | nop 536
xgkick(vu.vi10, render_state, prof);
xgkick(vu.vi10);
// lq.xyzw vf07, 960(vi00) | nop 537
lq_buffer(Mask::xyzw, vu.vf07, 960);
// xgkick vi08 | nop 538
xgkick(vu.vi08, render_state, prof);
xgkick(vu.vi08);
// iaddi vi08, vi10, 0x6 | nop 539
vu.vi08 = vu.vi10 + 6;
// sq.xyzw vf07, 6(vi10) | nop 540
@ -1541,13 +1541,13 @@ L28:
// isw.x vi06, 6(vi10) | nop 541
isw_buffer(Mask::x, vu.vi06, vu.vi10 + 6);
// xgkick vi08 | nop 542
xgkick(vu.vi08, render_state, prof);
xgkick(vu.vi08);
// iaddiu vi08, vi00, 0x3d5 | nop 543
vu.vi08 = 0x3d5; /* 981 */
// nop | nop 544
// xgkick vi08 | nop 545
xgkick(vu.vi08, render_state, prof);
xgkick(vu.vi08);
// iaddiu vi08, vi10, 0x2a | nop 546
vu.vi08 = vu.vi10 + 0x2a; /* 42 */
// iaddiu vi03, vi10, 0x2a | nop 547
@ -1577,7 +1577,7 @@ L28:
// iaddiu vi01, vi00, 0x69c | nop 555
vu.vi01 = 0x69c; /* 1692 */
// xgkick vi08 | nop 556
xgkick(vu.vi08, render_state, prof);
xgkick(vu.vi08);
// isub vi10, vi01, vi10 | nop 557
vu.vi10 = vu.vi01 - vu.vi10;
L29:

View File

@ -26,6 +26,13 @@ void main() {
color.xyzw *= 2;
} else if (bucket == 2) {
color = fragment_color * T0;
} else if (bucket == 3) {
color = fragment_color * T0;
color.xyzw *= 2;
color.xyz = mix(color.xyz, fog_color.xyz / 255., clamp(fog_color.w * (1 - fog), 0, 1));
} else if (bucket == 4) {
color = fragment_color * T0;
color.w = 0;
}
}

View File

@ -907,6 +907,8 @@
(define *generic-effect-mode* 0)
(defun real-main-draw-hook ()
"The main drawing function. This dispatches all renderers and is called directly from the display-loop
in main.gc."
(when *slow-frame-rate*
(dotimes (v1-2 40000000) ;; was 50000
(nop!)
@ -918,106 +920,109 @@
)
)
"Function to be executed to set up for engine dma"
;; update render enables from the debug menu
(set! *vu1-enable-user* *vu1-enable-user-menu*)
(set! *texture-enable-user* *texture-enable-user-menu*)
;; reset and display dma memory stats.
(when *debug-segment*
(when (or *stats-memory* *stats-memory-short*)
(dotimes (gp-0 (-> *level* length))
(let ((s5-0 (-> *level* level gp-0)))
(if (= (-> s5-0 status) 'active)
(print-mem-usage (compute-memory-usage s5-0 #f) s5-0 *stdcon*)
)
(when (or *stats-memory* *stats-memory-short*)
(dotimes (gp-0 (-> *level* length))
(let ((s5-0 (-> *level* level gp-0)))
(if (= (-> s5-0 status) 'active)
(print-mem-usage (compute-memory-usage s5-0 #f) s5-0 *stdcon*)
)
)
)
)
)
(reset! *dma-mem-usage*)
)
(reset! *dma-mem-usage*)
)
;; todo shrub matrix
;; todo generic init
;; initialize dma buckets that are generic sinks.
;; other renderers may output to these, so do them first.
(generic-init-buffers)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; texture uploads
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; tfrag
;; note: PC port uses preconverted tfrag textures.
; (#unless PC_PORT
(when (logtest? *texture-enable-user* 1)
(dotimes (gp-1 (-> *level* length))
(let ((a1-2 (-> *level* level gp-1)))
(if (= (-> a1-2 status) 'active)
(add-tex-to-dma! *texture-pool* a1-2 0)
)
)
)
)
; )
;; pris
;; next we use the texture system to build DMA commands to load texture.
;; internally, add-tex-to-dma! has special logic to avoid loading textures
;; that won't be used. (though it's pretty basic, it doesn't actually track per-texture usage)
;; level tfrag's upload if the level is running.
(when (logtest? *texture-enable-user* 1)
(dotimes (gp-1 (-> *level* length))
(let ((a1-2 (-> *level* level gp-1)))
(if (= (-> a1-2 status) 'active)
(add-tex-to-dma! *texture-pool* a1-2 0)
)
)
)
)
;; level pris's upload if the level is running.
(when (logtest? *texture-enable-user* 2)
(dotimes (gp-2 (-> *level* length))
(let ((a1-3 (-> *level* level gp-2)))
(if (= (-> a1-3 status) 'active)
(add-tex-to-dma! *texture-pool* a1-3 1)
(dotimes (gp-2 (-> *level* length))
(let ((a1-3 (-> *level* level gp-2)))
(if (= (-> a1-3 status) 'active)
(add-tex-to-dma! *texture-pool* a1-3 1)
)
)
)
)
)
)
;; shrub
;; level shrubs upload if the level is loading.
(when (logtest? *texture-enable-user* 4)
(dotimes (gp-3 (-> *level* length))
(let ((a1-4 (-> *level* level gp-3)))
(if (= (-> a1-4 status) 'active)
(add-tex-to-dma! *texture-pool* a1-4 2)
(dotimes (gp-3 (-> *level* length))
(let ((a1-4 (-> *level* level gp-3)))
(if (= (-> a1-4 status) 'active)
(add-tex-to-dma! *texture-pool* a1-4 2)
)
)
)
)
)
)
;; alpha and common.
(when (logtest? *texture-enable-user* 8)
(let ((uploaded-common #f))
(dotimes (gp-4 (-> *level* length))
(let ((a1-5 (-> *level* level gp-4)))
(when (= (-> a1-5 status) 'active)
(add-tex-to-dma! *texture-pool* a1-5 3)
(when (not uploaded-common)
(upload-one-common! *texture-pool* (-> *level* level0))
(set! uploaded-common #t)
(let ((uploaded-common #f))
(dotimes (gp-4 (-> *level* length))
(let ((a1-5 (-> *level* level gp-4)))
(when (= (-> a1-5 status) 'active)
(add-tex-to-dma! *texture-pool* a1-5 3)
(when (not uploaded-common)
(upload-one-common! *texture-pool* (-> *level* level0))
(set! uploaded-common #t)
)
)
)
)
(when (not uploaded-common)
(upload-one-common! *texture-pool* (-> *level* level0))
#t
)
)
)
)
(when (not uploaded-common)
(upload-one-common! *texture-pool* (-> *level* level0))
#t
)
)
)
;; water.
(when (logtest? *texture-enable-user* 16)
(dotimes (gp-5 (-> *level* length))
(let ((a1-8 (-> *level* level gp-5)))
(if (= (-> a1-8 status) 'active)
(add-tex-to-dma! *texture-pool* a1-8 4)
(dotimes (gp-5 (-> *level* length))
(let ((a1-8 (-> *level* level gp-5)))
(if (= (-> a1-8 status) 'active)
(add-tex-to-dma! *texture-pool* a1-8 4)
)
)
)
)
)
)
;;;;;;;;;;;;;
;; sky
;; todo - disabled sky
(when (zero? (logand *vu1-enable-user* 8))
;;;;;;;;;;;;;
(when (zero? (logand *vu1-enable-user* (vu1-renderer-mask sky)))
;; the sky is disabled. Just draw a solid gradient on the whole screen.
(with-dma-buffer-add-bucket ((dma-buf (-> (current-frame) global-buf)) (bucket-id sky-draw))
(dma-buffer-add-gs-set dma-buf
(zbuf-1 (new 'static 'gs-zbuf :zbp #x1c0 :psm (gs-psm ct24)))
@ -1033,28 +1038,63 @@
)
)
)
(when (logtest? *vu1-enable-user* 8)
(when (logtest? *vu1-enable-user* (vu1-renderer-mask sky))
;; check if we want the sky, and if we actually have textures ready.
;; we generate sky textures on the previous frame and they sit in vram (8160) until the next frame.
;; on the first frame after we request sky, we draw the textures, but they aren't ready until the next frame.
(cond
((and (-> *time-of-day-context* sky) *sky-drawn*)
(render-sky-tng *time-of-day-context*)
)
(else
;; todo
(with-dma-buffer-add-bucket ((dma-buf (-> (current-frame) global-buf)) (bucket-id sky-draw))
(dma-buffer-add-gs-set dma-buf
(zbuf-1 (new 'static 'gs-zbuf :zbp #x1c0 :psm (gs-psm ct24)))
(test-1 (new 'static 'gs-test :ate #x1 :atst (gs-atest always) :zte #x1 :ztst (gs-ztest always)))
(alpha-1 (new 'static 'gs-alpha :b #x1 :d #x1))
)
(screen-gradient
dma-buf
(-> *time-of-day-context* erase-color)
(-> *time-of-day-context* erase-color)
(-> *time-of-day-context* erase-color)
(-> *time-of-day-context* erase-color)
)
)
)
)
)
;; tod update
;; update mood lighting, draw sky textures.
(update-time-of-day *time-of-day-context*)
;; closest
(update-ocean)
(draw-ocean)
;; reset the closest object and desired texture masks for all levels.
(dotimes (v1-150 (-> *level* length))
(let ((a0-59 (-> *level* level v1-150)))
(when (= (-> a0-59 status) 'active)
(dotimes (a1-38 9)
(set! (-> a0-59 closest-object a1-38) 4095996000.0)
(set! (-> a0-59 texture-mask a1-38) (the-as uint 0))
)
)
)
)
(add-ee-profile-frame 'draw :r #x40 :b #x40 :a #x80)
;;;;;;; OCEAN
(update-ocean) ;; ocean map update
(draw-ocean) ;; far, mid, near, transition, and texture.
(add-ee-profile-frame 'draw :b #xff :a #x80)
;; reset MERC
(set! (-> *merc-global-array* count) (the-as uint 0))
(set! *merc-globals* (the-as merc-globals (-> *merc-global-array* globals)))
(set! (-> *shadow-queue* cur-run) (the-as uint 0))
(init-background)
;; exec bg
;; draw the background!
(init-background)
(execute-connections *background-draw-engine* (-> *display* frames (-> *display* on-screen) frame))
;; finish bg (most of the work is here)
@ -1063,7 +1103,7 @@
(read! (-> *perf-stats* data 3))
(update-wait-stats (-> *perf-stats* data 3) (-> *background-work* wait-to-vu0) (the-as uint 0) (the-as uint 0))
;;
;; perf stats are printed and restarted here, for some reason.
(end-perf-stat-collection)
(when (not (paused?))
(when *stats-poly*
@ -1081,6 +1121,8 @@
)
)
(start-perf-stat-collection)
;; draw the foreground engines.
(foreground-engine-execute
(-> *level* level-default foreground-draw-engine 0)
(-> *display* frames (-> *display* on-screen) frame)
@ -1093,30 +1135,36 @@
2
1
)
;; handle extra processing for foreground
(let ((gp-9 (-> *display* frames (-> *display* on-screen) frame global-buf)))
(bones-mtx-calc-execute)
(generic-merc-execute-all gp-9)
(bones-mtx-calc-execute) ;; skinning matrix calculation
(generic-merc-execute-all gp-9) ;; mercneric conversion.
;;(shadow-execute-all gp-9 *shadow-queue*)
(update-eyes)
)
;; fg engine
;; bones
;; gmerc
;; shadow
(update-eyes)
;; sprite draw
(when (logtest? (vu1-renderer-mask sprite) *vu1-enable-user*)
(swap-fake-shadow-buffers)
(sprite-draw *display*)
)
;; lots more in this function.
;; debug drawing
(when *debug-segment*
(debug-draw-actors *level* *display-actor-marks*)
(collide-shape-draw-debug-marks)
)
(render-boundaries)
;; for some reason we clear the touching list here...
(send-events-for-touching-shapes *touching-list*)
(free-all-prim-nodes *touching-list*)
(add-ee-profile-frame 'draw :r #x40 :b #x40 :a #x80)
;; spawn actors, compact heaps, etc.
(actors-update *level*)
(add-ee-profile-frame 'draw :r #x80 :a #x80)
(when (not (paused?))
(if *stats-collide*
(print-collide-stats)

View File

@ -1232,9 +1232,6 @@
)
)
; (dotimes (i 36)
; (format 0 "tidx: ~d ~X~%" i (-> *ocean-work* mid-camera-masks i))
; )
;; for now, skip seams.
;; when it's both on and cam is low