<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Thu, May 3, 2018 at 12:29 PM, Gert Wollny <span dir="ltr"><<a href="mailto:gert.wollny@collabora.com" target="_blank">gert.wollny@collabora.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">Am Donnerstag, den 03.05.2018, 11:43 -0400 schrieb Ilia Mirkin:<br>
> You're supposed to keep track of the bound state (usually in the<br>
> context). After your clear() implementation is done, you have to undo<br>
> all the state you've messed up on your "hardware" (or mark it dirty<br>
> for revalidation).<br>
<br>
</span>Thanks for you answer, but I think I didn't explain the issue properly.<br>
<br>
<br>
The problem is not the state after the clear(), it is what is happening<br>
before. To explain the specific case GL_RASTERIZER_DISCARD.<br>
<br>
In the tests I mentioned you see following for the standalone test <br>
<br>
- setup contest and buffers <br>
- glClear(...)<br>
- glEnable(GL_RASTERIZER_<wbr>DISCARD)<br>
- ... <br>
- glDrawArrays(...) <br>
- glDisable(GL_RASTERIZER_<wbr>DISCARD) <br>
- check result <br>
- Tear down buffers and context <br>
<br>
On a normal host (r600 in my case) I see state updates before clear<br>
(initial setup) and a state update initialized by glDrawArrays. <br>
The state update related to the glDisable is not really transmitted to<br>
the hardware since it is not needed. <br>
<br>
On virgl the first state update isn't send to the host, but since the<br>
test is run stand-alone, and GL_RASTERIZER_DISCARD is disabled by<br>
default all is fine, i.e. clear() works as expected and the glDisable<br>
is of no consequence. <br>
<br>
Now, if you run the test suite batched, you get <br>
<br>
- setup contest and buffers <br>
- FOREACH rasterizer_discard_test<br>
- glClear(...)<br>
- glEnable(GL_RASTERIZER_<wbr>DISCARD)<br>
- ... <br>
- glDrawArrays(...) <br>
- glDisable(GL_RASTERIZER_<wbr>DISCARD) <br>
- check result<br>
- ENDFOR<br>
- Tear down buffers and context <br>
<br>
Here, at each beginning of the loop the "normal" host sends a state<br>
update to the hardware before clear is actually executed, because the<br>
blitter validates the render state. Hence<br>
glDisable(GL_RASTERIZER_<wbr>DISCARD) goes into effect in consecutive runs<br>
and the clear() operation actually clears the buffers.<br>
<br>
On virgl the current code path for virgl_clear doesn't validate the<br>
render state, i.e. it doesn't do a blit like drivers that directly talk<br>
to the hardware and that validates the render state before the actual<br>
drawing happens. Virgl it just sends the command indicating clear from<br>
the guest running in Qemu to the host, without validating the state<br>
first. Hence the host doesn't update the hardware state, because it <br>
doesn't know that glDisable(GL_RASTERIZER_<wbr>DISCARD) was called in the<br>
guest, and the blit, that will eventually be executed on the host is<br>
still executed as if GL_RASTERIZER_DISCARD were enabled. <br>
<br>
Now, calling st_validate_state(st, ST_PIPELINE_RENDER) before<br>
virgl_clear is called solves the problem, but I see that this might not<br>
be thebest solution, because then all drivers that actually use the<br>
blitter will validate the render state a second time without need. <br></blockquote><div><br>tl;dr. Is the problem that Clear in virgl obeys rasterizer_discard? Well then you have a bigger problem, because rasterizer_discard should have no effect on Clear like in this example where glClear should be executed normally:<br><br></div><div>glEnable(GL_RASTERIZER_DISCARD);<br></div><div>glClear(GL_COLOR_BUFFER_BIT);<br></div><div>glDisable(GL_RASTERIZER_DISCARD);<br><br></div><div>Marek<br></div></div></div></div>