<div dir="ltr"><div class="gmail_quote"><div dir="ltr">On Tue, Sep 18, 2018 at 4:08 AM Danylo Piliaiev <<a href="mailto:danylo.piliaiev@gmail.com">danylo.piliaiev@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
    <div text="#000000" bgcolor="#FFFFFF"><div class="m_-6732043544054597089moz-cite-prefix">On 9/17/18 7:03 PM, Jason Ekstrand
      wrote:<br>
    </div>
    <blockquote type="cite">
      
      <div dir="ltr">
        <div class="gmail_quote">
          <div dir="ltr">On Mon, Sep 17, 2018 at 10:08 AM Danylo
            Piliaiev <<a href="mailto:danylo.piliaiev@gmail.com" target="_blank">danylo.piliaiev@gmail.com</a>>
            wrote:<br>
          </div>
          <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
            <div text="#000000" bgcolor="#FFFFFF"> <br>
              <br>
              <div class="m_-6732043544054597089m_8653083740311233362moz-cite-prefix">On
                9/17/18 5:34 PM, Jason Ekstrand wrote:<br>
              </div>
              <blockquote type="cite">
                <div dir="ltr">
                  <div class="gmail_quote">
                    <div dir="ltr">On Mon, Sep 17, 2018 at 8:34 AM
                      Danylo Piliaiev <<a href="mailto:danylo.piliaiev@gmail.com" target="_blank">danylo.piliaiev@gmail.com</a>>
                      wrote:<br>
                    </div>
                    <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
                      <div text="#000000" bgcolor="#FFFFFF"> Hi Jason,<br>
                        <br>
                        I have implemented the extension and it works,
                        however before sending the patch I decided to
                        see how it can interact with other extension -
                        VK_EXT_conditional_render<br>
                        and got confused:<br>
                        <br>
                        From the spec it is not disallowed to call
                        functions of VK_KHR_draw_indirect_count in
                        conditional rendering block. So let's say that
                        predicate of conditional rendering<br>
                        will result in FALSE, we call <span class="m_-6732043544054597089m_8653083740311233362m_8153322649885267684blob-code-inner
m_8653083740311233362m_8153322649885267684blob-code-marker-addition"><span class="m_-6732043544054597089m_8653083740311233362m_8153322649885267684pl-s">vkCmdDrawIndirectCountKHR
                            which sees that there is already a predicate
                            emitted and it should be taken into account,
                            since it will be FALSE<br>
                            all next predicates should result in FALSE.
                            The issue is that I don't see an easy way to
                            do this.<br>
                            <br>
                            My current implementation uses the next
                            predicate (it is same as in GL
                            implementation):<br>
                            <br>
                            <tt>       /* While draw_index <
                              maxDrawCount the predicate's result will
                              be</tt><tt><br>
                            </tt><tt>        *  (draw_index ==
                              maxDrawCount) ^ TRUE = TRUE</tt><tt><br>
                            </tt><tt>        * When draw_index ==
                              maxDrawCount the result is</tt><tt><br>
                            </tt><tt>        *  (TRUE) ^ TRUE = FALSE</tt><tt><br>
                            </tt><tt>        * After this all results
                              will be:</tt><tt><br>
                            </tt><tt>        *  (FALSE) ^ FALSE = FALSE</tt><tt><br>
                            </tt><tt>        */</tt><tt><br>
                            </tt><tt>      
                              anv_batch_emit(&cmd_buffer->batch,
                              GENX(MI_PREDICATE), mip) {</tt><tt><br>
                            </tt><tt>          mip.LoadOperation    =
                              LOAD_LOAD;</tt><tt><br>
                            </tt><tt>          mip.CombineOperation =
                              COMBINE_XOR;</tt><tt><br>
                            </tt><tt>          mip.CompareOperation =
                              COMPARE_SRCS_EQUAL;</tt><tt><br>
                            </tt><tt>       }</tt><br>
                            <br>
                            But if the initial predicate state is FALSE
                            then when draw_index equals maxDrawCount the
                            result will be<br>
                              <tt>(FALSE) ^ TRUE = TRUE</tt><br>
                            Which isn't something we want. But without
                            "not equal" operation or without MI_MATH I
                            don't see how to fix this.<br>
                          </span></span></div>
                    </blockquote>
                    <div><br>
                    </div>
                    <div>First off, thanks for looking into the
                      combination of these two features.  Getting them
                      to work together nicely is half of the difficulty
                      of these two extensions.<br>
                    </div>
                    <div><br>
                    </div>
                    <div>On platforms which support MI_MATH, I think
                      we're probably better off just using it.  For Ivy
                      Bridge, the only thing I could think to do when
                      both are in use would be to do two MI_PREDICATEs
                      for every draw call.  The first would be what you
                      describe above and the second would be the
                      MI_PREDICATE for the conditional render with
                      COMBINE_AND.  When the condition is true, the AND
                      would have no effect and you would get the
                      behavior above.  If the condition is false, the
                      above logic for implementing draw_indirect_count
                      wouldn't matter because it would get ANDed with
                      false.  On Haswell and later, it's likely more
                      efficient to just use MI_MATH and avoid re-loading
                      the draw count and condition on every draw call. 
                      (We could just leave the draw count in CS_GPR0,
                      for instance.)  Does that work?</div>
                  </div>
                </div>
              </blockquote>
              Looks like a plan. I'll try to go this path.<br>
              <br>
              Also there is another interaction which wasn't thought of
              before:<br>
              Several <span class="m_-6732043544054597089m_8653083740311233362m_8153322649885267684blob-code-inner
m_8653083740311233362m_8153322649885267684blob-code-marker-addition"><span class="m_-6732043544054597089m_8653083740311233362m_8153322649885267684pl-s">vkCmdDrawIndirectCountKHR
                  in conditional render block but using MI_MATH should
                  solve it.<br>
                </span></span></div>
          </blockquote>
          <div><br>
          </div>
          <div>In that case, we'll have to basically re-do the
            conditional bit for every draw call.  There may be some
            interesting interactions here with secondary command buffers
            as well.  I don't remember what we decided about inheriting
            conditions in secondaries.  Again, if we decide we need
            MI_MATH, then we'll just drop support for one or both
            extensions on Ivy Bridge.</div>
          <div><br>
          </div>
        </div>
      </div>
    </blockquote>
    About the secondary command buffers:<br>
    <br>
    If <a href="https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#features-features-inheritedConditionalRendering" target="_blank">inherited
      conditional
      rendering</a> is supported it means that secondary buffers can be
    executed inside conditional rendering block and commands which can
    be affected by conditional rendering are affected by it in secondary
    buffer and also in primary, is it right?<br>
    However at this point the secondary buffer is already composed
    without commands for conditions and since our implementation depends
    on commands emitted to the buffer making its commands to depend on
    condition either highly tricky to do (secondary buffer needs to have
    certain points where to inject conditions?) or just impossible. <br>
    And this secondary buffer may have been formed inside conditional
    render block so they could be affected by two conditions if I
    understand correctly.<br>
    <br>
    Is is doable to implement?<br></div></blockquote><div><br></div><div>I think it is.  The obvious way to implement it would be to have a boolean in the command buffer somewhere that tells you whether or not conditional rendering is enabled and use that to set the PredicateEnable bit on 3DPRIMITIVE commands.  For secondary command buffers, however, we would have to assume that predication is enabled and set the predicate to true in vkCmdExecuteCommands if conditional rendering is disabled.</div><div><br></div><div>The second issue is in communicating the predicate value.  If we don't have secondaries, we can just hang on to the condition buffer and re-read it whenever needed.  If we're going to use secondaries, we won't have it available in the secondary.  One obvious option would be to simply reserve one of the CS_GPR registers, say CS_GPR15, for storing the predicate value.  On Ivy Bridge, the CS_GPRs don't exist and we'd have to pick some other RW register.  Digging through the docs, I found the MI_PREDICATE_DATA which seems to exist for just this sort of thing. :-)  Exactly what register we use will have to depend on how we want to compute predicate values; I could see CS_GPR15 being more convenient if we use MI_MATH, for instance.<br></div><div><br></div>--Jason<br></div></div>