[Bug 110897] HyperZ is broken for r300 (bad z for some micro and macrotiles?)

bugzilla-daemon at freedesktop.org bugzilla-daemon at freedesktop.org
Fri Jun 14 17:20:13 UTC 2019


https://bugs.freedesktop.org/show_bug.cgi?id=110897

--- Comment #33 from Richard Thier <u9vata at gmail.com> ---
Created attachment 144548
  --> https://bugs.freedesktop.org/attachment.cgi?id=144548&action=edit
Working hack / quickfix

Pretty interesting but I just tried to change the "most logical" part of
r300_texture_desc.c and now it works - see quickfix patch.

I will tell you all what was my approach. I just started to ignore all my
previous attempts and go for a more "mágus" approach. That is is like "bogus"
approach, but "mágus" approach involves faith and magix haha.

The goal was to find a way to make the still non-erronous area of the image
grow. Just by trying around the code and possibly breaking law of the rules
(Judas Priest song should play in the background while readers read this for
best effect).

So this file seemed to be the good candidate for "breaking the law" and just
"mágus-approach" trying: r300_texture_desc.c

Then there was this part:

376             /* Get the ZMASK buffer size in dwords. */
377             zcomp_numdw = r300_pixels_to_dwords(stride, height,
378                     zmask_blocks_x_per_dw[pipes-1] * zcompsize,
379                     zmask_blocks_y_per_dw[pipes-1] * zcompsize);
380 
381             /* Check whether we have enough ZMASK memory. */
382             if (util_format_get_blocksizebits(tex->b.b.format) == 32 &&
383                 zcomp_numdw <= screen->caps.zmask_ram * pipes) {
384                 tex->tex.zmask_dwords[i] = zcomp_numdw;
385                 tex->tex.zcomp8x8[i] = zcompsize == 8;
386 
387                 tex->tex.zmask_stride_in_pixels[i] =
388                    util_align_npot(stride, zmask_blocks_x_per_dw[pipes-1] *
zcompsize);

The "zcomp_numdw" seems to be "the number of dwords" in the zmask_ram - and the
zmask ram is the compressed z-buffer itself. This "tex->tex.zmask_dwords[i]"
has multiple element because of the mip level. Of course I think only the first
element ever exists for zbuffer as I haven't seen mipmapped z ever just telling
you why there is indexing.

In short I saw earlier that this "zmask_dwords" get used later on even when
emitting but also at other places like in r300_blit.c for example. It is used
pretty much so this seemed to be the thing to change in my planned "mágus" way
;-)

I went and first doubled the value like this (please mind the "*2"):

376             /* Get the ZMASK buffer size in dwords. */
377             zcomp_numdw = r300_pixels_to_dwords(stride, height,
378                  zmask_blocks_x_per_dw[pipes-1] * zcompsize*2,
379                  zmask_blocks_y_per_dw[pipes-1] * zcompsize*2);

After that change the "still uneffected" area of the screen shrink roughly to
its 1/4th so I figured instead of multiplying the values I should divide them
by two (just guessing):

376             /* Get the ZMASK buffer size in dwords. */
377             zcomp_numdw = r300_pixels_to_dwords(stride, height,
378                  zmask_blocks_x_per_dw[pipes-1] * zcompsize/2,
379                  zmask_blocks_y_per_dw[pipes-1] * zcompsize/2);

And indeed now the whole screen is good and performance is fast too.
It is a hack however - just pure magic so far, but it seems that somehow this
value might be the one that can fix the problem.

My idea is that maybe that value of "pipes" is wrong???

This is where that variable is set:

357         if (screen->caps.family == CHIP_RV530) {
358             pipes = screen->info.r300_num_z_pipes;
359         } else {
360             pipes = screen->info.r300_num_gb_pipes;
361         }

Also because my card is not CHIP_RV530 the value is the
screen->info.r300_num_gb_pipes

This is set in: radeon_drm_winsys.c / do_winsys_init(...)

385     if (ws->gen == DRV_R300) {
386         if (!radeon_get_drm_value(ws->fd, RADEON_INFO_NUM_GB_PIPES,
387                                   "GB pipe count",
388                                   &ws->info.r300_num_gb_pipes))
389             return false;

I have no idea where this value comes from. Would need to see the other side in
the kernel modules I guess or some other places. If this is wrong it might
maybe cause other problems for me that I am not aware of while things still
generally work most of the time?

Also just a note for myself - the RC410 is R300 class / kind card not an R400
it seems - but I saw places where is_rv350 returns true, so those things seem
to be on in the driver for me at least:

205     case CHIP_R300:
206     case CHIP_R350:
207     case CHIP_RV350:
208     case CHIP_RV370:
209     case CHIP_RV380:
210     case CHIP_RS400:
211     case CHIP_RC410:
212     case CHIP_RS480:
213         ws->info.chip_class = R300;

So gb_pipes is 3 for my case, but maybe it should be a different value and this
is set badly for some reason. Of course this would explain the problem better.

One more thing: I build mesa to my own prefix and after this hacky quickfix
patch things immediately started working - even if I run glxgears with HYPERZ
from an other terminal that still runs with unchanged mesa!!! This is weird a
bit, but it might give me some insights why yesterday the whole thing was
working without me touching the relevant parts of the source: it seems if any
apps start up with proper hyperZ then it becomes pretty easy for the card to
"get stuck" in the good state for whatever reasons unknown to me.

-- 
You are receiving this mail because:
You are the assignee for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/dri-devel/attachments/20190614/3f24e2f7/attachment-0001.html>


More information about the dri-devel mailing list