Esempio n. 1
0
void GFXGLAppleFence::block()
{
   if(!mIssued)
      return;
      
   glFinishFenceAPPLE(mHandle);
}
Esempio n. 2
0
enum wined3d_event_query_result wined3d_event_query_finish(const struct wined3d_event_query *query,
        const struct wined3d_device *device)
{
    struct wined3d_context *context;
    const struct wined3d_gl_info *gl_info;
    enum wined3d_event_query_result ret;

    TRACE("(%p)\n", query);

    if (!query->context)
    {
        TRACE("Query not started\n");
        return WINED3D_EVENT_QUERY_NOT_STARTED;
    }
    gl_info = query->context->gl_info;

    if (query->context->tid != GetCurrentThreadId() && !gl_info->supported[ARB_SYNC])
    {
        /* A glFinish does not reliably wait for draws in other contexts. The caller has
         * to find its own way to cope with the thread switch
         */
        WARN("Event query finished from wrong thread\n");
        return WINED3D_EVENT_QUERY_WRONG_THREAD;
    }

    context = context_acquire(device, query->context->current_rt);

    if (gl_info->supported[ARB_SYNC])
    {
        /* Apple seems to be into arbitrary limits, and timeouts larger than
         * 0xfffffffffffffbff immediately return GL_TIMEOUT_EXPIRED. We don't
         * really care and can live with waiting a few μs less. (OS X 10.7.4). */
        GLenum gl_ret = GL_EXTCALL(glClientWaitSync(query->object.sync, GL_SYNC_FLUSH_COMMANDS_BIT, ~(GLuint64)0xffff));
        checkGLcall("glClientWaitSync");

        switch (gl_ret)
        {
            case GL_ALREADY_SIGNALED:
            case GL_CONDITION_SATISFIED:
                ret = WINED3D_EVENT_QUERY_OK;
                break;

                /* We don't expect a timeout for a ~584 year wait */
            default:
                ERR("glClientWaitSync returned %#x.\n", gl_ret);
                ret = WINED3D_EVENT_QUERY_ERROR;
        }
    }
    else if (context->gl_info->supported[APPLE_FENCE])
    {
        GL_EXTCALL(glFinishFenceAPPLE(query->object.id));
        checkGLcall("glFinishFenceAPPLE");
        ret = WINED3D_EVENT_QUERY_OK;
    }
    else if (context->gl_info->supported[NV_FENCE])
    {
        GL_EXTCALL(glFinishFenceNV(query->object.id));
        checkGLcall("glFinishFenceNV");
        ret = WINED3D_EVENT_QUERY_OK;
    }
    else
    {
        ERR("Event query created without GL support\n");
        ret = WINED3D_EVENT_QUERY_ERROR;
    }

    context_release(context);
    return ret;
}
Esempio n. 3
0
File: query.c Progetto: r6144/wine
enum wined3d_event_query_result wined3d_event_query_finish(struct wined3d_event_query *query, IWineD3DDeviceImpl *device)
{
    struct wined3d_context *context;
    const struct wined3d_gl_info *gl_info;
    enum wined3d_event_query_result ret;

    TRACE("(%p)\n", query);

    if (!query->context)
    {
        TRACE("Query not started\n");
        return WINED3D_EVENT_QUERY_NOT_STARTED;
    }
    gl_info = query->context->gl_info;

    if (query->context->tid != GetCurrentThreadId() && !gl_info->supported[ARB_SYNC])
    {
        /* A glFinish does not reliably wait for draws in other contexts. The caller has
         * to find its own way to cope with the thread switch
         */
        WARN("Event query finished from wrong thread\n");
        return WINED3D_EVENT_QUERY_WRONG_THREAD;
    }

    context = context_acquire(device, query->context->current_rt);

    ENTER_GL();
    if (gl_info->supported[ARB_SYNC])
    {
        GLenum gl_ret = GL_EXTCALL(glClientWaitSync(query->object.sync, 0, ~(GLuint64)0));
        checkGLcall("glClientWaitSync");

        switch (gl_ret)
        {
            case GL_ALREADY_SIGNALED:
            case GL_CONDITION_SATISFIED:
                ret = WINED3D_EVENT_QUERY_OK;
                break;

                /* We don't expect a timeout for a ~584 year wait */
            default:
                ERR("glClientWaitSync returned %#x.\n", gl_ret);
                ret = WINED3D_EVENT_QUERY_ERROR;
        }
    }
    else if (context->gl_info->supported[APPLE_FENCE])
    {
        GL_EXTCALL(glFinishFenceAPPLE(query->object.id));
        checkGLcall("glFinishFenceAPPLE");
        ret = WINED3D_EVENT_QUERY_OK;
    }
    else if (context->gl_info->supported[NV_FENCE])
    {
        GL_EXTCALL(glFinishFenceNV(query->object.id));
        checkGLcall("glFinishFenceNV");
        ret = WINED3D_EVENT_QUERY_OK;
    }
    else
    {
        ERR("Event query created without GL support\n");
        ret = WINED3D_EVENT_QUERY_ERROR;
    }
    LEAVE_GL();

    context_release(context);
    return ret;
}
Esempio n. 4
0
void	CGLMQuery::Complete( uint *result )
{
	m_ctx->MakeCurrent();

	uint resultval = 0;
	GLint available = 0;
	bool bogus_available = false;
	
	// blocking call if not done
	Assert(m_started);
	Assert(m_stopped);

	switch(m_params.m_type)
	{
		case EOcclusion:
		{
			if (m_nullQuery)
			{
				m_done = true;
				resultval = 0;		// we did say "null queries..."
			}
			else
			{
				// accept that the query is going to drain pipe in 10.6.4 and prior.
				// check the error on the spot.
				glGetQueryObjectivARB(m_name, GL_QUERY_RESULT_AVAILABLE_ARB, &available );
				GLenum errorcode = GetQueryError();
				
				if (errorcode)
				{
					const char	*decodedStr = GLMDecode( eGL_ERROR, errorcode );
					printf( "\nCGLMQuery::Complete saw %s error (%d) from glGetQueryObjectivARB GL_QUERY_RESULT_AVAILABLE_ARB name=%d", decodedStr, errorcode, m_name  );

					resultval=0;
				}
				else
				{
					if (!available)
					{
						// this does happen with some very modest frequency.
						if (!m_ctx->Caps().m_hasPerfPackage1)
						{
							glFlush();		// ISTR some deadlock cases on pre-SLGU drivers if you didn't do this to kick the queue along..
						}
					}
					
					glGetQueryObjectuivARB( m_name, GL_QUERY_RESULT_ARB, &resultval);
					
					errorcode = GetQueryError();
					if (errorcode)
					{
						const char	*decodedStr = GLMDecode( eGL_ERROR, errorcode );
						printf( "\nCGLMQuery::Complete saw %s error (%d) from glGetQueryObjectivARB GL_QUERY_RESULT_ARB name=%d", decodedStr, errorcode, m_name  );
						
						resultval=0;
					}
					else
					{
						// resultval is legit
					}
				}
				m_done = true;
			}
		}
		break;

		case EFence:
		{
			if(!m_done)
			{
				glFinishFenceAPPLE( m_name );

				GLenum errorcode = GetQueryError();
				if (errorcode)
				{
					const char	*decodedStr = GLMDecode( eGL_ERROR, errorcode );
					printf( "\nCGLMQuery::Complete saw %s error (%d) from glFinishFenceAPPLE (EFence) name=%d", decodedStr, errorcode, m_name  );
				}
				
				m_done = true;					// for clarity or if they try to Complete twice
			}
		}
		break;
	}

	Assert( m_done );
	
	// reset state for re-use - i.e. you have to call Complete if you want to re-use the object
	m_started = m_stopped = m_done = false;
	
	if (result)	// caller may pass NULL if not interested in result, for example to clear a fence
	{
		*result = resultval;
	}
}
Esempio n. 5
0
bool	CGLMQuery::IsDone( void )
{
	m_ctx->MakeCurrent();

	Assert(m_started);
	Assert(m_stopped);

	if(!m_done)		// you can ask more than once, but we only check until it comes back as done.
	{
		// on occlusion: glGetQueryObjectivARB - large cost on pre SLGU, cheap after
		// on fence: glTestFenceAPPLE on the fence
		switch(m_params.m_type)
		{
			case EOcclusion:	// just test the fence that was set after the query begin
			{
				if (m_nullQuery)
				{
					// do almost nothing.. but claim work is complete
					m_done = true;
				}
				else
				{
					// prepare to pay a big price on drivers prior to 10.6.4+SLGU
					
					GLint available = 0;
					glGetQueryObjectivARB(m_name, GL_QUERY_RESULT_AVAILABLE_ARB, &available );
					
					GLenum errorcode = GetQueryError();
					if (errorcode)
					{
						const char	*decodedStr = GLMDecode( eGL_ERROR, errorcode );
						printf( "\nCGLMQuery::IsDone saw %s error (%d) from glGetQueryObjectivARB(a2) name=%d", decodedStr, errorcode, m_name  );
					}

					m_done = (available != 0);					
				}
			}
			break;

			case EFence:
			{
				m_done = glTestFenceAPPLE( m_name );
				GLenum errorcode = GetQueryError();
				if (errorcode)
				{
					const char	*decodedStr = GLMDecode( eGL_ERROR, errorcode );
					printf( "\nCGLMQuery::IsDone saw %s error (%d) from glTestFenceAPPLE(b) name=%d", decodedStr, errorcode, m_name  );
				}

				if (m_done)
				{
					glFinishFenceAPPLE( m_name );	// no set fence goes un-finished

					errorcode = GetQueryError();
					if (errorcode)
					{
						const char	*decodedStr = GLMDecode( eGL_ERROR, errorcode );
						printf( "\nCGLMQuery::IsDone saw %s error (%d) from glFinishFenceAPPLE(b) name=%d", decodedStr, errorcode, m_name  );
					}
				}
			}
			break;
		}
	}
	
	return m_done;
}