<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">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_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_8653083740311233362m_8153322649885267684blob-code-inner m_8653083740311233362m_8153322649885267684blob-code-marker-addition"><span class="m_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_8653083740311233362m_8153322649885267684blob-code-inner m_8653083740311233362m_8153322649885267684blob-code-marker-addition"><span class="m_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><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div text="#000000" bgcolor="#FFFFFF"><span class="m_8653083740311233362m_8153322649885267684blob-code-inner m_8653083740311233362m_8153322649885267684blob-code-marker-addition"><span class="m_8653083740311233362m_8153322649885267684pl-s">
      </span></span>
    <blockquote type="cite">
      <div dir="ltr">
        <div class="gmail_quote">
          <div><br>
          </div>
          <div>Since you're already looking at it, it may be best to
            implement the two extensions together as one patch series so
            we can be sure we have the interactions right.  If we can't
            get them to play nicely together, we may have to disable one
            of them on Ivy Bridge and I'd rather not enable an extension
            and then take the functionality away later.<br>
          </div>
        </div>
      </div>
    </blockquote>
    I agree, the extensions are too interweaved which I realized when
    implemented the most basic version of EXT_conditional_render. I'll
    also make sure to test all of these on Ivy Bridge.<br>
    <blockquote type="cite">
      <div dir="ltr">
        <div class="gmail_quote">
          <div> </div>
          <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
            <div text="#000000" bgcolor="#FFFFFF"><span class="m_8653083740311233362m_8153322649885267684blob-code-inner m_8653083740311233362m_8153322649885267684blob-code-marker-addition"><span class="m_8653083740311233362m_8153322649885267684pl-s"> I don't see
                  anything related in Vulkan or GL specs neither I see
                  anything in Piglit and CTS tests.<br>
                  Maybe I'm missing something obvious, could you help me
                  here?<br>
                </span></span></div>
          </blockquote>
          <div><br>
          </div>
          <div>There's nothing preventing the two from being used
            together.  If we don't have piglit tests that exercise the
            GL versions together, that would be bad.  Have you found
            good Vulkan CTS tests for either of those two extensions? 
            VK_KHR_indirect_count should have tests since it's a KHR
            extension but we may need to write the tests for
            EXT_conditional_render.</div>
        </div>
      </div>
    </blockquote>
    There are no tests of how these features work together in Piglit or
    Vulkan CTS. Also my previous observations are true for GL so it also
    ought to be fixed (I'll write a test for Piglit first to confirm
    this). <br>
    There are tests for VK_KHR_indirect_count in Vulkan CTS which my
    current implementation passes. There aren't any tests for 
    EXT_conditional_render however I used an example from
    <a class="m_8653083740311233362moz-txt-link-freetext" href="https://github.com/SaschaWillems/Vulkan" target="_blank">https://github.com/SaschaWillems/Vulkan</a> to test my initial
    implementation of it.<br>
    Should tests for EXT_conditional_render go into Vulkan CTS? <br></div></blockquote><div><br></div><div>Yes, tests should go into the Vulkan CTS whenever possible.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div text="#000000" bgcolor="#FFFFFF">
    Also since the scope of the work grew quite a lot and I'll be soon
    on vacation the implementation won't be ready until at least second
    week of October (just making sure no one will think I ran away
    scared =) )<br></div></blockquote><div><br></div><div>That's ok, I understand.</div><div><br></div><div>--Jason<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div text="#000000" bgcolor="#FFFFFF">
    <blockquote type="cite">
      <div dir="ltr">
        <div class="gmail_quote">
          <div><br>
          </div>
          <div>--Jason<br>
          </div>
          <div> </div>
          <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
            <div text="#000000" bgcolor="#FFFFFF"><span class="m_8653083740311233362m_8153322649885267684blob-code-inner m_8653083740311233362m_8153322649885267684blob-code-marker-addition"><span class="m_8653083740311233362m_8153322649885267684pl-s"> You can find
                  current implementation in <a href="https://gitlab.freedesktop.org/GL/mesa/commit/9d1c7ae0db618c6f7281d5f667c96612ff0bb2c2" target="_blank">https://gitlab.freedesktop.org/GL/mesa/commit/9d1c7ae0db618c6f7281d5f667c96612ff0bb2c2</a><br>
                </span></span><br>
              - Danil<br>
              <br>
              <div class="m_8653083740311233362m_8153322649885267684moz-cite-prefix">On
                9/12/18 6:30 PM, Danylo Piliaiev wrote:<br>
              </div>
              <blockquote type="cite"> Hi, <br>
                <br>
                Thank you for the directions!<br>
                <br>
                <div class="m_8653083740311233362m_8153322649885267684moz-cite-prefix">On
                  9/12/18 6:13 PM, Jason Ekstrand wrote:<br>
                </div>
                <blockquote type="cite">
                  <div dir="ltr">
                    <div>Danylo,</div>
                    <div><br>
                    </div>
                    <div>You're free to implement anything not already
                      implemented.  Here are some other (probably
                      simpler) extensions that I think can be reasonably
                      implemented on Intel HW:</div>
                  </div>
                </blockquote>
                <blockquote type="cite">
                  <div dir="ltr">
                    <div><br>
                    </div>
                    <div> - VK_EXT_conservative_rasterization</div>
                    <div> - VK_EXT_conditional_render</div>
                  </div>
                </blockquote>
                Didn't see them, will take closer look later.<br>
                <blockquote type="cite">
                  <div dir="ltr">
                    <div><br>
                    </div>
                    <div>As far as VK_KHR_draw_indirect_count go, I
                      haven't implemented it yet because the "proper"
                      implementation is actually kind-of painful though
                      not impossible.  In general, there are two ways it
                      can be done:</div>
                    <div><br>
                    </div>
                    <div>## 1. The cheap and easy way</div>
                    <div><br>
                    </div>
                    <div>The spec explicitly allows for the cheap and
                      easy way by requiring the caller to pass in a
                      maxDrawCount.  The idea here would be to emit
                      maxDrawCount draw calls only have each one of them
                      predicated on draw_id <
                      draw_count_from_buffer.  This one probably
                      wouldn't take much to wire up but it does mean
                      doing maxDrawCount 3DPRIMITIVE commands no matter
                      how many of them are actually needed.</div>
                  </div>
                </blockquote>
                I saw such implementation for i965, looked
                straightforward and I thought it will easily translate
                into Vulkan implementation. Didn't know that it's
                possible to do it other way on Intel.<br>
                <blockquote type="cite">
                  <div dir="ltr">
                    <div><br>
                    </div>
                    <div>## 2. The hard but maybe more correct way</div>
                    <div><br>
                    </div>
                    <div>The Intel command streamer does have the
                      ability, if used carefully, to loop.  The
                      difficulty here isn't in looping; that can be done
                      fairly easily on gen8+ by emitting a predicated
                      MI_BATCH_BUFFER_START that's predicated off of the
                      looping condition which jumps to the top of the
                      loop.  The real difficult bit is taking your loop
                      counter and using it to indirectly access the
                      array of draw information.  In order to do this,
                      you have to have a self-modifying batch buffer. 
                      In short, you would emit MI commands which read
                      the draw information into registers and also emit
                      MI commands (which would probably come before the
                      first set) which write the actual address into the
                      location in the batch where the first set of MI
                      commands has their address to read from.  This
                      would be a painful to debug mess of GPU hangs but
                      could actually be kind-of fun to implement.</div>
                  </div>
                </blockquote>
                The correct way looks interesting, I'll need some time
                to understand details.<br>
                <blockquote type="cite">
                  <div dir="ltr">
                    <div><br>
                    </div>
                    <div>I hope I haven't scarred you away from working
                      on anv; I just wanted to make it clear what you're
                      getting yourself into.  Both ways are totally
                      implementable and I think you'd pretty much have
                      to do the first method on gen7 if we really care
                      about supporting it there.  The second is totally
                      doable, it'll just involve some headaches when
                      it's broken.  If you want to continue with this
                      project after reading my scarry e-mail, I
                      recommend starting with method 1 to get your feet
                      wet and then we can look into method 2 once you
                      have that working.</div>
                  </div>
                </blockquote>
                I'll follow your recommendation and will start from the
                first method.<br>
                <br>
                - Danil<br>
                <blockquote type="cite">
                  <div dir="ltr">
                    <div><br>
                    </div>
                    <div>--Jason<br>
                    </div>
                  </div>
                  <br>
                  <div class="gmail_quote">
                    <div dir="ltr">On Wed, Sep 12, 2018 at 6:36 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">Hello
                      everyone,<br>
                      <br>
                      I would like to try to implement one of the Vulkan
                      extensions - <br>
                      VK_KHR_draw_indirect_count for anv,<br>
                      unless someone is already working on it.<br>
                      <br>
                      It's a relatively minor extension and I saw that
                      the same functionality <br>
                      is already implemented<br>
                      for ARB_indirect_parameters in i965.<br>
                      <br>
                      Also I would appreciate any tips if there are any
                      known possible tricky <br>
                      parts.<br>
                      <br>
                      - Danil<br>
                      _______________________________________________<br>
                      mesa-dev mailing list<br>
                      <a href="mailto:mesa-dev@lists.freedesktop.org" target="_blank">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>
                    </blockquote>
                  </div>
                </blockquote>
                <br>
              </blockquote>
              <br>
            </div>
          </blockquote>
        </div>
      </div>
    </blockquote>
    <br>
  </div>

</blockquote></div></div>