Пример #1
0
void
schro_opengl_draw_texture (SchroOpenGL * display, GLuint texture,
    int width, int height, int sync)
{
  //g_return_if_fail (width > 0);
  //g_return_if_fail (height > 0);
  //g_return_if_fail (texture != None);

  schro_opengl_lock (display);

  //g_assert (display->window != None);
  //g_assert (display->context != NULL);

  //schro_opengl_update_attributes (display);
#if 0
  /* Doesn't work */
  {
    int64_t ust = 1234;
    int64_t mst = 1234;
    int64_t sbc = 1234;
    int ret;

    ret = glXGetSyncValuesOML (display->display, display->window,
        &ust, &mst, &sbc);
    SCHRO_ERROR ("sync values %d %lld %lld %lld", ret, ust, mst, sbc);
  }
#endif

  if (sync) {
    glXSwapIntervalSGI (1);
  } else {
    glXSwapIntervalSGI (0);
  }

  glViewport (0, 0, display->win_width, display->win_height);

  glClearColor (0.3, 0.3, 0.3, 1.0);
  glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glMatrixMode (GL_PROJECTION);
  glLoadIdentity ();

  glMatrixMode (GL_MODELVIEW);
  glLoadIdentity ();

  glDisable (GL_CULL_FACE);
  glEnableClientState (GL_TEXTURE_COORD_ARRAY);

  glColor4f (1, 1, 1, 1);

  glEnable (GL_TEXTURE_RECTANGLE_ARB);
  glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture);
  glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP);
  glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP);
  glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

  glColor4f (1, 0, 1, 1);
  schro_opengl_check_error (display, __LINE__);
  glBegin (GL_QUADS);

  glNormal3f (0, 0, -1);

  glTexCoord2f (width, 0);
  glVertex3f (1.0, 1.0, 0);
  glTexCoord2f (0, 0);
  glVertex3f (-1.0, 1.0, 0);
  glTexCoord2f (0, height);
  glVertex3f (-1.0, -1.0, 0);
  glTexCoord2f (width, height);
  glVertex3f (1.0, -1.0, 0);
  glEnd ();
  schro_opengl_check_error (display, __LINE__);

  glXSwapBuffers (display->display, display->window);

  schro_opengl_unlock (display);
}
enum piglit_result
draw(Display *dpy)
{
	/* Fill the variables that will be returned as out values with
	 * junk to better detect failure there.
	 */
	int64_t start_ust = 0xd0, start_msc = 0xd0, start_sbc = 0xd0;
	int64_t swapped_ust = 0xd0, swapped_msc = 0xd0, swapped_sbc = 0xd0;
	int64_t current_ust = 0xd0, current_msc = 0xd0, current_sbc = 0xd0;
	int64_t target_msc, outstanding_sbc;
	bool already_wrapped = false;

	piglit_set_timeout(5, PIGLIT_FAIL);

	glXGetSyncValuesOML(dpy, win, &start_ust, &start_msc, &start_sbc);
	if (start_sbc != 0) {
		fprintf(stderr,
			"Initial SBC for the window should be 0, was %lld\n",
			(long long)start_sbc);
		piglit_report_result(PIGLIT_FAIL);
	}
	outstanding_sbc = start_sbc;

wrap:
	glClearColor(0.0, 1.0, 0.0, 0.0);
	glClear(GL_COLOR_BUFFER_BIT);

	/* Queue a swap for 5 frames from when we started. */
	target_msc = start_msc + 5;
	glXSwapBuffersMscOML(dpy, win, target_msc, 0, 0);
	outstanding_sbc++;

	/* Wait for that swap. */
	glXWaitForSbcOML(dpy, win, outstanding_sbc,
			 &swapped_ust, &swapped_msc, &swapped_sbc);
	if (swapped_sbc != outstanding_sbc) {
		fprintf(stderr,
			"glXWaitForSbcOML() returned SBC %lld, "
			"should be %lld\n",
			(long long)swapped_sbc, (long long)outstanding_sbc);
		piglit_report_result(PIGLIT_FAIL);
	}

	glXGetSyncValuesOML(dpy, win,
			    &current_ust, &current_msc, &current_sbc);
	if (current_sbc != outstanding_sbc) {
		fprintf(stderr,
			"glXGetSyncValuesOML() returned SBC %lld, "
			"should be %lld\n",
			(long long)current_sbc, (long long)outstanding_sbc);
		piglit_report_result(PIGLIT_FAIL);
	}

	if (current_msc < start_msc) {
		/* The MSC counter wrapped. Try the test again.  But
		 * it definitely won't wrap this time.
		 */
		if (already_wrapped) {
			fprintf(stderr,
				"Wrapped MSC twice!\n"
				"Second time: %lld -> %lld\n",
				(long long)start_msc,
				(long long)current_msc);
			piglit_report_result(PIGLIT_FAIL);
		}

		glXGetSyncValuesOML(dpy, win,
				    &start_ust, &start_msc, &start_sbc);
		already_wrapped = true;
		goto wrap;
	}

	if (swapped_msc < target_msc) {
		fprintf(stderr,
			"glXWaitForSbcOML() returned MSC %lld, "
			"should be at least %lld\n",
			(long long)swapped_msc,
			(long long)target_msc);
		piglit_report_result(PIGLIT_FAIL);
	}

	if (current_msc < target_msc ||
	    current_msc < swapped_msc) {
		fprintf(stderr,
			"glXGetSyncValuesMsc() returned MSC %lld, "
			"should be at least swap target msc (%lld) "
			"and last swap MSC (%lld)\n",
			(long long)current_msc,
			(long long)target_msc,
			(long long)swapped_msc);
		piglit_report_result(PIGLIT_FAIL);
	}

	piglit_report_result(PIGLIT_PASS);

	/* UNREACHED */
	return PIGLIT_FAIL;
}
Пример #3
0
static enum piglit_result
draw(Display *dpy)
{
    enum piglit_result result = PIGLIT_PASS;
    int64_t last_ust = 0xd0, last_msc = 0xd0, last_sbc = 0xd0;
    int64_t last_timestamp = -1;
    struct stats msc_wallclock_duration_stats = {};
    struct stats msc_ust_duration_stats = {};
    double expected_msc_wallclock_duration = 0.0;
    int32_t rate_num, rate_den;
    unsigned int i;

    if (!glXGetSyncValuesOML(dpy, win, &last_ust, &last_msc, &last_sbc)) {
        fprintf(stderr, "Initial glXGetSyncValuesOML failed\n");
        return PIGLIT_FAIL;
    }

    /* Check that the window is fresh */
    if (last_sbc != 0) {
        fprintf(stderr, "Initial SBC for the window should be 0, was "
                "%" PRId64 "\n",
                last_sbc);
        piglit_merge_result(&result, PIGLIT_WARN);
    }

    if (!glXGetMscRateOML(dpy, win, &rate_num, &rate_den)) {
        fprintf(stderr,
                "glXGetMscRateOML failed, can't test MSC duration\n");
        piglit_merge_result(&result, PIGLIT_WARN);
    } else {
        expected_msc_wallclock_duration = 1e6 * rate_den / rate_num;
    }

    piglit_set_timeout(5, PIGLIT_FAIL);


    for (i = 0; i < loops; i++) {
        int64_t new_ust = 0xd0, new_msc = 0xd0, new_sbc = 0xd0;
        int64_t check_ust = 0xd0, check_msc = 0xd0, check_sbc = 0xd0;
        int64_t new_timestamp;
        int64_t expected_msc, target_sbc;
        int64_t target_msc = 0;

        if (target_msc_delta) {
            target_msc = last_msc + target_msc_delta;
        }

        if (use_swapbuffers) {
            glClearColor(0.0, 1.0, 0.0, 0.0);
            glClear(GL_COLOR_BUFFER_BIT);

            target_sbc = glXSwapBuffersMscOML(dpy, win,
                                              target_msc, divisor, msc_remainder);
            if(target_sbc <= 0) {
                fprintf(stderr, "SwapBuffersMscOML failed\n");
                return PIGLIT_FAIL;
            }
            if(target_sbc != last_sbc + 1) {
                fprintf(stderr,
                        "glXSwapBuffersMscOML calculated the"
                        " wrong target sbc: expected %"PRId64
                        " but got %"PRId64"\n",
                        last_sbc + 1, target_sbc);
                result = PIGLIT_FAIL;
            }

            if(!glXWaitForSbcOML(dpy, win, target_sbc,
                                 &new_ust, &new_msc, &new_sbc))
            {
                fprintf(stderr, "glXWaitForSbcOML failed\n");
                result = PIGLIT_FAIL;
            }
        } else {
            target_sbc = last_sbc;

            if(!glXWaitForMscOML(dpy, win, target_msc, divisor,
                                 msc_remainder, &new_ust,
                                 &new_msc, &new_sbc))
            {
                fprintf(stderr, "glXWaitForSbcOML failed\n");
                result = PIGLIT_FAIL;
            }
        }
        new_timestamp = piglit_get_microseconds();

        if (!glXGetSyncValuesOML(dpy, win,
                                 &check_ust, &check_msc, &check_sbc))
        {
            fprintf(stderr, "Follow-up GetSyncValuesOML failed\n");
            return PIGLIT_FAIL;
        }

        if (new_ust < last_ust) {
            fprintf(stderr, "iteration %u: non-monotonic UST went "
                    "backward by %"PRId64" during Wait\n",
                    i, last_ust - new_ust);
            result = PIGLIT_FAIL;
            /* Wait returned something bogus, but GetSyncValues
             * usually works, so try evaluating the rest of the
             * tests using the check values. */
            new_ust = check_ust;
        }

        if (check_ust < new_ust) {
            fprintf(stderr, "iteration %u: non-monotonic UST went "
                    "backward by %"PRId64" across GetSyncValues\n",
                    i, last_ust - check_ust);
            result = PIGLIT_FAIL;
        }

        if (new_msc < last_msc) {
            fprintf(stderr, "iteration %u: non-monotonic MSC went "
                    "backward by %"PRId64" during Wait\n",
                    i, last_msc - new_msc);
            result = PIGLIT_FAIL;
            /* Wait returned something bogus, but GetSyncValues
             * usually works, so try evaluating the rest of the
             * tests using the check values. */
            new_msc = check_msc;
        }

        if (check_msc < new_msc) {
            fprintf(stderr, "iteration %u: non-monotonic MSC went "
                    "backward by %"PRId64" across GetSyncValues\n",
                    i, last_msc - check_msc);
            result = PIGLIT_FAIL;
        }

        if (new_sbc != target_sbc) {
            fprintf(stderr, "iteration %u: Wait should have "
                    "returned at SBC %"PRId64" but returned at "
                    "%"PRId64"\n",
                    i, target_sbc, new_sbc);
            result = PIGLIT_FAIL;
        }

        if (check_sbc != new_sbc) {
            fprintf(stderr, "iteration %u: GetSyncValues "
                    "returned SBC %"PRId64" but Wait returned "
                    "%"PRId64"\n",
                    i, check_sbc, new_sbc);
            result = PIGLIT_FAIL;
        }

        if (new_msc > last_msc) {
            int64_t delta_msc = new_msc - last_msc;
            update_stats(&msc_ust_duration_stats,
                         (new_ust - last_ust) / delta_msc);

            if (last_timestamp >= 0) {
                if (new_timestamp < 0) {
                    fprintf(stderr,
                            "no monotonic clock\n");
                    piglit_merge_result(&result,
                                        PIGLIT_WARN);
                } else {
                    update_stats(
                        &msc_wallclock_duration_stats,
                        (new_timestamp - last_timestamp)
                        / delta_msc);
                }
            }
        }

        expected_msc = target_msc;
        if (!target_msc) {
            /* If there is a divisor, the expected MSC is the
             * next MSC after last_msc such that
             * MSC % divisor == remainder
             */
            int64_t last_remainder = last_msc % divisor;
            expected_msc = last_msc - last_remainder + msc_remainder;
            if (expected_msc <= last_msc)
                expected_msc += divisor;
        }

        if (new_msc < expected_msc) {
            fprintf(stderr, "iteration %u woke up %"PRId64
                    " MSCs early\n",
                    i, expected_msc - new_msc);
            result = PIGLIT_FAIL;
        }

        if (new_msc > expected_msc) {
            fprintf(stderr, "iteration %u woke up %"PRId64
                    " MSCs later than expected\n",
                    i, new_msc - expected_msc);
            piglit_merge_result(&result, PIGLIT_WARN);
        }

        if (new_msc % divisor != msc_remainder) {
            fprintf(stderr, "iteration %u woke up at wrong MSC"
                    " remainder %"PRId64", not requested remainder"
                    " %"PRId64"\n",
                    i, new_msc % divisor, msc_remainder);
            result = PIGLIT_FAIL;
        }

        last_ust = new_ust;
        last_msc = new_msc;
        last_sbc = new_sbc;
        last_timestamp = new_timestamp;
    }

    if (msc_ust_duration_stats.n < 2) {
        fprintf(stderr, "Not enough UST timing samples\n");
        piglit_merge_result(&result, PIGLIT_WARN);
    } else if (expected_msc_wallclock_duration > 0.0) {
        double apparent_ust_rate = msc_ust_duration_stats.mean /
                                   expected_msc_wallclock_duration;
        if (get_stddev(&msc_ust_duration_stats) / apparent_ust_rate > 100)
        {
            fprintf(stderr, "UST duration per MSC is surprisingly"
                    " variable (stddev %f USTs), but then it only"
                    " has to be monotonic\n",
                    get_stddev(&msc_ust_duration_stats));
            piglit_merge_result(&result, PIGLIT_WARN);
        }
    }

    if (msc_wallclock_duration_stats.n < 2) {
        fprintf(stderr, "Not enough wallclock timing samples\n");
        piglit_merge_result(&result, PIGLIT_WARN);
    } else if (get_stddev(&msc_wallclock_duration_stats) > 1000) {
        fprintf(stderr, "Wallclock time between MSCs has stddev > 1ms"
                " (%fus), driver is probably not syncing to"
                " vblank\n",
                get_stddev(&msc_wallclock_duration_stats));
        result = PIGLIT_FAIL;
    } else if (expected_msc_wallclock_duration > 0.0) {
        if (fabs(expected_msc_wallclock_duration -
                 msc_wallclock_duration_stats.mean) > 50)
        {
            fprintf(stderr, "Wallclock time between MSCs %fus"
                    " does not match glXGetMscRateOML %fus\n",
                    msc_wallclock_duration_stats.mean,
                    expected_msc_wallclock_duration);
            result = PIGLIT_FAIL;
        }
    }

    return result;
}