The function blorp_emit_gen8_hiz_op contains a pipe control operation that has only the WriteImmediateData bit set. It doesn't specify an address, so this results in a store to address 0.
a) What is this pipe control for? I don't see the need for it in the docs.
From what I can see, the docs for 3DSTATE_WM_HZ_OP say: "As this command generates an implicit rectangle, SW must make sure any MMIO register writes following WM_HZ_OP must be preceded by PIPE_CONTROL with Command Streamer Stall Enable bit set."
In the code there's a following PIPECONTROL with depth_stall and depth flush bits set, which corresponds to the docs in the section 'Depth Buffer Clear'.
b) How is it not a problem to emit a pipecontrol that writes to address 0?
As for a), the comments in i965 are a bit better:
/* Emit a PIPE_CONTROL with "Post-Sync Operation" set to "Write Immediate
* Data", and no other bits set. This causes 3DSTATE_WM_HZ_OP's state to
* take effect, and spawns a rectangle primitive.
3DSTATE_WM_HZ_OP is kind of weird - it overrides all the state, and sets up a rectangle primitive that's about ready to fire...but it needs a flush to actually push it over the edge and make it happen. No idea why they designed it this way.
b) It's absolutely a problem - that code is definitely broken. Good catch!
Ken, crazy idea but how would you feel about just pinning the workaround BO to address 0?
Fwiw, switching from WriteImmediateData to CommandStreamerStall on skylake appears to work.
How about making the zero page always invalid, to catch inadvertent accesses like this?
There's a patch on the list to fix this:
Issue should be resolved with the following. Feel free to reopen otherwise.
Author: Jason Ekstrand <email@example.com>
Date: Mon Jun 5 14:19:28 2017 -0700
intel/blorp: Plumb through access to the workaround BO