* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
*/
#include "util/u_double_list.h"
#include "nouveau_screen.h"
+#include "nouveau_winsys.h"
#include "nouveau_fence.h"
-#include "nouveau/nouveau_pushbuf.h"
-
#ifdef PIPE_OS_UNIX
#include <sched.h>
#endif
{
struct nouveau_screen *screen = fence->screen;
- fence->sequence = ++screen->fence.sequence;
-
assert(fence->state == NOUVEAU_FENCE_STATE_AVAILABLE);
/* set this now, so that if fence.emit triggers a flush we don't recurse */
- fence->state = NOUVEAU_FENCE_STATE_EMITTED;
+ fence->state = NOUVEAU_FENCE_STATE_EMITTING;
++fence->ref;
screen->fence.tail = fence;
- screen->fence.emit(&screen->base, fence->sequence);
+ screen->fence.emit(&screen->base, &fence->sequence);
+
+ assert(fence->state == NOUVEAU_FENCE_STATE_EMITTING);
+ fence->state = NOUVEAU_FENCE_STATE_EMITTED;
}
void
if (flushed) {
for (fence = next; fence; fence = fence->next)
- fence->state = NOUVEAU_FENCE_STATE_FLUSHED;
+ if (fence->state == NOUVEAU_FENCE_STATE_EMITTED)
+ fence->state = NOUVEAU_FENCE_STATE_FLUSHED;
}
}
struct nouveau_screen *screen = fence->screen;
uint32_t spins = 0;
- if (fence->state < NOUVEAU_FENCE_STATE_EMITTED) {
+ /* wtf, someone is waiting on a fence in flush_notify handler? */
+ assert(fence->state != NOUVEAU_FENCE_STATE_EMITTING);
+
+ if (fence->state < NOUVEAU_FENCE_STATE_EMITTED)
nouveau_fence_emit(fence);
- if (fence == screen->fence.current)
- nouveau_fence_new(screen, &screen->fence.current, FALSE);
- }
if (fence->state < NOUVEAU_FENCE_STATE_FLUSHED)
- FIRE_RING(screen->channel);
+ if (nouveau_pushbuf_kick(screen->pushbuf, screen->pushbuf->channel))
+ return FALSE;
+
+ if (fence == screen->fence.current)
+ nouveau_fence_next(screen);
do {
nouveau_fence_update(screen, FALSE);
if (fence->state == NOUVEAU_FENCE_STATE_SIGNALLED)
return TRUE;
+ if (!spins)
+ NOUVEAU_DRV_STAT(screen, any_non_kernel_fence_sync_count, 1);
spins++;
#ifdef PIPE_OS_UNIX
if (!(spins % 8)) /* donate a few cycles */
void
nouveau_fence_next(struct nouveau_screen *screen)
{
- if (screen->fence.current->state < NOUVEAU_FENCE_STATE_EMITTED)
+ if (screen->fence.current->state < NOUVEAU_FENCE_STATE_EMITTING)
nouveau_fence_emit(screen->fence.current);
nouveau_fence_ref(NULL, &screen->fence.current);