Exemple #1
0
enum wined3d_event_query_result wined3d_event_query_test(struct wined3d_event_query *query, IWineD3DDeviceImpl *device)
{
    struct wined3d_context *context;
    const struct wined3d_gl_info *gl_info;
    enum wined3d_event_query_result ret;
    BOOL fence_result;

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

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

    if (!query->context->gl_info->supported[ARB_SYNC] && query->context->tid != GetCurrentThreadId())
    {
#ifdef VBOX_WINE_WITH_SINGLE_CONTEXT
        ERR("Event query tested from wrong thread\n");
#else
        WARN("Event query tested from wrong thread\n");
#endif
        return WINED3D_EVENT_QUERY_WRONG_THREAD;
    }

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

    ENTER_GL();

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

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

            case GL_TIMEOUT_EXPIRED:
                ret = WINED3D_EVENT_QUERY_WAITING;
                break;

            case GL_WAIT_FAILED:
            default:
                ERR("glClientWaitSync returned %#x.\n", gl_ret);
                ret = WINED3D_EVENT_QUERY_ERROR;
        }
    }
    else if (gl_info->supported[APPLE_FENCE])
    {
        fence_result = GL_EXTCALL(glTestFenceAPPLE(query->object.id));
        checkGLcall("glTestFenceAPPLE");
        if (fence_result) ret = WINED3D_EVENT_QUERY_OK;
        else ret = WINED3D_EVENT_QUERY_WAITING;
    }
    else if (gl_info->supported[NV_FENCE])
    {
        fence_result = GL_EXTCALL(glTestFenceNV(query->object.id));
        checkGLcall("glTestFenceNV");
        if (fence_result) ret = WINED3D_EVENT_QUERY_OK;
        else ret = WINED3D_EVENT_QUERY_WAITING;
    }
    else
    {
        ERR("Event query created despite lack of GL support\n");
        ret = WINED3D_EVENT_QUERY_ERROR;
    }

    LEAVE_GL();

    context_release(context);
    return ret;
}
Exemple #2
0
enum piglit_result
piglit_display(void)
{
	float white[4] = {1.0, 1.0, 1.0, 1.0};
	GLboolean pass = GL_TRUE;
	int i;

#ifdef PIGLIT_USE_OPENGL
	float array[] = {
		17, 13, 0,
		17, 18, 0,
		12, 13, 0,
		12, 18, 0,
		27, 13, 0,
		27, 18, 0,
		22, 13, 0,
		22, 18, 0,
		37, 13, 0,
		37, 18, 0,
		32, 13, 0,
		32, 18, 0,
		47, 13, 0,
		47, 18, 0,
		42, 13, 0,
		42, 18, 0
	};
#else // PIGLIT_USE_OPENGL_ES3
	float array[] = {
		1.00, 0.75, 0.0,
		1.00, 1.00, 0.0,
		0.75, 0.75, 0.0,
		0.75, 1.00, 0.0,

		0.50, 0.75, 0.0,
		0.50, 1.00, 0.0,
		0.25, 0.75, 0.0,
		0.25, 1.00, 0.0,

		0.00, 0.75, 0.0,
		0.00, 1.00, 0.0,
		-0.25, 0.75, 0.0,
		-0.25, 1.00, 0.0,

		-0.50, 0.75, 0.0,
		-0.50, 1.00, 0.0,
		-0.75, 0.75, 0.0,
		-0.75, 1.00, 0.0,
       };
#endif
	glClear(GL_COLOR_BUFFER_BIT);

	if (test == DRAW) {
#ifdef PIGLIT_USE_OPENGL
		glEnableClientState(GL_VERTEX_ARRAY);
		glBindBuffer(GL_ARRAY_BUFFER, buffer);
		glVertexPointer(3, GL_FLOAT, 0, 0);
		glBindBuffer(GL_ARRAY_BUFFER, 0);
#else // PIGLIT_USE_OPENGL_ES3
		glBindVertexArray(vao);
#endif

		memcpy(map, array, 12 * sizeof(float));
		if (!coherent)
			glMemoryBarrier(GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT);

		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

		memcpy(map+12, array+12, 12 * sizeof(float));
		if (!coherent)
			glMemoryBarrier(GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT);

		glDrawArrays(GL_TRIANGLE_STRIP, 4, 4);

		memcpy(map+12*2, array+12*2, 12 * sizeof(float));
		if (!coherent)
			glMemoryBarrier(GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT);

		glDrawArrays(GL_TRIANGLE_STRIP, 8, 4);

		memcpy(map+12*3, array+12*3, 12 * sizeof(float));
		if (!coherent)
			glMemoryBarrier(GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT);

		glDrawArrays(GL_TRIANGLE_STRIP, 12, 4);

		piglit_check_gl_error(0);

#ifdef PIGLIT_USE_OPENGL
		pass = pass && piglit_probe_pixel_rgb(15, 15, white);
		pass = pass && piglit_probe_pixel_rgb(25, 15, white);
		pass = pass && piglit_probe_pixel_rgb(35, 15, white);
		pass = pass && piglit_probe_pixel_rgb(45, 15, white);

		glDisableClientState(GL_VERTEX_ARRAY);
#else // PIGLIT_USE_OPENGL_ES3
		pass = pass && piglit_probe_pixel_rgba(13, 87, white);
		pass = pass && piglit_probe_pixel_rgba(39, 87, white);
		pass = pass && piglit_probe_pixel_rgba(65, 87, white);
		pass = pass && piglit_probe_pixel_rgba(91, 87, white);
#endif
	}
	else if (test == READ) {
		GLuint srcbuf;
		GLsync fence;

		glGenBuffers(1, &srcbuf);
		glBindBuffer(GL_COPY_READ_BUFFER, srcbuf);
		glBufferData(GL_COPY_READ_BUFFER, BUF_SIZE, array, GL_STATIC_DRAW);

		/* Copy some data to the mapped buffer and check if the CPU can see it. */
		glBindBuffer(GL_COPY_WRITE_BUFFER, buffer);
		glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER,
				    0, 0, BUF_SIZE);

		glBindBuffer(GL_COPY_READ_BUFFER, 0);
		glBindBuffer(GL_COPY_WRITE_BUFFER, 0);
		glDeleteBuffers(1, &srcbuf);

		if (!coherent)
			glMemoryBarrier(GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT);

		fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
		glClientWaitSync(fence, GL_SYNC_FLUSH_COMMANDS_BIT, GL_TIMEOUT_IGNORED);

		for (i = 0; i < ARRAY_SIZE(array); i++) {
			if (map[i] != array[i]) {
				printf("Probe [%i] failed. Expected: %f  Observed: %f\n",
				       i, array[i], map[i]);
				pass = GL_FALSE;
			}
		}
	}
	else {
		assert(0);
	}

	piglit_present_results();

	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
}
Exemple #3
0
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
         */
#ifdef VBOX_WINE_WITH_SINGLE_CONTEXT
        ERR("Event query finished from wrong thread\n");
#else
        WARN("Event query finished from wrong thread\n");
#endif
        return WINED3D_EVENT_QUERY_WRONG_THREAD;
    }

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

    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;
}
Exemple #4
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;
}
Exemple #5
0
/** Update shadowSplit values and make Cascade Bounding Box pointer valid.
* The function aunches two compute kernel that generates an histogram of the depth buffer value (between 0 and 250 with increment of 0.25)
* and get an axis aligned bounding box (from SunCamMatrix view) containing all depth buffer value.
* It also retrieves the result from the previous computations (in a Round Robin fashion) and update CBB pointer.
* \param width of the depth buffer
* \param height of the depth buffer
* TODO : The depth histogram part is commented out, needs to tweak it when I have some motivation
*/
void IrrDriver::UpdateSplitAndLightcoordRangeFromComputeShaders(size_t width, size_t height)
{
    // Value that should be kept between multiple calls
    static GLuint ssbo[2];
    static Histogram *Hist[2];
    static GLsync LightcoordBBFence = 0;
    static size_t currentHist = 0;
    static GLuint ssboSplit[2];
    static float tmpshadowSplit[5] = { 1., 5., 20., 50., 150. };

    if (!LightcoordBBFence)
    {
        glGenBuffers(2, ssbo);
        glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo[0]);
        glBufferStorage(GL_SHADER_STORAGE_BUFFER, 4 * sizeof(CascadeBoundingBox), 0, GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
        CBB[0] = (CascadeBoundingBox *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 4 * sizeof(CascadeBoundingBox), GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
        glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo[1]);
        glBufferStorage(GL_SHADER_STORAGE_BUFFER, 4 * sizeof(CascadeBoundingBox), 0, GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
        CBB[1] = (CascadeBoundingBox *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 4 * sizeof(CascadeBoundingBox), GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);

/*        glGenBuffers(2, ssboSplit);
        glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssboSplit[0]);
        glBufferStorage(GL_SHADER_STORAGE_BUFFER, sizeof(Histogram), 0, GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
        Hist[0] = (Histogram *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(Histogram), GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
        glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssboSplit[1]);
        glBufferStorage(GL_SHADER_STORAGE_BUFFER, sizeof(Histogram), 0, GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
        Hist[1] = (Histogram *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(Histogram), GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);*/
    }

    // Use bounding boxes from last frame
    if (LightcoordBBFence)
    {
        while (glClientWaitSync(LightcoordBBFence, GL_SYNC_FLUSH_COMMANDS_BIT, 0) != GL_ALREADY_SIGNALED);
        glDeleteSync(LightcoordBBFence);
    }

/*    {
        memcpy(shadowSplit, tmpshadowSplit, 5 * sizeof(float));
        unsigned numpix = Hist[currentHist]->count;
        unsigned split = 0;
        unsigned i;
        for (i = 0; i < 1022; i++)
        {
            split += Hist[currentHist]->bin[i];
            if (split > numpix / 2)
                break;
        }
        tmpshadowSplit[1] = (float)++i / 4.;

        for (; i < 1023; i++)
        {
            split += Hist[currentHist]->bin[i];
            if (split > 3 * numpix / 4)
                break;
        }
        tmpshadowSplit[2] = (float)++i / 4.;

        for (; i < 1024; i++)
        {
            split += Hist[currentHist]->bin[i];
            if (split > 7 * numpix / 8)
                break;
        }
        tmpshadowSplit[3] = (float)++i / 4.;

        for (; i < 1024; i++)
        {
            split += Hist[currentHist]->bin[i];
        }

        tmpshadowSplit[0] = (float)(Hist[currentHist]->bin[1024] - 1) / 4.;
        tmpshadowSplit[4] = (float)(Hist[currentHist]->bin[1025] + 1) / 4.;
                printf("numpix is %d\n", numpix);
        printf("total : %d\n", split);
        printf("split 0 : %f\n", tmpshadowSplit[1]);
        printf("split 1 : %f\n", tmpshadowSplit[2]);
        printf("split 2 : %f\n", tmpshadowSplit[3]);
        printf("min %f max %f\n", tmpshadowSplit[0], tmpshadowSplit[4]);
        currentHist = (currentHist + 1) % 2;
    }*/

    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, ssbo[currentCBB]);
//    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, ssboSplit[currentHist]);
    for (unsigned i = 0; i < 4; i++)
    {
        CBB[currentCBB][i].xmin = CBB[currentCBB][i].ymin = CBB[currentCBB][i].zmin = 1000;
        CBB[currentCBB][i].xmax = CBB[currentCBB][i].ymax = CBB[currentCBB][i].zmax = -1000;
    }
//    memset(Hist[currentHist], 0, sizeof(Histogram));
//    Hist[currentHist]->mindepth = 3000;
    glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
    glUseProgram(FullScreenShader::LightspaceBoundingBoxShader::getInstance()->Program);
    FullScreenShader::LightspaceBoundingBoxShader::getInstance()->SetTextureUnits(getDepthStencilTexture());
    FullScreenShader::LightspaceBoundingBoxShader::getInstance()->setUniforms(m_suncam->getViewMatrix(), tmpshadowSplit[1], tmpshadowSplit[2], tmpshadowSplit[3], tmpshadowSplit[4]);
    glDispatchCompute((int)width / 64, (int)height / 64, 1);

/*    glUseProgram(FullScreenShader::DepthHistogramShader::getInstance()->Program);
    FullScreenShader::DepthHistogramShader::getInstance()->SetTextureUnits(getDepthStencilTexture());
    FullScreenShader::DepthHistogramShader::getInstance()->setUniforms();
    glDispatchCompute((int)width / 32, (int)height / 32, 1);*/

    glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
    LightcoordBBFence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);

    currentCBB = (currentCBB + 1) % 2;

}
void base::app::process_captured_screen()
{
	while(_rb_tail != _rb_head) {
		const int screen_size = 
			get_wnd_width() 
				* get_wnd_height() 
				* base::get_pfd(CAPTURE_PF)->_size;
		const int tmp_tail = (_rb_tail + 1) & RB_BUFFERS_MASK;
		screen_buffer *sc = _screen_buffers_rb + tmp_tail;

		GLenum res = glClientWaitSync(sc->_fence, 0, 0);
		if(res == GL_ALREADY_SIGNALED || res == GL_CONDITION_SATISFIED) { // AMD returns GL_CONDITION_SATISFIED only BUG?
			glDeleteSync(sc->_fence);

			_timer.start();

			if(base::cfg().use_pinned_memory) {
				// process data
				//memcpy(ptr_dst, sc->_pinned_ptr_aligned, screen_size);
				glBindBuffer(GL_PIXEL_UNPACK_BUFFER, sc->_buffer);
			}
			else {
				glBindBuffer(GL_COPY_READ_BUFFER, sc->_buffer);
				/*glBindBuffer(GL_PIXEL_UNPACK_BUFFER, sc->_showtime_buffer);
				char *ptr_dst = reinterpret_cast<char*>(
					glMapBufferRange(
						GL_PIXEL_UNPACK_BUFFER,
						0,
						screen_size,
						GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT));*/
				char *ptr_src = reinterpret_cast<char*>(
					glMapBufferRange(
						GL_COPY_READ_BUFFER,
						0,
						screen_size,
						GL_MAP_READ_BIT));

				//memcpy(ptr_dst, ptr_src, screen_size);

				glUnmapBuffer(GL_COPY_READ_BUFFER);
				//glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
			}

			glBindTexture(GL_TEXTURE_2D, _showtime_tex);
			glTexImage2D(
				GL_TEXTURE_2D,
				0,
				base::get_pfd(CAPTURE_PF)->_internal,
				get_wnd_width(),
				get_wnd_height(),
				0,
				base::get_pfd(CAPTURE_PF)->_format,
				base::get_pfd(CAPTURE_PF)->_type, 
				0);
			glBindTexture(GL_TEXTURE_2D, 0);

			glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);

			const double map_time = _timer.elapsed_time();

			__int64 result[3]={0,};
			glGetQueryObjecti64v(sc->_queries[2], GL_QUERY_RESULT, result + 2);
			glGetQueryObjecti64v(sc->_queries[1], GL_QUERY_RESULT, result + 1);
			glGetQueryObjecti64v(sc->_queries[0], GL_QUERY_RESULT, result);
			const double coef_n2m = 1.0 / 1000000.0;
			const double time0 = double(result[1] - result[0]) * coef_n2m;
			const double time1 = double(result[2] - result[1]) * coef_n2m;
			static int counter = 0;

			if((counter++ % 64) == 0) {
				printf("read %.2f ms / %.2f GB/s copy: %.2f ms / %.2f GB/s lag: %u  map: %.2f ms / %.2f GB/s\n",
					time0,
					(double(screen_size) / time0) * (1.0 / double(0x100000)),
					time1,
					time1 > 0.01 ? (double(screen_size) / time1) * (1.0 / double(0x100000)) : 0.0,
					_frame_number - sc->_frame_num,
					map_time,
					map_time > 0.01 ? (double(screen_size) / map_time) * (1.0 / double(0x100000)) : 0.0);
			}

			_rb_tail = tmp_tail;
		}
		else {
			break;
		}
	}
}
Exemple #7
0
enum piglit_result piglit_display(void)
{
	GLboolean pass = GL_TRUE;
	float white[] = {1, 1, 1, 1};
	unsigned i, vbo, size;
	size_t page_size;
	GLsync fence = 0;
	float x, y, *mem;

	page_size = piglit_get_page_size();

	size = ALIGN(NUM_PRIMS * TRI_SIZE, page_size);
	mem = piglit_alloc_aligned(page_size, size);

	glClear(GL_COLOR_BUFFER_BIT);
	glEnableClientState(GL_VERTEX_ARRAY);

	glGenBuffers(1, &vbo);
	glBindBuffer(GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, vbo);
	glBufferData(GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, size, mem,
		     GL_STATIC_DRAW);

	glBindBuffer(GL_ARRAY_BUFFER, vbo);
	glVertexPointer(2, GL_FLOAT, 0, 0);

	x = 0, y = 0;
	for (i = 0; i < NUM_PRIMS; i++) {
		unsigned slot = 0;

		switch (test_offset) {
		case TEST_OFFSET_0_FENCE_WAIT:
			if (fence)
				glClientWaitSync(fence,
						 GL_SYNC_FLUSH_COMMANDS_BIT,
						 GL_TIMEOUT_IGNORED);
			break;
		case TEST_OFFSET_INCR_NO_WAIT:
			slot = i;
			break;
		case TEST_OFFSET_DECR_NO_WAIT:
			slot = NUM_PRIMS - 1 - i;
			break;
		default:
			assert(0);
		}

		upload(vbo, mem, slot, x, y, x+20, y+20);
		glDrawArrays(GL_TRIANGLES, slot*3, 3);

		x += 20;
		if (x >= piglit_width) {
			x = 0;
			y += 20;
		}

		if (test_offset == TEST_OFFSET_0_FENCE_WAIT) {
			if (fence)
				glDeleteSync(fence);
			fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
		}
	}

	x = 0, y = 0;
	for (i = 0; i < NUM_PRIMS; i++) {
		GLboolean result = piglit_probe_pixel_rgb(x+5, y+5, white);
		if (!result)
			printf("  ... FAIL with primitive %i:\n", i+1);
		pass = result && pass;

		x += 20;
		if (x >= piglit_width) {
			x = 0;
			y += 20;
		}
	}

	if (fence)
		glDeleteSync(fence);
	glDeleteBuffers(1, &vbo);
	if (!piglit_check_gl_error(GL_NO_ERROR))
		piglit_report_result(PIGLIT_FAIL);
	piglit_present_results();

	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
}
Exemple #8
0
enum piglit_result
piglit_display(void)
{
	GLboolean pass = GL_TRUE;
	GLenum wait_val;
	GLsync sync;

	glClear(GL_COLOR_BUFFER_BIT);

	glBegin(GL_TRIANGLES);
	glColor3f(.8,0,0);
	glVertex3f(-0.9, -0.9, -30.0);
	glColor3f(0,.9,0);
	glVertex3f( 0.9, -0.9, -30.0);
	glColor3f(0,0,.7);
	glVertex3f( 0.0,  0.9, -30.0);
	glEnd();

	glGetError();

	sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
	FAIL_ON_ERROR("glFenceSync");

	if (!glIsSync(sync)) {
		fprintf(stderr, "IsSync(%p) failed\n", sync);
		pass = GL_FALSE;
		goto done;
	}
	FAIL_ON_ERROR("glIsSync");

	if (! test_GetSynciv(sync, GL_SYNC_CONDITION,
			     GL_SYNC_GPU_COMMANDS_COMPLETE)) {
		pass = GL_FALSE;
		goto done;
	}

	if (! test_GetSynciv(sync, GL_SYNC_FLAGS, 0)) {
		pass = GL_FALSE;
		goto done;
	}

	glFinish();

	/* After the glFinish, the sync *must* be signaled!
	 */
	if (! test_GetSynciv(sync, GL_SYNC_STATUS, GL_SIGNALED)) {
		pass = GL_FALSE;
		goto done;
	}


	/* Since the sync has already been signaled, the wait should return
	 * GL_ALREADY_SIGNALED.
	 */
	wait_val = glClientWaitSync(sync, 0, 1);
	FAIL_ON_ERROR("glClientWaitSync");

	if (wait_val != GL_ALREADY_SIGNALED) {
		fprintf(stderr, "glClientWaitSync expected 0x%08x, "
			"got 0x%08x\n", GL_ALREADY_SIGNALED, wait_val);
		pass = GL_FALSE;
	}

	glDeleteSync(sync);
	FAIL_ON_ERROR("glDeleteSync");

done:
	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
}