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); }
public abstract void CmdBeginConditionalRendering([Count(Count = 0)] CommandBuffer commandBuffer, [Count(Count = 0), Flow(FlowDirection.In)] ref ConditionalRenderingBeginInfoEXT pConditionalRenderingBegin);