enable filter by default and fix up bucket hacks (#1214)

This commit is contained in:
water111
2022-03-02 21:40:52 -05:00
committed by GitHub
parent 1e387e1f93
commit 67946a4274
9 changed files with 82 additions and 56 deletions
@@ -81,6 +81,7 @@ RenderMux::RenderMux(const std::string& name,
void RenderMux::render(DmaFollower& dma,
SharedRenderState* render_state,
ScopedProfilerNode& prof) {
m_renderers[m_render_idx]->enabled() = m_enabled;
m_renderers[m_render_idx]->render(dma, render_state, prof);
}
@@ -66,6 +66,7 @@ struct LevelVis {
u8 data[2048];
};
class EyeRenderer;
/*!
* The main renderer will contain a single SharedRenderState that's passed to all bucket renderers.
* This allows bucket renders to share textures and shaders.
@@ -99,6 +100,8 @@ struct SharedRenderState {
LevelVis occlusion_vis[2];
math::Vector4f camera_planes[4];
EyeRenderer* eye_renderer = nullptr;
std::string load_status_debug;
};
+1 -1
View File
@@ -22,7 +22,7 @@ class EyeRenderer : public BucketRenderer {
std::string m_debug;
float m_average_time_ms = 0;
bool m_use_bilinear = false;
bool m_use_bilinear = true;
bool m_alpha_hack = true;
u32 m_left[SINGLE_EYE_SIZE * SINGLE_EYE_SIZE];
@@ -181,9 +181,11 @@ void OpenGLRenderer::init_bucket_renderers() {
init_bucket_renderer<MercRenderer>("l1-pris-merc", BucketId::MERC_PRIS_LEVEL1); // 52
init_bucket_renderer<GenericRenderer>("l1-pris-generic", BucketId::GENERIC_PRIS_LEVEL1); // 53
init_bucket_renderer<EyeRenderer>("common-pris-eyes", BucketId::MERC_EYES_AFTER_PRIS); // 54
init_bucket_renderer<MercRenderer>("common-pris-merc", BucketId::MERC_AFTER_PRIS); // 55
init_bucket_renderer<GenericRenderer>("common-pris-generic", BucketId::GENERIC_PRIS); // 56
// other renderers may output to the eye renderer
m_render_state.eye_renderer =
init_bucket_renderer<EyeRenderer>("common-pris-eyes", BucketId::MERC_EYES_AFTER_PRIS); // 54
init_bucket_renderer<MercRenderer>("common-pris-merc", BucketId::MERC_AFTER_PRIS); // 55
init_bucket_renderer<GenericRenderer>("common-pris-generic", BucketId::GENERIC_PRIS); // 56
//-----------------------
// LEVEL 0 water texture
@@ -36,8 +36,11 @@ class OpenGLRenderer {
void finish_screenshot(const std::string& output_name, int px, int py, int x, int y);
template <typename T, class... Args>
void init_bucket_renderer(const std::string& name, BucketId id, Args&&... args) {
m_bucket_renderers.at((int)id) = std::make_unique<T>(name, id, std::forward<Args>(args)...);
T* init_bucket_renderer(const std::string& name, BucketId id, Args&&... args) {
auto renderer = std::make_unique<T>(name, id, std::forward<Args>(args)...);
T* ret = renderer.get();
m_bucket_renderers.at((int)id) = std::move(renderer);
return ret;
}
SharedRenderState m_render_state;
@@ -3,24 +3,28 @@
#include "TextureUploadHandler.h"
#include "game/graphics/pipelines/opengl.h"
#include "game/graphics/opengl_renderer/EyeRenderer.h"
TextureUploadHandler::TextureUploadHandler(const std::string& name, BucketId my_id)
: BucketRenderer(name, my_id) {}
void TextureUploadHandler::render(DmaFollower& dma,
SharedRenderState* render_state,
ScopedProfilerNode& /*prof*/) {
ScopedProfilerNode& prof) {
// this is the data we get from the PC Port modification.
struct TextureUpload {
u64 page;
s64 mode;
};
std::vector<TextureUpload> uploads;
// loop through all data, grabbing buckets
while (dma.current_tag_offset() != render_state->next_bucket) {
auto dma_tag = dma.current_tag();
// 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<false>(dma, render_state, prof);
}
auto data = dma.read_and_advance();
if (data.size_bytes == 0 && data.vif0() == 0 && data.vif1() == 0) {
continue;
@@ -44,37 +48,46 @@ void TextureUploadHandler::render(DmaFollower& dma,
}
}
// 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;
if (uploads.size() == 2 && uploads[0].mode == 2 && uploads[1].mode == -2 &&
uploads[0].page == uploads[1].page) {
render_state->texture_pool->handle_upload_now(ee_mem + uploads[0].page, -2, ee_mem,
render_state->offset_of_s7);
render_state->texture_pool->handle_upload_now(ee_mem + uploads[0].page, 2, ee_mem,
render_state->offset_of_s7);
} else if (uploads.size() == 1 && uploads[0].mode == -1) {
render_state->texture_pool->handle_upload_now(ee_mem + uploads[0].page, -1, ee_mem,
render_state->offset_of_s7);
} else if (uploads.size() == 1 && uploads[0].mode == -2) {
render_state->texture_pool->handle_upload_now(ee_mem + uploads[0].page, -2, ee_mem,
render_state->offset_of_s7);
} else if (uploads.size() == 1 && uploads[0].mode == 0) {
render_state->texture_pool->handle_upload_now(ee_mem + uploads[0].page, 0, ee_mem,
render_state->offset_of_s7);
}
else if (uploads.empty()) {
// do nothing.
} else {
fmt::print("unhandled upload sequence in {}:\n", m_name);
for (auto& upload : uploads) {
fmt::print(" page: 0x{:x} mode: {}\n", upload.page, upload.mode);
}
ASSERT(false);
}
flush_uploads(uploads, render_state);
}
void TextureUploadHandler::draw_debug_window() {}
void TextureUploadHandler::flush_uploads(std::vector<TextureUpload>& uploads,
SharedRenderState* render_state) {
if (m_fake_uploads) {
uploads.clear();
} else {
// 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;
if (uploads.size() == 2 && uploads[0].mode == 2 && uploads[1].mode == -2 &&
uploads[0].page == uploads[1].page) {
render_state->texture_pool->handle_upload_now(ee_mem + uploads[0].page, -2, ee_mem,
render_state->offset_of_s7);
render_state->texture_pool->handle_upload_now(ee_mem + uploads[0].page, 2, ee_mem,
render_state->offset_of_s7);
} else if (uploads.size() == 1 && uploads[0].mode == -1) {
render_state->texture_pool->handle_upload_now(ee_mem + uploads[0].page, -1, ee_mem,
render_state->offset_of_s7);
} else if (uploads.size() == 1 && uploads[0].mode == -2) {
render_state->texture_pool->handle_upload_now(ee_mem + uploads[0].page, -2, ee_mem,
render_state->offset_of_s7);
} else if (uploads.size() == 1 && uploads[0].mode == 0) {
render_state->texture_pool->handle_upload_now(ee_mem + uploads[0].page, 0, ee_mem,
render_state->offset_of_s7);
}
else if (uploads.empty()) {
// do nothing.
} else {
fmt::print("unhandled upload sequence in {}:\n", m_name);
for (auto& upload : uploads) {
fmt::print(" page: 0x{:x} mode: {}\n", upload.page, upload.mode);
}
ASSERT(false);
}
}
}
void TextureUploadHandler::draw_debug_window() {
ImGui::Checkbox("Fake Uploads", &m_fake_uploads);
}
@@ -5,15 +5,20 @@
/*!
* The TextureUploadHandler receives textures uploads in the DMA chain and updates the TexturePool.
* It will attempt to cache textures when possible as converting and uploading them to the GPU is
* pretty expensive.
*
* Note that the PC Port sends a somewhat simplified texture upload message and this can't handle
* any arbitrary PS2 texture transfer. We rely on the texture metadata in GOAL to simplify this.
* The actual textures are preconverted and provided by the loader, so this just updates tables that
* tell the renderers which OpenGL texture goes with PS2 VRAM addresses.
*/
class TextureUploadHandler : public BucketRenderer {
public:
TextureUploadHandler(const std::string& name, BucketId my_id);
void render(DmaFollower& dma, SharedRenderState* render_state, ScopedProfilerNode& prof) override;
void draw_debug_window() override;
private:
struct TextureUpload {
u64 page;
s64 mode;
};
void flush_uploads(std::vector<TextureUpload>& uploads, SharedRenderState* render_state);
bool m_fake_uploads = false;
};
+1 -1
View File
@@ -322,7 +322,7 @@ void TexturePool::draw_debug_window() {
void TexturePool::draw_debug_for_tex(const std::string& name, GpuTexture* tex, u32 slot) {
if (tex->is_placeholder) {
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.8, 0.3, 0.3, 1.0));
} else if (tex->slots.size() == 1) {
} else if (tex->gpu_textures.size() == 1) {
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.3, 0.8, 0.3, 1.0));
} else {
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.8, 0.8, 0.3, 1.0));
+5 -6
View File
@@ -894,12 +894,11 @@
)
(dma-bucket-insert-tag
(-> *display* frames (-> *display* on-screen) frame bucket-group)
(bucket-id merc-eyes)
; (the-as bucket-id (if (zero? (-> s5-3 level))
; 48
; 51
; )
; )
(the-as bucket-id (if (zero? (-> s5-3 level))
(bucket-id pris-tex0)
(bucket-id pris-tex1)
)
)
s4-0
(the-as (pointer dma-tag) a3-6)
)