[Mesa-dev] Implementation of VK_KHR_draw_indirect_count extension for anv
Danylo Piliaiev
danylo.piliaiev at gmail.com
Mon Sep 17 13:34:25 UTC 2018
Hi Jason,
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
and got confused:
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
will result in FALSE, we call vkCmdDrawIndirectCountKHR which sees that
there is already a predicate emitted and it should be taken into
account, since it will be FALSE
all next predicates should result in FALSE. The issue is that I don't
see an easy way to do this.
My current implementation uses the next predicate (it is same as in GL
implementation):
/* While draw_index < maxDrawCount the predicate's result will be
* (draw_index == maxDrawCount) ^ TRUE = TRUE
* When draw_index == maxDrawCount the result is
* (TRUE) ^ TRUE = FALSE
* After this all results will be:
* (FALSE) ^ FALSE = FALSE
*/
anv_batch_emit(&cmd_buffer->batch, GENX(MI_PREDICATE), mip) {
mip.LoadOperation = LOAD_LOAD;
mip.CombineOperation = COMBINE_XOR;
mip.CompareOperation = COMPARE_SRCS_EQUAL;
}
But if the initial predicate state is FALSE then when draw_index equals
maxDrawCount the result will be
(FALSE) ^ TRUE = TRUE
Which isn't something we want. But without "not equal" operation or
without MI_MATH I don't see how to fix this.
I don't see anything related in Vulkan or GL specs neither I see
anything in Piglit and CTS tests.
Maybe I'm missing something obvious, could you help me here?
You can find current implementation in
https://gitlab.freedesktop.org/GL/mesa/commit/9d1c7ae0db618c6f7281d5f667c96612ff0bb2c2
- Danil
On 9/12/18 6:30 PM, Danylo Piliaiev wrote:
> Hi,
>
> Thank you for the directions!
>
> On 9/12/18 6:13 PM, Jason Ekstrand wrote:
>> Danylo,
>>
>> 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:
>>
>> - VK_EXT_conservative_rasterization
>> - VK_EXT_conditional_render
> Didn't see them, will take closer look later.
>>
>> 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:
>>
>> ## 1. The cheap and easy way
>>
>> 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.
> 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.
>>
>> ## 2. The hard but maybe more correct way
>>
>> 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.
> The correct way looks interesting, I'll need some time to understand
> details.
>>
>> 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.
> I'll follow your recommendation and will start from the first method.
>
> - Danil
>>
>> --Jason
>>
>> On Wed, Sep 12, 2018 at 6:36 AM Danylo Piliaiev
>> <danylo.piliaiev at gmail.com <mailto:danylo.piliaiev at gmail.com>> wrote:
>>
>> Hello everyone,
>>
>> I would like to try to implement one of the Vulkan extensions -
>> VK_KHR_draw_indirect_count for anv,
>> unless someone is already working on it.
>>
>> It's a relatively minor extension and I saw that the same
>> functionality
>> is already implemented
>> for ARB_indirect_parameters in i965.
>>
>> Also I would appreciate any tips if there are any known possible
>> tricky
>> parts.
>>
>> - Danil
>> _______________________________________________
>> mesa-dev mailing list
>> mesa-dev at lists.freedesktop.org
>> <mailto:mesa-dev at lists.freedesktop.org>
>> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20180917/b2a5990b/attachment-0001.html>
More information about the mesa-dev
mailing list