<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Thu, Mar 24, 2016 at 7:45 PM, Francisco Jerez <span dir="ltr"><<a href="mailto:currojerez@riseup.net" target="_blank">currojerez@riseup.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">Francisco Jerez <<a href="mailto:currojerez@riseup.net">currojerez@riseup.net</a>> writes:<br>
<br>
> Jason Ekstrand <<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>> writes:<br>
><br>
>> On Thu, Mar 24, 2016 at 5:50 PM, Kenneth Graunke <<a href="mailto:kenneth@whitecape.org">kenneth@whitecape.org</a>><br>
>> wrote:<br>
>><br>
>>> dEQP-GLES31.functional.fbo.no_attachments.* draws a quad with no<br>
>>> framebuffer attachments, using a shader that discards based on<br>
>>> gl_FragCoord.  It uses occlusion queries to inspect whether pixels<br>
>>> are rendered or not.<br>
>>><br>
>>> Unfortunately, the hardware is not dispatching any pixel shaders,<br>
>>> so discards never happen, and the full quad of pixels increments<br>
>>> PS_DEPTH_COUNT, making the occlusion query results bogus.<br>
>>><br>
>>> To understand why, we have to delve into the WM_INT internal<br>
>>> signalling mechanism's formulas.<br>
>>><br>
>>> The "WM_INT::Pixel Shader Kill Pixel" signal is defined as:<br>
>>><br>
>>>     3DSTATE_WM::ForceKillPixel == ON ||<br>
>>>     (3DSTATE_WM::ForceKillPixel != Off &&<br>
>>>      !WM_INT::WM_HZ_OP &&<br>
>>>      3DSTATE_WM::EDSC_Mode != PREPS &&<br>
>>>      (WM_INT::Depth Write Enable || WM_INT::Stencil Write Enable) &&<br>
>>>      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^<br>
>>>      (3DSTATE_PS_EXTRA::PixelShaderKillsPixels ||<br>
>>>       3DSTATE_PS_EXTRA:: oMask Present to RenderTarget ||<br>
>>>       3DSTATE_PS_BLEND::AlphaToCoverageEnable ||<br>
>>>       3DSTATE_PS_BLEND::AlphaTestEnable ||<br>
>>>       3DSTATE_WM_CHROMAKEY::ChromaKeyKillEnable))<br>
>>><br>
>>> Because there is no depth or stencil buffer, writes to those buffers<br>
>>> are disabled.  So the highlighted condition is false, making the whole<br>
>>> "Kill Pixel" condition false.  This then feeds into the following<br>
>>> "WM_INT::ThreadDispatchEnable" condition:<br>
>>><br>
>>>     3DSTATE_WM::ForceThreadDispatch != OFF &&<br>
>>>     !WM_INT::WM_HZ_OP &&<br>
>>>     3DSTATE_PS_EXTRA::PixelShaderValid &&<br>
>>>     (3DSTATE_PS_EXTRA::PixelShaderHasUAV ||<br>
>>>      WM_INT::Pixel Shader Kill Pixel ||<br>
>>>      WM_INT::RTIndependentRasterizationEnable ||<br>
>>>      (!3DSTATE_PS_EXTRA::PixelShaderDoesNotWriteRT &&<br>
>>>       3DSTATE_PS_BLEND::HasWriteableRT) ||<br>
>>>      (WM_INT::Pixel Shader Computed Depth Mode != PSCDEPTH_OFF &&<br>
>>>       (WM_INT::Depth Test Enable || WM_INT::Depth Write Enable)) ||<br>
>>>      (3DSTATE_PS_EXTRA::Computed Stencil && WM_INT::Stencil Test Enable) ||<br>
>>>      (3DSTATE_WM::EDSC_Mode == 1 && (WM_INT::Depth Test Enable ||<br>
>>>                                      WM_INT::Depth Write Enable ||<br>
>>>                                      WM_INT::Stencil Test Enable)))<br>
>>><br>
>>> Given that there's no depth/stencil testing, no writeable render target,<br>
>>> and the hardware thinks kill pixel doesn't happen, all of these<br>
>>> conditions are false.  We have to whack some bit to make PS invocations<br>
>>> happen.  There are many options.<br>
>>><br>
>>> Curro suggested using the UAV bit.  There's some precedence in doing<br>
>>> that - we set it for fragment shaders that do SSBO/image/atomic writes<br>
>>> when no color buffer writes are enabled.  We can simply include discard<br>
>>> here too.<br>
>>><br>
>>> Fixes 64 dEQP-GLES31.functional.fbo.no_attachments.* tests.<br>
>>><br>
>>> Signed-off-by: Kenneth Graunke <<a href="mailto:kenneth@whitecape.org">kenneth@whitecape.org</a>><br>
>>> ---<br>
>>>  src/mesa/drivers/dri/i965/gen8_ps_state.c | 4 ++--<br>
>>>  1 file changed, 2 insertions(+), 2 deletions(-)<br>
>>><br>
>>> diff --git a/src/mesa/drivers/dri/i965/gen8_ps_state.c<br>
>>> b/src/mesa/drivers/dri/i965/gen8_ps_state.c<br>
>>> index b9a06e7..cda8159 100644<br>
>>> --- a/src/mesa/drivers/dri/i965/gen8_ps_state.c<br>
>>> +++ b/src/mesa/drivers/dri/i965/gen8_ps_state.c<br>
>>> @@ -93,8 +93,8 @@ gen8_upload_ps_extra(struct brw_context *brw,<br>
>>>      *<br>
>>>      * BRW_NEW_FS_PROG_DATA | BRW_NEW_FRAGMENT_PROGRAM | _NEW_BUFFERS |<br>
>>> _NEW_COLOR<br>
>>>      */<br>
>>> -   if (_mesa_active_fragment_shader_has_side_effects(&brw->ctx) &&<br>
>>> -       !brw_color_buffer_write_enabled(brw))<br>
>>> +   if ((_mesa_active_fragment_shader_has_side_effects(ctx) ||<br>
>>> +        prog_data->uses_kill) && !brw_color_buffer_write_enabled(brw))<br>
>>><br>
>><br>
>> Whould you mind adding a short comment as to why uses_kill is in here?  You<br>
>> don't need the full explination above, bot something along the lines of<br>
>><br>
>> "Gen8 hardware tries to compute ThreadDispatchEnable for us but doesn't<br>
>> take into account KillPixels when no depth or stencil writes are enabled.<br>
>> In order for occlusion queries to work correctly with no attachments, we<br>
>> need to force-enable here."<br>
>><br>
> That sounds good to me.<br>
><br>
>> You can come up with your own text if you'd like.<br>
>><br>
>> One other thought: Do we know if HAS_UAV has any perf impact other than<br>
>> actually running the shader?  I would guess not, but if it does we may want<br>
>> to make the condition a bit more specifi.<br>
>><br>
><br>
> It does, it causes an implicit DC flush at the bottom of the pipeline,<br>
> see the comment right on top of this code for a more detailed<br>
> explanation.  It would definitely be possible to make the check more<br>
> specific by e.g. setting the bit only if both stencil and depth writes<br>
> are disabled (in addition to color buffer writes), but Ken had some<br>
> concerns about the additional state dependencies that would introduce<br>
> when I brought up the same question earlier today in the office.  Anyway<br>
> this only gets turned on when no color buffer writes are enabled so it<br>
> doesn't seem like a huge deal, but it would of course be nice to do the<br>
> additional checks.<br>
><br>
</div></div>Let me elaborate a bit more why I don't think setting the has-UAV bit in<br>
this case is a big deal: On the one hand, unless the application is<br>
using shader images, SSBOs or atomics the implicit DC flush shouldn't be<br>
too expensive because the DC is likely to be already close to being<br>
coherent with the L3, so the flush shouldn't do much work -- However if<br>
the shader *is* using images, SSBOs or atomics the has_side_effects<br>
check in the same conditional will evaluate to true and the has-UAV bit<br>
will be set (or not) regardless of the additional uses_kill condition.<br>
On the other hand, because we don't use the UAV coherency mechanism (and<br>
are unlikely to use it anytime soon), the DC flush is asynchronous and<br>
doesn't lead to a pipeline stall on subsequent geometry processing, so<br>
it shouldn't hurt much anyway.<br></blockquote><div><br></div><div>Right, but what about the dept-stencil-only-with-a-discard case?  In that case, we don't need to force pixel shader dispatch because KillsPixels will enable it and we would really rather not have a DC flush after every 3DPRIMITIVE.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
BTW, if you're curious about the workings of the UAV coherency<br>
mechanism, I wrote most of what I could find out in the commit message<br>
of 5346c1167064d6429c6338974c6342f8346fd34b.  I haven't found any decent<br>
documentation about it anywhere else...<br>
<div class="HOEnZb"><div class="h5"><br>
>> Other than that, looks good to me.<br>
>> --Jason<br>
>><br>
>><br>
>>>        dw1 |= GEN8_PSX_SHADER_HAS_UAV;<br>
>>><br>
>>>     if (prog_data->computed_stencil) {<br>
>>> --<br>
>>> 2.7.4<br>
>>><br>
>>> _______________________________________________<br>
>>> mesa-dev mailing list<br>
>>> <a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
>>> <a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
>>><br>
>> _______________________________________________<br>
>> mesa-dev mailing list<br>
>> <a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
>> <a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</div></div></blockquote></div><br></div></div>