Skip to content

Commit

Permalink
rdpq: fix latent bug about mode freeze, change of mode and blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
rasky committed Nov 16, 2024
1 parent 7918285 commit b6761ba
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 11 deletions.
5 changes: 4 additions & 1 deletion include/rsp_rdpq.inc
Original file line number Diff line number Diff line change
Expand Up @@ -327,9 +327,12 @@ RDPQ_UpdateRenderMode:
#define bkg_blending t8

# If updates are frozen, do nothing
# We just call RDPQ_Finalize just in case we come
# from RDPQCmd_ResetMode and we have a pending
# scissor change to send.
lw som_hi, %lo(RDPQ_OTHER_MODES) + 0
andi t0, som_hi, SOMX_UPDATE_FREEZE >> 32
bnez t0, RSPQ_Loop
bnez t0, RDPQ_Finalize
lw som_lo, %lo(RDPQ_OTHER_MODES) + 4

# If we are in fill/copy mode, we just need to emit SOM
Expand Down
15 changes: 8 additions & 7 deletions src/rdpq/rdpq_mode.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
* as they are batched instead, so we can avoid reserving space in the
* RDP static buffer in blocks.
*/
#define rdpq_mode_write(num_rdp_commands, ...) ({ \
rdpq_write(rdpq_tracking.mode_freeze ? 0 : num_rdp_commands, ##__VA_ARGS__); \
#define rdpq_mode_write(num_rdp_commands, num_frozen_rdp_commands, ...) ({ \
rdpq_write(rdpq_tracking.mode_freeze ? num_frozen_rdp_commands : num_rdp_commands, ##__VA_ARGS__); \
})

/**
Expand All @@ -29,15 +29,15 @@ __attribute__((noinline))
void __rdpq_fixup_mode(uint32_t cmd_id, uint32_t w0, uint32_t w1)
{
__rdpq_autosync_change(AUTOSYNC_PIPE);
rdpq_mode_write(2, RDPQ_OVL_ID, cmd_id, w0, w1); // COMBINE+SOM
rdpq_mode_write(2, 0, RDPQ_OVL_ID, cmd_id, w0, w1); // COMBINE+SOM
}

/** @brief Write a fixup that changes the current render mode (12-byte command) */
__attribute__((noinline))
void __rdpq_fixup_mode3(uint32_t cmd_id, uint32_t w0, uint32_t w1, uint32_t w2)
{
__rdpq_autosync_change(AUTOSYNC_PIPE);
rdpq_mode_write(2, RDPQ_OVL_ID, cmd_id, w0, w1, w2); // COMBINE+SOM
rdpq_mode_write(2, 0, RDPQ_OVL_ID, cmd_id, w0, w1, w2); // COMBINE+SOM

}

Expand All @@ -46,16 +46,17 @@ __attribute__((noinline))
void __rdpq_fixup_mode4(uint32_t cmd_id, uint32_t w0, uint32_t w1, uint32_t w2, uint32_t w3)
{
__rdpq_autosync_change(AUTOSYNC_PIPE);
rdpq_mode_write(2, RDPQ_OVL_ID, cmd_id, w0, w1, w2, w3); // COMBINE+SOM
rdpq_mode_write(2, 0, RDPQ_OVL_ID, cmd_id, w0, w1, w2, w3); // COMBINE+SOM
}

/** @brief Write a fixup to reset the render mode */
__attribute__((noinline))
void __rdpq_reset_render_mode(uint32_t w0, uint32_t w1, uint32_t w2, uint32_t w3)
{
__rdpq_autosync_change(AUTOSYNC_PIPE);
// ResetRenderMode can genereate: SCISSOR+COMBINE+SOM
rdpq_mode_write(3, RDPQ_OVL_ID, RDPQ_CMD_RESET_RENDER_MODE, w0, w1, w2, w3);
// ResetRenderMode can generate: SCISSOR+COMBINE+SOM when not frozen,
// or just SCISSOR when frozen.
rdpq_mode_write(3, 1, RDPQ_OVL_ID, RDPQ_CMD_RESET_RENDER_MODE, w0, w1, w2, w3);
}

void rdpq_mode_push(void)
Expand Down
10 changes: 7 additions & 3 deletions tests/test_rdpq.c
Original file line number Diff line number Diff line change
Expand Up @@ -1797,6 +1797,7 @@ void test_rdpq_mode_freeze(TestContext *ctx) {

rdpq_debug_log_msg("Mode freeze: standard");
rdpq_set_mode_fill(RGBA32(255,255,255,255));
rdpq_set_blend_color(RGBA32(1,1,1,255));
rdpq_debug_log_msg("Freeze start");
rdpq_mode_begin();
rdpq_set_mode_standard();
Expand Down Expand Up @@ -1825,19 +1826,20 @@ void test_rdpq_mode_freeze(TestContext *ctx) {
// Try again within a block.
debug_rdp_stream_reset();
surface_clear(&fb, 0);
rdpq_set_blend_color(RGBA32(1,1,1,255));
rdpq_debug_log_msg("Mode freeze: in block");
rspq_block_begin();
rdpq_set_mode_fill(RGBA32(255,255,255,255));
rdpq_debug_log_msg("Freeze start");
rdpq_mode_begin();
rdpq_set_mode_standard();
rdpq_set_blend_color(RGBA32(255,255,255,255));
rdpq_set_mode_standard();
rdpq_mode_combiner(RDPQ_COMBINER1((0,0,0,0), (0,0,0,0)));
rdpq_mode_blender(RDPQ_BLENDER((IN_RGB, 0, BLEND_RGB, 1)));
rdpq_mode_filter(FILTER_POINT);
rdpq_mode_alphacompare(false);
rdpq_debug_log_msg("Freeze end");
rdpq_mode_end();
rdpq_set_blend_color(RGBA32(255,255,255,255));
rdp_draw_filled_triangle(0, 0, FBWIDTH, 0, FBWIDTH, FBWIDTH);
rdp_draw_filled_triangle(0, 0, 0, FBWIDTH, FBWIDTH, FBWIDTH);
rspq_block_t *block = rspq_block_end();
Expand Down Expand Up @@ -1868,11 +1870,13 @@ void test_rdpq_mode_freeze(TestContext *ctx) {
DEFER(rspq_block_free(block2));

rdpq_set_mode_fill(RGBA32(255,255,255,255));
rdpq_set_blend_color(RGBA32(1,1,1,255));
rdpq_debug_log_msg("Freeze start");
rdpq_mode_begin();
rspq_block_run(block2);
rdpq_debug_log_msg("Freeze end");
rdpq_mode_end();
rdpq_set_blend_color(RGBA32(255,255,255,255));
rdp_draw_filled_triangle(0, 0, FBWIDTH, 0, FBWIDTH, FBWIDTH);
rdp_draw_filled_triangle(0, 0, 0, FBWIDTH, FBWIDTH, FBWIDTH);
rspq_wait();
Expand All @@ -1883,7 +1887,7 @@ void test_rdpq_mode_freeze(TestContext *ctx) {
num_nops = debug_rdp_stream_count_cmd(0xC0);
ASSERT_EQUAL_SIGNED(num_ccs, 1, "too many SET_COMBINE_MODE");
ASSERT_EQUAL_SIGNED(num_soms, 2, "too many SET_OTHER_MODES"); // 1 SOM for fill, 1 SOM for standard
ASSERT_EQUAL_SIGNED(num_nops, 9, "wrong number of NOPs");
ASSERT_EQUAL_SIGNED(num_nops, 8, "wrong number of NOPs");
}

void test_rdpq_mode_freeze_stack(TestContext *ctx) {
Expand Down

0 comments on commit b6761ba

Please sign in to comment.