On 9/18/18 1:08 PM, Jason Ekstrand wrote:
On Tue, Sep 18, 2018 at 4:08 AM Danylo Piliaiev
<[email protected] <mailto:[email protected]>> wrote:
On 9/17/18 7:03 PM, Jason Ekstrand wrote:
On Mon, Sep 17, 2018 at 10:08 AM Danylo Piliaiev
<[email protected] <mailto:[email protected]>> wrote:
On 9/17/18 5:34 PM, Jason Ekstrand wrote:
On Mon, Sep 17, 2018 at 8:34 AM Danylo Piliaiev
<[email protected]
<mailto:[email protected]>> wrote:
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.
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.
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?
Looks like a plan. I'll try to go this path.
Also there is another interaction which wasn't thought of before:
Several vkCmdDrawIndirectCountKHR in conditional render block
but using MI_MATH should solve it.
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.
About the secondary command buffers:
If inherited conditional rendering
<https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#features-features-inheritedConditionalRendering>
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?
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.
And this secondary buffer may have been formed inside conditional
render block so they could be affected by two conditions if I
understand correctly.
Is is doable to implement?
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.
For primary buffers I'm already doing it this way.
So if we want to support inherited conditional rendering all relevant
commands in command buffers should be constructed with dependency on
predicate. Just to be sure: is the dependency on predicate cheap?
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.
Thanks for suggestion!
--Jason
_______________________________________________
mesa-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-dev