Example #1
0
        public bool ReserveForHostAccess()
        {
            if (Base != null)
            {
                return(Base.ReserveForHostAccess());
            }
            else
            {
                bool result = true;

                // A very light lock, as this case is uncommon.
                ThreadedHelpers.SpinUntilExchange(ref _createLock, 1, 0);

                if (Base != null)
                {
                    result = Base.ReserveForHostAccess();
                }
                else
                {
                    _reserved = true;
                }

                Volatile.Write(ref _createLock, 0);

                return(result);
            }
        }
Example #2
0
        public bool TryHostConditionalRendering(ICounterEvent value, ulong compare, bool isEqual)
        {
            // Compare an event and a constant value.
            if (value is CounterQueueEvent evt)
            {
                // Easy host conditional rendering when the check matches what GL can do:
                //  - Event is of type samples passed.
                //  - Result is not a combination of multiple queries.
                //  - Comparing against 0.
                //  - Event has not already been flushed.

                if (compare == 0 && evt.Type == CounterType.SamplesPassed && evt.ClearCounter)
                {
                    if (!value.ReserveForHostAccess())
                    {
                        // If the event has been flushed, then just use the values on the CPU.
                        // The query object may already be repurposed for another draw (eg. begin + end).
                        return(false);
                    }

                    if (Gd.Capabilities.SupportsConditionalRendering)
                    {
                        var buffer = evt.GetBuffer().Get(Cbs, 0, sizeof(long)).Value;
                        var flags  = isEqual ? ConditionalRenderingFlagsEXT.ConditionalRenderingInvertedBitExt : 0;

                        var conditionalRenderingBeginInfo = new ConditionalRenderingBeginInfoEXT()
                        {
                            SType  = StructureType.ConditionalRenderingBeginInfoExt,
                            Buffer = buffer,
                            Flags  = flags
                        };

                        // Gd.ConditionalRenderingApi.CmdBeginConditionalRendering(CommandBuffer, conditionalRenderingBeginInfo);
                    }

                    _activeConditionalRender = evt;
                    return(true);
                }
            }

            // The GPU will flush the queries to CPU and evaluate the condition there instead.

            FlushPendingQuery(); // The thread will be stalled manually flushing the counter, so flush commands now.
            return(false);
        }