<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <br>
    <br>
    <div class="moz-cite-prefix">On 9/17/18 7:03 PM, Jason Ekstrand
      wrote:<br>
    </div>
    <blockquote type="cite"
cite="mid:CAOFGe944A_p13-2Lh5i=hdThCp-Yxy3mNvWG4Zy=nxjdFBDdbA@mail.gmail.com">
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <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"
              moz-do-not-send="true">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" moz-do-not-send="true">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>
        </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">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>
    <br>
    <br>
    <blockquote type="cite"
cite="mid:CAOFGe944A_p13-2Lh5i=hdThCp-Yxy3mNvWG4Zy=nxjdFBDdbA@mail.gmail.com">
      <div dir="ltr">
        <div class="gmail_quote">
          <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" moz-do-not-send="true">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" moz-do-not-send="true">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" moz-do-not-send="true">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" moz-do-not-send="true">mesa-dev@lists.freedesktop.org</a><br>
                                <a
                                  href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev"
                                  rel="noreferrer" target="_blank"
                                  moz-do-not-send="true">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>
    </blockquote>
    <br>
  </body>
</html>