1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright © 2008 Intel Corporation 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"), 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software is furnished to do so, subject to the following conditions: 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the next 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * paragraph) shall be included in all copies or substantial portions of the 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software. 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN THE SOFTWARE. 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Authors: 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Eric Anholt <eric@anholt.net> 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** @file intel_syncobj.c 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Support for ARB_sync 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ARB_sync is implemented by flushing the current batchbuffer and keeping a 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * reference on it. We can then check for completion or wait for completion 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * using the normal buffer object mechanisms. This does mean that if an 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * application is using many sync objects, it will emit small batchbuffers 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * which may end up being a significant overhead. In other tests of removing 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * gratuitous batchbuffer syncs in Mesa, it hasn't appeared to be a significant 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * performance bottleneck, though. 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/simple_list.h" 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/imports.h" 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "intel_context.h" 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "intel_batchbuffer.h" 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "intel_reg.h" 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct gl_sync_object * 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgintel_new_sync_object(struct gl_context *ctx, GLuint id) 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct intel_sync_object *sync; 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sync = calloc(1, sizeof(struct intel_sync_object)); 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return &sync->Base; 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgintel_delete_sync_object(struct gl_context *ctx, struct gl_sync_object *s) 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct intel_sync_object *sync = (struct intel_sync_object *)s; 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org drm_intel_bo_unreference(sync->bo); 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(sync); 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgintel_fence_sync(struct gl_context *ctx, struct gl_sync_object *s, 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLenum condition, GLbitfield flags) 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct intel_context *intel = intel_context(ctx); 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct intel_sync_object *sync = (struct intel_sync_object *)s; 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(condition == GL_SYNC_GPU_COMMANDS_COMPLETE); 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org intel_batchbuffer_emit_mi_flush(intel); 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sync->bo = intel->batch.bo; 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org drm_intel_bo_reference(sync->bo); 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org intel_flush(ctx); 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* We ignore the user-supplied timeout. This is weaselly -- we're allowed to 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * round to an implementation-dependent accuracy, and right now our 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * implementation "rounds" to the wait-forever value. 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The fix would be a new kernel function to do the GTT transition with a 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * timeout. 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void intel_client_wait_sync(struct gl_context *ctx, struct gl_sync_object *s, 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLbitfield flags, GLuint64 timeout) 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct intel_sync_object *sync = (struct intel_sync_object *)s; 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (sync->bo) { 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org drm_intel_bo_wait_rendering(sync->bo); 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s->StatusFlag = 1; 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org drm_intel_bo_unreference(sync->bo); 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sync->bo = NULL; 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* We have nothing to do for WaitSync. Our GL command stream is sequential, 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * so given that the sync object has already flushed the batchbuffer, 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * any batchbuffers coming after this waitsync will naturally not occur until 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the previous one is done. 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void intel_server_wait_sync(struct gl_context *ctx, struct gl_sync_object *s, 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLbitfield flags, GLuint64 timeout) 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void intel_check_sync(struct gl_context *ctx, struct gl_sync_object *s) 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct intel_sync_object *sync = (struct intel_sync_object *)s; 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (sync->bo && !drm_intel_bo_busy(sync->bo)) { 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org drm_intel_bo_unreference(sync->bo); 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sync->bo = NULL; 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s->StatusFlag = 1; 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid intel_init_syncobj_functions(struct dd_function_table *functions) 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org functions->NewSyncObject = intel_new_sync_object; 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org functions->DeleteSyncObject = intel_delete_sync_object; 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org functions->FenceSync = intel_fence_sync; 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org functions->CheckSync = intel_check_sync; 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org functions->ClientWaitSync = intel_client_wait_sync; 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org functions->ServerWaitSync = intel_server_wait_sync; 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 133