Skip to content

Commit

Permalink
Merge branch 'port' into port-debugger
Browse files Browse the repository at this point in the history
  • Loading branch information
fgsfdsfgs committed Oct 16, 2023
2 parents 704153d + 1eb1e96 commit ac46cf8
Show file tree
Hide file tree
Showing 13 changed files with 303 additions and 53 deletions.
5 changes: 3 additions & 2 deletions port/fast3d/gfx_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,11 @@ void gfx_set_target_fps(int);
void gfx_set_maximum_frame_latency(int latency);
void gfx_texture_cache_clear(void);
void gfx_texture_cache_delete(const uint8_t *orig_addr);
int gfx_create_framebuffer(uint32_t width, uint32_t height);
int gfx_create_framebuffer(uint32_t width, uint32_t height, int upscale, int autoresize);
void gfx_resize_framebuffer(int fb, uint32_t width, uint32_t height, int upscale, int autoresize);
void gfx_set_framebuffer(int fb, float noise_scale) ;
void gfx_reset_framebuffer(void);
void gfx_copy_framebuffer(int fb_dst, int fb_src, int left, int top);
void gfx_copy_framebuffer(int fb_dst, int fb_src, int left, int top, int use_back);
void gfx_get_pixel_depth_prepare(float x, float y);
uint16_t gfx_get_pixel_depth(float x, float y);

Expand Down
22 changes: 15 additions & 7 deletions port/fast3d/gfx_opengl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -921,7 +921,9 @@ static void gfx_opengl_init(void) {
// maybe replace this with sysFatalError, though the GLSL compiler will cause that later anyway
}

if (!gfx_opengl_supports_framebuffers()) {
if (!gfx_framebuffers_enabled) {
sysLogPrintf(LOG_WARNING, "GL: framebuffer effects disabled by user");
} else if (!gfx_opengl_supports_framebuffers()) {
sysLogPrintf(LOG_WARNING, "GL: GL_ARB_framebuffer_object unsupported, framebuffer effects disabled");
gfx_framebuffers_enabled = false;
}
Expand Down Expand Up @@ -1110,7 +1112,7 @@ void gfx_opengl_select_texture_fb(int fb_id) {
glBindTexture(GL_TEXTURE_2D, framebuffers[fb_id].clrbuf);
}

void gfx_opengl_copy_framebuffer(int fb_dst, int fb_src, int left, int top) {
void gfx_opengl_copy_framebuffer(int fb_dst, int fb_src, int left, int top, bool flip_y, bool use_back) {
if (!gfx_framebuffers_enabled || fb_dst >= (int)framebuffers.size() || fb_src >= (int)framebuffers.size()) {
return;
}
Expand Down Expand Up @@ -1139,16 +1141,22 @@ void gfx_opengl_copy_framebuffer(int fb_dst, int fb_src, int left, int top) {
srcY1 = src.height;
}

if (fb_src == 0) {
// flip the dst rect to mirror the image vertically
std::swap(dstY0, dstY1);
}

glDisable(GL_SCISSOR_TEST);

glBindFramebuffer(GL_READ_FRAMEBUFFER, src.fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dst.fbo);

if (flip_y) {
// flip the dst rect to mirror the image vertically
std::swap(dstY0, dstY1);
}

if (fb_src == 0) {
glReadBuffer(use_back ? GL_BACK : GL_FRONT);
} else {
glReadBuffer(GL_COLOR_ATTACHMENT0);
}

glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, GL_COLOR_BUFFER_BIT, GL_NEAREST);

glBindFramebuffer(GL_FRAMEBUFFER, framebuffers[current_framebuffer].fbo);
Expand Down
164 changes: 139 additions & 25 deletions port/fast3d/gfx_pc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ static uintptr_t segmentPointers[16];
struct FBInfo {
uint32_t orig_width, orig_height;
uint32_t applied_width, applied_height;
bool upscale, autoresize;
};

static bool fbActive = 0;
Expand Down Expand Up @@ -2152,10 +2153,10 @@ static void gfx_dp_texture_rectangle(int32_t ulx, int32_t uly, int32_t lrx, int3
// lrx, lry, ulx, uly are U10.2
// lrs, lrt are S10.5

int16_t width = !flip ? lrx - ulx : lry - uly;
int16_t height = !flip ? lry - uly : lrx - ulx;
float lrs = ((uls << 7) + dsdx * width) >> 7;
float lrt = ((ult << 7) + dtdy * height) >> 7;
const int16_t width = flip ? lry - uly : lrx - ulx;
const int16_t height = flip ? lrx - ulx : lry - uly;
const float lrs = ((uls << 7) + dsdx * width) >> 7;
const float lrt = ((ult << 7) + dtdy * height) >> 7;

struct LoadedVertex* ul = &rsp.loaded_vertices[MAX_VERTICES + 0];
struct LoadedVertex* ll = &rsp.loaded_vertices[MAX_VERTICES + 1];
Expand Down Expand Up @@ -2193,6 +2194,53 @@ static void gfx_dp_texture_rectangle(int32_t ulx, int32_t uly, int32_t lrx, int3
rdp.combine_mode = saved_combine_mode;
}

static void gfx_dp_image_rectangle(int32_t tile, int32_t w, int32_t h,
int32_t ulx, int32_t uly, int16_t uls, int16_t ult,
int32_t lrx, int32_t lry, int16_t lrs, int16_t lrt) {
uint64_t saved_combine_mode = rdp.combine_mode;

struct LoadedVertex* ul = &rsp.loaded_vertices[MAX_VERTICES + 0];
struct LoadedVertex* ll = &rsp.loaded_vertices[MAX_VERTICES + 1];
struct LoadedVertex* lr = &rsp.loaded_vertices[MAX_VERTICES + 2];
struct LoadedVertex* ur = &rsp.loaded_vertices[MAX_VERTICES + 3];
ul->u = uls * 32;
ul->v = ult * 32;
lr->u = lrs * 32;
lr->v = lrt * 32;
ll->u = uls * 32;
ll->v = lrt * 32;
ur->u = lrs * 32;
ur->v = ult * 32;

// ensure we have the correct texture size
rdp.texture_tile[tile].line_size_bytes = w << rdp.texture_tile[tile].siz >> 1;
rdp.texture_tile[tile].width = w;
rdp.texture_tile[tile].height = h;
rdp.texture_tile[tile].cms = 0;
rdp.texture_tile[tile].cmt = 0;
rdp.texture_tile[tile].shifts = 0;
rdp.texture_tile[tile].shiftt = 0;
auto& loadtex = rdp.loaded_texture[rdp.texture_tile[tile].tmem];
loadtex.full_image_line_size_bytes = loadtex.line_size_bytes = rdp.texture_tile[tile].line_size_bytes;
loadtex.size_bytes = loadtex.orig_size_bytes = loadtex.full_size_bytes = loadtex.line_size_bytes * h;

uint8_t saved_tile = rdp.first_tile_index;
if (saved_tile != tile) {
rdp.textures_changed[0] = true;
rdp.textures_changed[1] = true;
}
rdp.first_tile_index = tile;

gfx_draw_rectangle(ulx, uly, lrx, lry);
if (saved_tile != tile) {
rdp.textures_changed[0] = true;
rdp.textures_changed[1] = true;
}
rdp.first_tile_index = saved_tile;

rdp.combine_mode = saved_combine_mode;
}

static void gfx_dp_fill_rectangle(int32_t ulx, int32_t uly, int32_t lrx, int32_t lry) {
if (rdp.color_image_address == rdp.z_buf_address) {
// Don't clear Z buffer here since we already did it with glClear
Expand Down Expand Up @@ -2529,9 +2577,11 @@ static void gfx_run_dl(Gfx* cmd) {
case G_TEXRECT_WIDE_EXT: {
int32_t lrx, lry, tile, ulx, uly;
uint32_t uls, ult, dsdx, dtdy;
bool flip;
lrx = (int32_t)((C0(0, 24) << 8)) >> 8;
lry = (int32_t)((C1(0, 24) << 8)) >> 8;
tile = C1(24, 3);
flip = C1(27, 1);
++cmd;
ulx = (int32_t)((C0(0, 24) << 8)) >> 8;
uly = (int32_t)((C1(0, 24) << 8)) >> 8;
Expand All @@ -2540,7 +2590,27 @@ static void gfx_run_dl(Gfx* cmd) {
ult = C0(0, 16);
dsdx = C1(16, 16);
dtdy = C1(0, 16);
gfx_dp_texture_rectangle(ulx, uly, lrx, lry, tile, uls, ult, dsdx, dtdy, opcode == G_TEXRECTFLIP);
gfx_dp_texture_rectangle(ulx, uly, lrx, lry, tile, uls, ult, dsdx, dtdy, flip);
break;
}
case G_IMAGERECT_EXT: {
int16_t tile, iw, ih;
int16_t x0, y0, s0, t0;
int16_t x1, y1, s1, t1;
tile = C0(0, 3);
iw = C1(16, 16);
ih = C1(0, 16);
++cmd;
x0 = C0(16, 16);
y0 = C0(0, 16);
s0 = C1(16, 16);
t0 = C1(0, 16);
++cmd;
x1 = C0(16, 16);
y1 = C0(0, 16);
s1 = C1(16, 16);
t1 = C1(0, 16);
gfx_dp_image_rectangle(tile, iw, ih, x0, y0, s0, t0, x1, y1, s1, t1);
break;
}
case G_SETSCISSOR:
Expand All @@ -2564,7 +2634,7 @@ static void gfx_run_dl(Gfx* cmd) {
}
break;
case G_COPYFB_EXT:
gfx_copy_framebuffer(C0(12, 12), C0(0, 12), C1(16, 16), C1(0, 16));
gfx_copy_framebuffer(C0(11, 11), C0(0, 11), (int16_t)C1(16, 16), (int16_t)C1(0, 16), C0(22, 1));
break;
case G_RDPSETOTHERMODE:
gfx_dp_set_other_mode(C0(0, 24), cmd->words.w1);
Expand Down Expand Up @@ -2618,6 +2688,11 @@ extern "C" void gfx_init(struct GfxWindowManagerAPI* wapi, struct GfxRenderingAP
game_framebuffer = gfx_rapi->create_framebuffer();
game_framebuffer_msaa_resolved = gfx_rapi->create_framebuffer();

if (gfx_msaa_level > 1 && !gfx_framebuffers_enabled) {
sysLogPrintf(LOG_WARNING, "F3D: MSAA set to %d, but framebuffers are not available; disabling", gfx_msaa_level);
gfx_msaa_level = 1;
}

for (int i = 0; i < 16; i++) {
segmentPointers[i] = 0;
}
Expand Down Expand Up @@ -2665,12 +2740,22 @@ extern "C" void gfx_start_frame(void) {

if (gfx_current_dimensions.height != gfx_prev_dimensions.height) {
for (auto& fb : framebuffers) {
uint32_t width = fb.second.orig_width, height = fb.second.orig_height;
gfx_adjust_width_height_for_scale(width, height);
if (width != fb.second.applied_width || height != fb.second.applied_height) {
gfx_rapi->update_framebuffer_parameters(fb.first, width, height, 1, true, true, true, true);
fb.second.applied_width = width;
fb.second.applied_height = height;
uint32_t width, height, msaa;
if (fb.second.autoresize) {
if (fb.second.upscale) {
width = fb.second.orig_width;
height = fb.second.orig_height;
gfx_adjust_width_height_for_scale(width, height);
} else {
// assume this is a fullscreen fb
width = gfx_current_dimensions.width;
height = gfx_current_dimensions.height;
}
if (width != fb.second.applied_width || height != fb.second.applied_height) {
gfx_rapi->update_framebuffer_parameters(fb.first, width, height, 1, true, true, true, true);
fb.second.applied_width = width;
fb.second.applied_height = height;
}
}
}
}
Expand Down Expand Up @@ -2768,29 +2853,58 @@ extern "C" void gfx_set_target_fps(int fps) {
gfx_wapi->set_target_fps(fps);
}

extern "C" int gfx_create_framebuffer(uint32_t width, uint32_t height) {
uint32_t orig_width = width, orig_height = height;
gfx_adjust_width_height_for_scale(width, height);
extern "C" int gfx_create_framebuffer(uint32_t width, uint32_t height, int upscale, int autoresize) {
int fb = gfx_rapi->create_framebuffer();
gfx_rapi->update_framebuffer_parameters(fb, width, height, 1, true, true, true, true);
framebuffers[fb] = { orig_width, orig_height, width, height };
gfx_resize_framebuffer(fb, width, height, upscale, autoresize);
return fb;
}

extern "C" void gfx_resize_framebuffer(int fb, uint32_t width, uint32_t height, int upscale, int autoresize) {
uint32_t orig_width, orig_height;

if (width && height) {
// user-specified size
orig_width = width;
orig_height = height;
if (upscale) {
gfx_adjust_width_height_for_scale(width, height);
}
gfx_rapi->update_framebuffer_parameters(fb, width, height, 1, true, true, true, true);
} else {
// same size as main fb
orig_width = width = gfx_current_dimensions.width;
orig_height = height = gfx_current_dimensions.height;
upscale = false;
autoresize = true;
gfx_rapi->update_framebuffer_parameters(fb, width, height, 1, true, true, true, true);
}

framebuffers[fb] = { orig_width, orig_height, width, height, (bool)upscale, (bool)autoresize };
}

extern "C" void gfx_set_framebuffer(int fb, float noise_scale) {
gfx_rapi->start_draw_to_framebuffer(fb, noise_scale);
gfx_rapi->clear_framebuffer();
}

extern "C" void gfx_copy_framebuffer(int fb_dst, int fb_src, int left, int top) {
if (fb_src == 0 && left > 0 && top > 0) {
// upscale the position
left = left * gfx_current_dimensions.width / gfx_current_native_viewport.width;
top = top * gfx_current_dimensions.height / gfx_current_native_viewport.height;
// flip Y
top = gfx_current_dimensions.height - top - 1;
extern "C" void gfx_copy_framebuffer(int fb_dst, int fb_src, int left, int top, int use_back) {
const bool is_main_fb = (fb_src == 0);

if (is_main_fb) {
if (left > 0 && top > 0) {
// upscale the position
left = left * gfx_current_dimensions.width / gfx_current_native_viewport.width;
top = top * gfx_current_dimensions.height / gfx_current_native_viewport.height;
// flip Y
top = gfx_current_dimensions.height - top - 1;
}
if (use_back && gfx_msaa_level > 1) {
// read from the framebuffer we've been rendering to
fb_src = game_framebuffer;
}
}
gfx_rapi->copy_framebuffer(fb_dst, fb_src, left, top);

gfx_rapi->copy_framebuffer(fb_dst, fb_src, left, top, is_main_fb, (bool)use_back);
}

extern "C" void gfx_reset_framebuffer(void) {
Expand Down
2 changes: 1 addition & 1 deletion port/fast3d/gfx_rendering_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ struct GfxRenderingAPI {
bool opengl_invert_y, bool render_target, bool has_depth_buffer,
bool can_extract_depth);
bool (*start_draw_to_framebuffer)(int fb_id, float noise_scale);
void (*copy_framebuffer)(int fb_dst, int fb_src, int left, int top);
void (*copy_framebuffer)(int fb_dst, int fb_src, int left, int top, bool flip_y, bool use_back);
void (*clear_framebuffer)(void);
void (*resolve_msaa_color_buffer)(int fb_id_target, int fb_id_source);
void* (*get_framebuffer_texture_id)(int fb_id);
Expand Down
4 changes: 3 additions & 1 deletion port/include/video.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@ u32 videoGetTextureFilter2D(void);

void videoSetWindowOffset(s32 x, s32 y);

s32 videoCreateFramebuffer(u32 w, u32 h);
s32 videoCreateFramebuffer(u32 w, u32 h, s32 upscale, s32 autoresize);
void videoSetFramebuffer(s32 target);
void videoResetFramebuffer(void);
void videoCopyFramebuffer(s32 dst, s32 src, s32 left, s32 top);
void videoResizeFramebuffer(s32 target, u32 w, u32 h, s32 upscale, s32 autoresize);
s32 videoFramebuffersSupported(void);

void videoResetTextureCache(void);
void videoFreeCachedTexture(const void *texptr);
Expand Down
12 changes: 12 additions & 0 deletions port/src/pdsched.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ u32 var8005cea4 = 0;
OSScMsg g_SchedRspMsg = {OS_SC_RSP_MSG};
bool g_SchedIsFirstTask = true;

s32 g_PrevFrameFb = -1;
s32 g_PrevFrameCapTimer = -1;

void schedSetCrashEnable1(bool enable)
{
g_SchedCrashEnable1 = enable;
Expand Down Expand Up @@ -176,6 +179,8 @@ void osCreateScheduler(OSSched *sc, OSThread *thread, u8 mode, u32 numFields)

osViSetEvent(&sc->interruptQ, (OSMesg)VIDEO_MSG, numFields);
schedInitCrashLastRendered();

g_PrevFrameFb = videoCreateFramebuffer(0, 0, false, true);
}

void osScAddClient(OSSched *sc, OSScClient *c, OSMesgQueue *msgQ, bool is30fps)
Expand Down Expand Up @@ -386,6 +391,13 @@ void schedConsiderScreenshot(void)
g_MenuData.screenshottimer = 0;
}

if (g_PrevFrameCapTimer == 0) {
videoCopyFramebuffer(g_PrevFrameFb, 0, -1, -1);
g_PrevFrameCapTimer = -1;
} else if (g_PrevFrameCapTimer > 0) {
--g_PrevFrameCapTimer;
}

if (g_MenuData.screenshottimer >= 2) {
g_MenuData.screenshottimer--;
}
Expand Down
Loading

0 comments on commit ac46cf8

Please sign in to comment.