mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-06 15:58:05 +02:00
r300: split large HiZ clears into multiple packets
R300_PACKET3_3D_CLEAR_HIZ encodes COUNT in 14 bits (COUNT[13:0]), so a single packet can clear at most 0x3fff dwords. Large depth surfaces on R5xx can require more HiZ dwords than that. When we emitted a single packet, COUNT truncated and part of HiZ RAM remained uncleared, which could show up as HyperZ corruption. Emit CLEAR_HIZ in chunks of R300_CLEAR_HIZ_COUNT_MAX and reserve enough atom space for the worst-case packet count derived. Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/360 Fixes:12dcbd5954("r300g: enable Hyper-Z by default on r500") (cherry picked from commitfddc101070) Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40752>
This commit is contained in:
parent
2b87cb01b2
commit
dfd0e55b5a
4 changed files with 37 additions and 11 deletions
|
|
@ -654,7 +654,7 @@
|
|||
"description": "r300: split large HiZ clears into multiple packets",
|
||||
"nominated": true,
|
||||
"nomination_type": 2,
|
||||
"resolution": 0,
|
||||
"resolution": 1,
|
||||
"main_sha": null,
|
||||
"because_sha": "12dcbd5954676ee32604d82cacbf9a4259967e13",
|
||||
"notes": null
|
||||
|
|
|
|||
|
|
@ -146,6 +146,19 @@ do { \
|
|||
return false; \
|
||||
} while (0)
|
||||
|
||||
static unsigned r300_hiz_clear_atom_size(const struct r300_screen *screen)
|
||||
{
|
||||
if (screen->caps.hiz_ram <= 0)
|
||||
return 0;
|
||||
|
||||
unsigned pipes = r300_hyperz_pipe_count(screen);
|
||||
unsigned max_hiz_dwords = screen->caps.hiz_ram * pipes;
|
||||
unsigned max_hiz_packets =
|
||||
(max_hiz_dwords + R300_CLEAR_HIZ_COUNT_MAX - 1) /
|
||||
R300_CLEAR_HIZ_COUNT_MAX;
|
||||
return max_hiz_packets * 4;
|
||||
}
|
||||
|
||||
static bool r300_setup_atoms(struct r300_context* r300)
|
||||
{
|
||||
bool is_rv350 = r300->screen->caps.is_rv350;
|
||||
|
|
@ -203,8 +216,10 @@ static bool r300_setup_atoms(struct r300_context* r300)
|
|||
/* TX. */
|
||||
R300_INIT_ATOM(texture_cache_inval, 2);
|
||||
R300_INIT_ATOM(textures_state, 0);
|
||||
/* Clear commands */
|
||||
R300_INIT_ATOM(hiz_clear, r300->screen->caps.hiz_ram > 0 ? 4 : 0);
|
||||
/* Clear commands.
|
||||
* 3D_CLEAR_HIZ uses COUNT[13:0], so large clears are split into chunks.
|
||||
* Reserve enough dwords for the worst-case per-chip HiZ RAM size. */
|
||||
R300_INIT_ATOM(hiz_clear, r300_hiz_clear_atom_size(r300->screen));
|
||||
R300_INIT_ATOM(zmask_clear, r300->screen->caps.zmask_ram > 0 ? 4 : 0);
|
||||
R300_INIT_ATOM(cmask_clear, 4);
|
||||
/* ZB (unpipelined), SU. */
|
||||
|
|
|
|||
|
|
@ -1244,17 +1244,26 @@ void r300_emit_hiz_clear(struct r300_context *r300, unsigned size, void *state)
|
|||
{
|
||||
struct pipe_framebuffer_state *fb =
|
||||
(struct pipe_framebuffer_state*)r300->fb_state.state;
|
||||
struct r300_resource* tex;
|
||||
struct r300_resource *tex = r300_resource(fb->zsbuf.texture);
|
||||
unsigned remaining = tex->tex.hiz_dwords[fb->zsbuf.level];
|
||||
unsigned start = 0;
|
||||
CS_LOCALS(r300);
|
||||
|
||||
tex = r300_resource(fb->zsbuf.texture);
|
||||
/* 3D_CLEAR_HIZ COUNT is 14-bit (max 0x3fff), so large surfaces must be
|
||||
* split into multiple packets. */
|
||||
while (remaining) {
|
||||
unsigned count = MIN2(remaining, R300_CLEAR_HIZ_COUNT_MAX);
|
||||
|
||||
BEGIN_CS(size);
|
||||
OUT_CS_PKT3(R300_PACKET3_3D_CLEAR_HIZ, 2);
|
||||
OUT_CS(0);
|
||||
OUT_CS(tex->tex.hiz_dwords[fb->zsbuf.level]);
|
||||
OUT_CS(r300->hiz_clear_value);
|
||||
END_CS;
|
||||
BEGIN_CS(4);
|
||||
OUT_CS_PKT3(R300_PACKET3_3D_CLEAR_HIZ, 2);
|
||||
OUT_CS(start);
|
||||
OUT_CS(count);
|
||||
OUT_CS(r300->hiz_clear_value);
|
||||
END_CS;
|
||||
|
||||
start += count;
|
||||
remaining -= count;
|
||||
}
|
||||
|
||||
/* Mark the current zbuffer's hiz ram as in use. */
|
||||
r300->hiz_in_use = true;
|
||||
|
|
|
|||
|
|
@ -3485,6 +3485,8 @@ enum {
|
|||
* 2. CLEAR_VALUE: Value to write into HIZ RAM.
|
||||
*/
|
||||
#define R300_PACKET3_3D_CLEAR_HIZ 0x00003700
|
||||
/* 3D_CLEAR_HIZ COUNT field width (COUNT[13:0]). */
|
||||
#define R300_CLEAR_HIZ_COUNT_MAX 0x3fff
|
||||
#define R300_PACKET3_3D_CLEAR_CMASK 0x00003800
|
||||
|
||||
/* Draws a set of primitives using vertex buffers pointed by the state data.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue