Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions include/rdpq.h
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,52 @@ inline void rdpq_set_yuv_parms(uint16_t k0, uint16_t k1, uint16_t k2, uint16_t k
_carg(x1fx, 0xFFF, 12) | _carg(y1fx, 0xFFF, 0)); \
})

/** @brief Only keep/draw even lines while drawing to a buffer */
#define RDP_INTERLACE_DRAW_ODD 1
/** @brief Only keep/draw odd lines while drawing to a buffer */
#define RDP_INTERLACE_DRAW_EVEN 0

/**
* @brief Enable whether the RDP should only draw even or odd lines (for interlaced displays) (RDP command: SET_SCISSOR)
*
* This function is used to configure an interlacing function the RDP internally has
* to only draw half the lines into a framebuffer (Z-buffer is interlaced as well
* automatically).
*
* This interlacing mode assumes that the framebuffer itself has both fields in it
* and it can work on any framebuffer size (320x240, 512x256, 640x480 etc.)
*
* This interlacing mode saves half the RDP's fillrate since it skips half the lines
* to draw. This is very helpful for performance in high-res mode since the system
* is primairly fillrate constrained.
*
*
* @param[in] draw_field True if the RDP should only draw odd lines, otherwise only even lines are drawn
*
*/
inline void rdpq_enable_interlaced(int draw_field) {
__rdpq_set_scissor(
0,
_carg(1, 0x1, 26) | _carg(1, 0x1, 25) | _carg(draw_field & 1, 0x1, 24));
}

/**
* @brief Disable the RDP interlacing feature to be able to draw all lines in a framebuffer (RDP command: SET_SCISSOR)
*
* This function is used to configure an interlacing function the RDP internally has
* to only draw half the lines into a framebuffer (Z-buffer is interlaced as well
* automatically). This function disables this functionality.
*
*
* @see #rdpq_enable_interlaced
* */
inline void rdpq_disable_interlaced() {
__rdpq_set_scissor(
0,
_carg(1, 0x1, 26) | _carg(0, 0x1, 25) | _carg(0, 0x1, 24));
}


/**
* @brief Set a fixed Z value to be used instead of a per-pixel value (RDP command; SET_PRIM_DEPTH)
*
Expand Down
19 changes: 19 additions & 0 deletions include/rsp_rdpq.inc
Original file line number Diff line number Diff line change
Expand Up @@ -674,7 +674,26 @@ rdpq_update_fillcopy:
#############################################################
.func RDPQ_WriteSetScissor
RDPQ_WriteSetScissor:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the reason you put the change here, instead of in RDPQCmd_SetScissorEx? RDPQ_WriteSetScissor is called any time a ucode needs to reset the scissoring (eg: rdpq_mode has to call it when it switches cycle type). So its main use is "reapply the current scissor settings".

I believe the change should go to RDPQCmd_SetScissorEx instead, which is what is called to process the rspq command used to set scissoring (and now interlacing). That's probably where the special semantic should go.

# Check whether we have sent a scissor rect command or interlacing command by checking 26th bit
li t6, 0x1 << 26
and t6, t6, a1
beqz t6, 3f
lw a2, %lo(RDPQ_SCISSOR_RECT) + 0x4

# Only update the interlacing info in low word if we've sent an rdp interlacing command
li t6, ~(3 << 24)
and a2, a2, t6
or a1, a2, a1
j 1f
sw a1, %lo(RDPQ_SCISSOR_RECT) + 0x4
3:
# Load the interlacing info from the state info if we've sent a scissor rect command
li t6, (3 << 24)
and a2, a2, t6
Comment thread
SpookyIluha marked this conversation as resolved.
sw a0, %lo(RDPQ_SCISSOR_RECT) + 0x0
or a1, a2, a1

lb t6, %lo(RDPQ_OTHER_MODES) + 0x1
# Bit 21 of the first word is set if FILL or COPY mode is active
andi t6, 0x1 << 5
Expand Down
2 changes: 2 additions & 0 deletions src/rdpq/rdpq.c
Original file line number Diff line number Diff line change
Expand Up @@ -1194,3 +1194,5 @@ extern inline void rdpq_set_lookup_address(uint8_t index, void* rdram_addr);
extern inline void rdpq_set_tile(rdpq_tile_t tile, tex_format_t format, int32_t tmem_addr, uint16_t tmem_pitch, const rdpq_tileparms_t *parms);
extern inline void rdpq_call_deferred(void (*func)(void *), void *arg);
extern inline void rdpq_set_yuv_parms(uint16_t k0, uint16_t k1, uint16_t k2, uint16_t k3, uint16_t k4, uint16_t k5);
extern inline void rdpq_enable_interlaced(int draw_field);
extern inline void rdpq_disable_interlaced();
Loading