summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tests/general/triangle-rasterization-overdraw.cpp378
-rw-r--r--tests/general/triangle-rasterization.cpp737
2 files changed, 559 insertions, 556 deletions
diff --git a/tests/general/triangle-rasterization-overdraw.cpp b/tests/general/triangle-rasterization-overdraw.cpp
index 0a41e5850..58b67748f 100644
--- a/tests/general/triangle-rasterization-overdraw.cpp
+++ b/tests/general/triangle-rasterization-overdraw.cpp
@@ -51,16 +51,16 @@
/* Data structures */
struct Vector
{
- Vector()
- {
- }
+ Vector()
+ {
+ }
- Vector(float x, float y)
- : x(x), y(y)
- {
- }
+ Vector(float x, float y)
+ : x(x), y(y)
+ {
+ }
- float x, y;
+ float x, y;
};
/* Command line arguments */
@@ -90,227 +90,227 @@ Mersenne mersenne;
static inline float
random_float(void)
{
- const int float_range = 1 << 23;
- return (mersenne.value() % float_range) * (1.0 / float_range);
+ const int float_range = 1 << 23;
+ return (mersenne.value() % float_range) * (1.0 / float_range);
}
/* Random float from [a to b) */
static inline float
random_float(float a, float b)
{
- return a + (b - a - 1) * random_float();
+ return a + (b - a - 1) * random_float();
}
struct TestCase
{
- Vector mid;
- std::vector<Vector> triangle_fan;
-
- struct {
- int x;
- int y;
- int w;
- int h;
- } probe_rect;
-
- void generate(void);
- bool run(void) const;
+ Vector mid;
+ std::vector<Vector> triangle_fan;
+
+ struct {
+ int x;
+ int y;
+ int w;
+ int h;
+ } probe_rect;
+
+ void generate(void);
+ bool run(void) const;
};
/* Generates a random triangle fan with a random origin, and contouring a rectangle or circle */
void TestCase::generate(void)
{
- /* Random center point */
- if (clips) {
- mid.x = random_float(-0.5*piglit_width, 1.5*piglit_width);
- mid.y = random_float(-0.5*piglit_height, 1.5*piglit_height);
- } else {
- mid.x = random_float(0, piglit_width);
- mid.y = random_float(0, piglit_height);
- }
-
- if (clips) {
- probe_rect.x = 0;
- probe_rect.y = 0;
- probe_rect.w = piglit_width;
- probe_rect.h = piglit_height;
- } else {
- probe_rect.x = piglit_width/4;
- probe_rect.y = piglit_height/4;
- probe_rect.w = piglit_width/2;
- probe_rect.h = piglit_height/2;
- }
-
- triangle_fan.clear();
- triangle_fan.push_back(mid);
-
- if (rect) {
- /* Step around the window perimeter adding triangles */
- double perimeter = probe_rect.w*2 + probe_rect.h*2;
- double pos = 0.0;
-
- while (pos < perimeter) {
- Vector vertex;
-
- if (pos < probe_rect.w) {
- /* bottom */
- vertex.x = probe_rect.x + pos;
- vertex.y = probe_rect.y + 0.0f;
- } else if (pos < probe_rect.w + probe_rect.h) {
- /* right */
- vertex.x = probe_rect.x + probe_rect.w;
- vertex.y = probe_rect.y + pos - probe_rect.w;
- } else if(pos < probe_rect.w*2 + probe_rect.h) {
- /* top */
- vertex.x = probe_rect.x + probe_rect.w - (pos - (probe_rect.w + probe_rect.h));
- vertex.y = probe_rect.y + probe_rect.h;
- } else {
- /* left */
- vertex.x = probe_rect.x + 0.0f;
- vertex.y = probe_rect.y + probe_rect.h - (pos - (probe_rect.w*2 + probe_rect.h));
- }
-
- triangle_fan.push_back(vertex);
- pos += random_float();
- }
- } else {
- /* Step around a circle that contains the window */
- double radius = (sqrt((double)(probe_rect.w*probe_rect.w + probe_rect.h*probe_rect.h)) / 2.0) + 5.0;
- double perimeter = 2.0 * M_PI * radius;
- double pos = 0.0;
-
- while (pos < perimeter) {
- double theta = pos / radius;
-
- float x = probe_rect.x + 0.5 * probe_rect.w + cos(theta) * radius;
- float y = probe_rect.y + 0.5 * probe_rect.h + sin(theta) * radius;
-
- triangle_fan.push_back(Vector(x, y));
- pos += random_float();
- }
- }
-
- /* Complete the fan! */
- triangle_fan.push_back(triangle_fan.at(1));
- ++test_id;
+ /* Random center point */
+ if (clips) {
+ mid.x = random_float(-0.5*piglit_width, 1.5*piglit_width);
+ mid.y = random_float(-0.5*piglit_height, 1.5*piglit_height);
+ } else {
+ mid.x = random_float(0, piglit_width);
+ mid.y = random_float(0, piglit_height);
+ }
+
+ if (clips) {
+ probe_rect.x = 0;
+ probe_rect.y = 0;
+ probe_rect.w = piglit_width;
+ probe_rect.h = piglit_height;
+ } else {
+ probe_rect.x = piglit_width/4;
+ probe_rect.y = piglit_height/4;
+ probe_rect.w = piglit_width/2;
+ probe_rect.h = piglit_height/2;
+ }
+
+ triangle_fan.clear();
+ triangle_fan.push_back(mid);
+
+ if (rect) {
+ /* Step around the window perimeter adding triangles */
+ double perimeter = probe_rect.w*2 + probe_rect.h*2;
+ double pos = 0.0;
+
+ while (pos < perimeter) {
+ Vector vertex;
+
+ if (pos < probe_rect.w) {
+ /* bottom */
+ vertex.x = probe_rect.x + pos;
+ vertex.y = probe_rect.y + 0.0f;
+ } else if (pos < probe_rect.w + probe_rect.h) {
+ /* right */
+ vertex.x = probe_rect.x + probe_rect.w;
+ vertex.y = probe_rect.y + pos - probe_rect.w;
+ } else if(pos < probe_rect.w*2 + probe_rect.h) {
+ /* top */
+ vertex.x = probe_rect.x + probe_rect.w - (pos - (probe_rect.w + probe_rect.h));
+ vertex.y = probe_rect.y + probe_rect.h;
+ } else {
+ /* left */
+ vertex.x = probe_rect.x + 0.0f;
+ vertex.y = probe_rect.y + probe_rect.h - (pos - (probe_rect.w*2 + probe_rect.h));
+ }
+
+ triangle_fan.push_back(vertex);
+ pos += random_float();
+ }
+ } else {
+ /* Step around a circle that contains the window */
+ double radius = (sqrt((double)(probe_rect.w*probe_rect.w + probe_rect.h*probe_rect.h)) / 2.0) + 5.0;
+ double perimeter = 2.0 * M_PI * radius;
+ double pos = 0.0;
+
+ while (pos < perimeter) {
+ double theta = pos / radius;
+
+ float x = probe_rect.x + 0.5 * probe_rect.w + cos(theta) * radius;
+ float y = probe_rect.y + 0.5 * probe_rect.h + sin(theta) * radius;
+
+ triangle_fan.push_back(Vector(x, y));
+ pos += random_float();
+ }
+ }
+
+ /* Complete the fan! */
+ triangle_fan.push_back(triangle_fan.at(1));
+ ++test_id;
}
/* Tests a triangle fan */
bool TestCase::run(void) const
{
- glViewport(0, 0, piglit_width, piglit_height);
- piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
-
- /* Set render state */
- float colour[4];
- glEnable(GL_BLEND);
- glBlendEquation(GL_FUNC_ADD);
- if (rect) {
- glBlendFunc(GL_ONE, GL_ONE);
- colour[0] = colour[1] = colour[2] = 127.0f / 255.0f;
- } else {
- /* Invert.
- *
- * When contouring a circle with very small steps, some overdraw occurs
- * naturally, but it should cancel itself out, i.e., there should be an
- * odd number of overdraw inside the shape, and an even number outside.
- * */
- glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO);
- colour[0] = colour[1] = colour[2] = 1.0f;
- }
-
- colour[3] = 1.0f;
- glColor4fv(colour);
-
- glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
- glClear(GL_COLOR_BUFFER_BIT);
-
- /* Draw triangle fan */
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(2, GL_FLOAT, 0, &triangle_fan.front());
- glDrawArrays(GL_TRIANGLE_FAN, 0, triangle_fan.size());
- glDisableClientState(GL_VERTEX_ARRAY);
-
- /* Reset draw state */
- glDisable(GL_BLEND);
-
- if (!piglit_probe_rect_rgb(probe_rect.x, probe_rect.y, probe_rect.w, probe_rect.y, colour)) {
- printf("%d. Triangle Fan with %d triangles around (%f, %f)\n",
- test_id, (int)triangle_fan.size(), mid.x, mid.y);
-
- fflush(stdout);
- return false;
- }
-
- return true;
+ glViewport(0, 0, piglit_width, piglit_height);
+ piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
+
+ /* Set render state */
+ float colour[4];
+ glEnable(GL_BLEND);
+ glBlendEquation(GL_FUNC_ADD);
+ if (rect) {
+ glBlendFunc(GL_ONE, GL_ONE);
+ colour[0] = colour[1] = colour[2] = 127.0f / 255.0f;
+ } else {
+ /* Invert.
+ *
+ * When contouring a circle with very small steps, some overdraw occurs
+ * naturally, but it should cancel itself out, i.e., there should be an
+ * odd number of overdraw inside the shape, and an even number outside.
+ * */
+ glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO);
+ colour[0] = colour[1] = colour[2] = 1.0f;
+ }
+
+ colour[3] = 1.0f;
+ glColor4fv(colour);
+
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ /* Draw triangle fan */
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glVertexPointer(2, GL_FLOAT, 0, &triangle_fan.front());
+ glDrawArrays(GL_TRIANGLE_FAN, 0, triangle_fan.size());
+ glDisableClientState(GL_VERTEX_ARRAY);
+
+ /* Reset draw state */
+ glDisable(GL_BLEND);
+
+ if (!piglit_probe_rect_rgb(probe_rect.x, probe_rect.y, probe_rect.w, probe_rect.y, colour)) {
+ printf("%d. Triangle Fan with %d triangles around (%f, %f)\n",
+ test_id, (int)triangle_fan.size(), mid.x, mid.y);
+
+ fflush(stdout);
+ return false;
+ }
+
+ return true;
}
/* Render */
enum piglit_result
piglit_display(void)
{
- /* Perform test */
- GLboolean pass = GL_TRUE;
+ /* Perform test */
+ GLboolean pass = GL_TRUE;
- TestCase test_case;
+ TestCase test_case;
- if (piglit_automatic) {
- int fail_count = 0;
+ if (piglit_automatic) {
+ int fail_count = 0;
- printf("Running %d random tests\n", random_test_count);
- fflush(stdout);
+ printf("Running %d random tests\n", random_test_count);
+ fflush(stdout);
- for (int i = 0; i < random_test_count && !(fail_count && break_on_fail); ++i) {
- test_case.generate();
- if (!test_case.run())
- fail_count++;
- }
+ for (int i = 0; i < random_test_count && !(fail_count && break_on_fail); ++i) {
+ test_case.generate();
+ if (!test_case.run())
+ fail_count++;
+ }
- printf("Failed %d random tests\n", fail_count);
- fflush(stdout);
+ printf("Failed %d random tests\n", fail_count);
+ fflush(stdout);
- if (fail_count)
- pass = GL_FALSE;
- } else {
- test_case.generate();
- pass = pass && test_case.run();
+ if (fail_count)
+ pass = GL_FALSE;
+ } else {
+ test_case.generate();
+ pass = pass && test_case.run();
- piglit_present_results();
- }
+ piglit_present_results();
+ }
- assert(glGetError() == 0);
- return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+ assert(glGetError() == 0);
+ return pass ? PIGLIT_PASS : PIGLIT_FAIL;
}
/* Read command line arguments! */
void
piglit_init(int argc, char **argv)
{
- uint32_t seed = 0xfacebeef ^ time(NULL);
-
- for (int i = 1; i < argc; ++i) {
- if (strcmp(argv[i], "-break_on_fail") == 0){
- break_on_fail = true;
- printf("Execution will stop on first fail\n");
- } else if (strcmp(argv[i], "-rect") == 0){
- rect = true;
- } else if (strcmp(argv[i], "-max_size") == 0){
- glGetIntegerv(GL_MAX_TEXTURE_SIZE, &piglit_width);
- piglit_height = piglit_width;
- } else if (strcmp(argv[i], "-clip") == 0){
- clips = true;
- printf("Clipped triangles are being tested\n");
- } else if (i + 1 < argc) {
- if (strcmp(argv[i], "-count") == 0) {
- random_test_count = strtoul(argv[++i], NULL, 0);
- } else if (strcmp(argv[i], "-seed") == 0) {
- seed = strtoul(argv[++i], NULL, 0);
- }
- }
- }
-
- printf("Random seed: 0x%08X\n", seed);
- mersenne.init(seed);
+ uint32_t seed = 0xfacebeef ^ time(NULL);
+
+ for (int i = 1; i < argc; ++i) {
+ if (strcmp(argv[i], "-break_on_fail") == 0){
+ break_on_fail = true;
+ printf("Execution will stop on first fail\n");
+ } else if (strcmp(argv[i], "-rect") == 0){
+ rect = true;
+ } else if (strcmp(argv[i], "-max_size") == 0){
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, &piglit_width);
+ piglit_height = piglit_width;
+ } else if (strcmp(argv[i], "-clip") == 0){
+ clips = true;
+ printf("Clipped triangles are being tested\n");
+ } else if (i + 1 < argc) {
+ if (strcmp(argv[i], "-count") == 0) {
+ random_test_count = strtoul(argv[++i], NULL, 0);
+ } else if (strcmp(argv[i], "-seed") == 0) {
+ seed = strtoul(argv[++i], NULL, 0);
+ }
+ }
+ }
+
+ printf("Random seed: 0x%08X\n", seed);
+ mersenne.init(seed);
}
diff --git a/tests/general/triangle-rasterization.cpp b/tests/general/triangle-rasterization.cpp
index 78b5b73b0..5dc02567a 100644
--- a/tests/general/triangle-rasterization.cpp
+++ b/tests/general/triangle-rasterization.cpp
@@ -45,41 +45,41 @@
/* Data structures */
struct Vector
{
- Vector()
- {
- }
+ Vector()
+ {
+ }
- Vector(float x, float y)
- : x(x), y(y)
- {
- }
+ Vector(float x, float y)
+ : x(x), y(y)
+ {
+ }
- float x, y;
+ float x, y;
};
struct Triangle {
- Triangle()
- {
- }
-
- Triangle(const Vector& v0, const Vector& v1, const Vector& v2)
- {
- v[0] = v0;
- v[1] = v1;
- v[2] = v2;
- }
-
- Vector& operator[](int i)
- {
- return v[i];
- }
-
- const Vector& operator[](int i) const
- {
- return v[i];
- }
-
- Vector v[3];
+ Triangle()
+ {
+ }
+
+ Triangle(const Vector& v0, const Vector& v1, const Vector& v2)
+ {
+ v[0] = v0;
+ v[1] = v1;
+ v[2] = v2;
+ }
+
+ Vector& operator[](int i)
+ {
+ return v[i];
+ }
+
+ const Vector& operator[](int i) const
+ {
+ return v[i];
+ }
+
+ Vector v[3];
};
@@ -117,175 +117,178 @@ std::vector<Triangle> fixed_tests;
/* std::algorithm min/max with 3 arguments! :D */
namespace std {
- template<typename T>
- T min(T& a, T& b, T& c)
- {
- return (a < b) ? std::min(a, c) : std::min(b, c);
- }
-
- template<typename T>
- T max(T& a, T& b, T& c)
- {
- return (a > b) ? std::max(a, c) : std::max(b, c);
- }
+ template<typename T>
+ T min(T& a, T& b, T& c)
+ {
+ return (a < b) ? std::min(a, c) : std::min(b, c);
+ }
+
+ template<typename T>
+ T max(T& a, T& b, T& c)
+ {
+ return (a > b) ? std::max(a, c) : std::max(b, c);
+ }
}
/* Proper rounding of float to integer */
int iround(float v)
{
- if (v > 0.0f) v += 0.5f;
- if (v < 0.0f) v -= 0.5f;
- return (int)v;
+ if (v > 0.0f)
+ v += 0.5f;
+ if (v < 0.0f)
+ v -= 0.5f;
+ return (int)v;
}
/* Calculate log2 for integers */
int log2i(int x)
{
- int res = 0 ;
- while (x >>= 1) ++res;
- return res ;
+ int res = 0 ;
+ while (x >>= 1)
+ ++res;
+ return res ;
}
/* Based on http://devmaster.net/forums/topic/1145-advanced-rasterization */
void rast_triangle(uint8_t* buffer, uint32_t stride, const Triangle& tri)
{
- float center_offset = -0.5f;
-
- /* 28.4 fixed point coordinates */
- int x1 = iround(FIXED_ONE * (tri[0].x + center_offset));
- int x2 = iround(FIXED_ONE * (tri[1].x + center_offset));
- int x3 = iround(FIXED_ONE * (tri[2].x + center_offset));
-
- int y1 = iround(FIXED_ONE * (tri[0].y + center_offset));
- int y2 = iround(FIXED_ONE * (tri[1].y + center_offset));
- int y3 = iround(FIXED_ONE * (tri[2].y + center_offset));
-
- /* Force correct vertex order */
- const int cross = (x2 - x1) * (y3 - y2) - (y2 - y1) * (x3 - x2);
- if (cross > 0) {
- std::swap(x1, x3);
- std::swap(y1, y3);
- }
-
- /* Deltas */
- const int dx12 = x1 - x2;
- const int dx23 = x2 - x3;
- const int dx31 = x3 - x1;
-
- const int dy12 = y1 - y2;
- const int dy23 = y2 - y3;
- const int dy31 = y3 - y1;
-
- /* Fixed-point deltas */
- const int fdx12 = dx12 << FIXED_SHIFT;
- const int fdx23 = dx23 << FIXED_SHIFT;
- const int fdx31 = dx31 << FIXED_SHIFT;
-
- const int fdy12 = dy12 << FIXED_SHIFT;
- const int fdy23 = dy23 << FIXED_SHIFT;
- const int fdy31 = dy31 << FIXED_SHIFT;
-
- /* Bounding rectangle */
- int minx = std::min(x1, x2, x3) >> FIXED_SHIFT;
- int maxx = (std::max(x1, x2, x3) - 1) >> FIXED_SHIFT;
-
- int miny = (std::min(y1, y2, y3) + 1) >> FIXED_SHIFT;
- int maxy = std::max(y1, y2, y3) >> FIXED_SHIFT;
-
- minx = std::max(minx, 0);
- maxx = std::min(maxx, fbo_width - 1);
-
- miny = std::max(miny, 0);
- maxy = std::min(maxy, fbo_height - 1);
-
- /* Half-edge constants */
- int c1 = dy12 * x1 - dx12 * y1;
- int c2 = dy23 * x2 - dx23 * y2;
- int c3 = dy31 * x3 - dx31 * y3;
-
- /* Correct for fill convention */
- if (dy12 < 0 || (dy12 == 0 && dx12 > 0)) c1++;
- if (dy23 < 0 || (dy23 == 0 && dx23 > 0)) c2++;
- if (dy31 < 0 || (dy31 == 0 && dx31 > 0)) c3++;
-
- int cy1 = c1 + dx12 * (miny << FIXED_SHIFT) - dy12 * (minx << FIXED_SHIFT);
- int cy2 = c2 + dx23 * (miny << FIXED_SHIFT) - dy23 * (minx << FIXED_SHIFT);
- int cy3 = c3 + dx31 * (miny << FIXED_SHIFT) - dy31 * (minx << FIXED_SHIFT);
-
- /* Perform rasterization */
- buffer += miny * stride;
- for (int y = miny; y <= maxy; y++) {
- int cx1 = cy1;
- int cx2 = cy2;
- int cx3 = cy3;
-
- for (int x = minx; x <= maxx; x++) {
- if (cx1 > 0 && cx2 > 0 && cx3 > 0) {
- ((uint32_t*)buffer)[x] = 0x00FF00FF;
- }
-
- cx1 -= fdy12;
- cx2 -= fdy23;
- cx3 -= fdy31;
- }
-
- cy1 += fdx12;
- cy2 += fdx23;
- cy3 += fdx31;
-
- buffer += stride;
- }
+ float center_offset = -0.5f;
+
+ /* 28.4 fixed point coordinates */
+ int x1 = iround(FIXED_ONE * (tri[0].x + center_offset));
+ int x2 = iround(FIXED_ONE * (tri[1].x + center_offset));
+ int x3 = iround(FIXED_ONE * (tri[2].x + center_offset));
+
+ int y1 = iround(FIXED_ONE * (tri[0].y + center_offset));
+ int y2 = iround(FIXED_ONE * (tri[1].y + center_offset));
+ int y3 = iround(FIXED_ONE * (tri[2].y + center_offset));
+
+ /* Force correct vertex order */
+ const int cross = (x2 - x1) * (y3 - y2) - (y2 - y1) * (x3 - x2);
+ if (cross > 0) {
+ std::swap(x1, x3);
+ std::swap(y1, y3);
+ }
+
+ /* Deltas */
+ const int dx12 = x1 - x2;
+ const int dx23 = x2 - x3;
+ const int dx31 = x3 - x1;
+
+ const int dy12 = y1 - y2;
+ const int dy23 = y2 - y3;
+ const int dy31 = y3 - y1;
+
+ /* Fixed-point deltas */
+ const int fdx12 = dx12 << FIXED_SHIFT;
+ const int fdx23 = dx23 << FIXED_SHIFT;
+ const int fdx31 = dx31 << FIXED_SHIFT;
+
+ const int fdy12 = dy12 << FIXED_SHIFT;
+ const int fdy23 = dy23 << FIXED_SHIFT;
+ const int fdy31 = dy31 << FIXED_SHIFT;
+
+ /* Bounding rectangle */
+ int minx = std::min(x1, x2, x3) >> FIXED_SHIFT;
+ int maxx = (std::max(x1, x2, x3) - 1) >> FIXED_SHIFT;
+
+ int miny = (std::min(y1, y2, y3) + 1) >> FIXED_SHIFT;
+ int maxy = std::max(y1, y2, y3) >> FIXED_SHIFT;
+
+ minx = std::max(minx, 0);
+ maxx = std::min(maxx, fbo_width - 1);
+
+ miny = std::max(miny, 0);
+ maxy = std::min(maxy, fbo_height - 1);
+
+ /* Half-edge constants */
+ int c1 = dy12 * x1 - dx12 * y1;
+ int c2 = dy23 * x2 - dx23 * y2;
+ int c3 = dy31 * x3 - dx31 * y3;
+
+ /* Correct for fill convention */
+ if (dy12 < 0 || (dy12 == 0 && dx12 > 0)) c1++;
+ if (dy23 < 0 || (dy23 == 0 && dx23 > 0)) c2++;
+ if (dy31 < 0 || (dy31 == 0 && dx31 > 0)) c3++;
+
+ int cy1 = c1 + dx12 * (miny << FIXED_SHIFT) - dy12 * (minx << FIXED_SHIFT);
+ int cy2 = c2 + dx23 * (miny << FIXED_SHIFT) - dy23 * (minx << FIXED_SHIFT);
+ int cy3 = c3 + dx31 * (miny << FIXED_SHIFT) - dy31 * (minx << FIXED_SHIFT);
+
+ /* Perform rasterization */
+ buffer += miny * stride;
+ for (int y = miny; y <= maxy; y++) {
+ int cx1 = cy1;
+ int cx2 = cy2;
+ int cx3 = cy3;
+
+ for (int x = minx; x <= maxx; x++) {
+ if (cx1 > 0 && cx2 > 0 && cx3 > 0) {
+ ((uint32_t*)buffer)[x] = 0x00FF00FF;
+ }
+
+ cx1 -= fdy12;
+ cx2 -= fdy23;
+ cx3 -= fdy31;
+ }
+
+ cy1 += fdx12;
+ cy2 += fdx23;
+ cy3 += fdx31;
+
+ buffer += stride;
+ }
}
/* Prints an ascii representation of the triangle */
void triangle_art(uint32_t* buffer)
{
- int minx = fbo_width - 1, miny = fbo_height - 1;
- int maxx = 0, maxy = 0;
-
- /* Find bounds so we dont have to print whole screen */
- for (int y = 0; y < fbo_height; ++y) {
- for (int x = 0; x < fbo_width; ++x) {
- if (buffer[y*fbo_width + x] & 0xFFFFFF00) {
- if (x < minx) minx = x;
- if (y < miny) miny = y;
- if (x > maxx) maxx = x;
- if (y > maxy) maxy = y;
- }
- }
- }
-
- /* Nothing drawn */
- if (minx > maxx || miny > maxy)
- return;
-
- --minx; --miny;
- ++maxx; ++maxy;
-
- /* Print an ascii representation of triangle */
- for (int y = maxy; y >= miny; --y) {
- for (int x = minx; x <= maxx; ++x) {
- uint32_t val = buffer[y*fbo_width + x] & 0xFFFFFF00;
-
- if (val == 0xFF000000) {
- printf("+");
- } else if (val == 0x00FF0000) {
- printf("-");
- } else if (val == 0xFFFF0000) {
- printf("o");
- } else if (val == 0) {
- printf(".");
- } else {
- printf("?");
- }
- }
-
- printf("\n");
- }
-
- printf("\n");
+ int minx = fbo_width - 1, miny = fbo_height - 1;
+ int maxx = 0, maxy = 0;
+
+ /* Find bounds so we dont have to print whole screen */
+ for (int y = 0; y < fbo_height; ++y) {
+ for (int x = 0; x < fbo_width; ++x) {
+ if (buffer[y*fbo_width + x] & 0xFFFFFF00) {
+ if (x < minx) minx = x;
+ if (y < miny) miny = y;
+ if (x > maxx) maxx = x;
+ if (y > maxy) maxy = y;
+ }
+ }
+ }
+
+ /* Nothing drawn */
+ if (minx > maxx || miny > maxy)
+ return;
+
+ --minx; --miny;
+ ++maxx; ++maxy;
+
+ /* Print an ascii representation of triangle */
+ for (int y = maxy; y >= miny; --y) {
+ for (int x = minx; x <= maxx; ++x) {
+ uint32_t val = buffer[y*fbo_width + x] & 0xFFFFFF00;
+
+ if (val == 0xFF000000) {
+ printf("+");
+ } else if (val == 0x00FF0000) {
+ printf("-");
+ } else if (val == 0xFFFF0000) {
+ printf("o");
+ } else if (val == 0) {
+ printf(".");
+ } else {
+ printf("?");
+ }
+ }
+
+ printf("\n");
+ }
+
+ printf("\n");
}
@@ -294,73 +297,73 @@ void triangle_art(uint32_t* buffer)
*/
uint32_t* check_triangle()
{
- static uint32_t* buffer = 0;
- if (!buffer) buffer = new uint32_t[fbo_width * fbo_height];
+ static uint32_t* buffer = 0;
+ if (!buffer) buffer = new uint32_t[fbo_width * fbo_height];
- glReadPixels(0, 0, fbo_width, fbo_height, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, buffer);
+ glReadPixels(0, 0, fbo_width, fbo_height, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, buffer);
- for (int y = 0; y < fbo_height; ++y) {
- for (int x = 0; x < fbo_width; ++x) {
- uint32_t val = buffer[y*fbo_width + x] & 0xFFFFFF00;
+ for (int y = 0; y < fbo_height; ++y) {
+ for (int x = 0; x < fbo_width; ++x) {
+ uint32_t val = buffer[y*fbo_width + x] & 0xFFFFFF00;
- if (val != 0 && val != 0xFFFF0000) {
- return buffer;
- }
- }
- }
+ if (val != 0 && val != 0xFFFF0000) {
+ return buffer;
+ }
+ }
+ }
- return NULL;
+ return NULL;
}
/* Performs test using tri */
GLboolean test_triangle(const Triangle& tri)
{
- static uint32_t* buffer = 0;
- if (!buffer) buffer = new uint32_t[fbo_width * fbo_height];
+ static uint32_t* buffer = 0;
+ if (!buffer) buffer = new uint32_t[fbo_width * fbo_height];
- /* Clear OpenGL and software buffer */
- glClear(GL_COLOR_BUFFER_BIT);
- memset(buffer, 0, sizeof(uint32_t) * fbo_width * fbo_height);
+ /* Clear OpenGL and software buffer */
+ glClear(GL_COLOR_BUFFER_BIT);
+ memset(buffer, 0, sizeof(uint32_t) * fbo_width * fbo_height);
- /* Software rasterise triangle and blit it to OpenGL */
- rast_triangle((uint8_t*)buffer, fbo_width * 4, tri);
- glDrawPixels(fbo_width, fbo_height, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, buffer);
+ /* Software rasterise triangle and blit it to OpenGL */
+ rast_triangle((uint8_t*)buffer, fbo_width * 4, tri);
+ glDrawPixels(fbo_width, fbo_height, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, buffer);
- /* Draw OpenGL triangle */
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(2, GL_FLOAT, 0, tri.v);
- glDrawArrays(GL_TRIANGLES, 0, 3);
- glDisableClientState(GL_VERTEX_ARRAY);
+ /* Draw OpenGL triangle */
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glVertexPointer(2, GL_FLOAT, 0, tri.v);
+ glDrawArrays(GL_TRIANGLES, 0, 3);
+ glDisableClientState(GL_VERTEX_ARRAY);
- /* Check the result and print relevant error messages */
- if (uint32_t* result = check_triangle()) {
- printf("FAIL: %d. (%f, %f), (%f, %f), (%f, %f)\n", test_id,
- tri[0].x, tri[0].y, tri[1].x, tri[1].y, tri[2].x, tri[2].y);
+ /* Check the result and print relevant error messages */
+ if (uint32_t* result = check_triangle()) {
+ printf("FAIL: %d. (%f, %f), (%f, %f), (%f, %f)\n", test_id,
+ tri[0].x, tri[0].y, tri[1].x, tri[1].y, tri[2].x, tri[2].y);
- if (print_triangle) {
- triangle_art(result);
- }
+ if (print_triangle) {
+ triangle_art(result);
+ }
- fflush(stdout);
- return GL_FALSE;
- }
+ fflush(stdout);
+ return GL_FALSE;
+ }
- return GL_TRUE;
+ return GL_TRUE;
}
/* Generate a random triangle */
void random_triangle(Triangle& tri)
{
- int size = 1 << (mersenne.value() % (log2i(fbo_width) + 1));
+ int size = 1 << (mersenne.value() % (log2i(fbo_width) + 1));
- for (int i = 0; i < 3; ++i) {
- tri[i].x = (mersenne.value() % (size * FIXED_ONE)) * (1.0f / FIXED_ONE);
- tri[i].y = (mersenne.value() % (size * FIXED_ONE)) * (1.0f / FIXED_ONE);
- }
+ for (int i = 0; i < 3; ++i) {
+ tri[i].x = (mersenne.value() % (size * FIXED_ONE)) * (1.0f / FIXED_ONE);
+ tri[i].y = (mersenne.value() % (size * FIXED_ONE)) * (1.0f / FIXED_ONE);
+ }
- test_id++;
+ test_id++;
}
@@ -368,109 +371,109 @@ void random_triangle(Triangle& tri)
enum piglit_result
piglit_display(void)
{
- GLuint fb, tex;
+ GLuint fb, tex;
- /* If using FBO, set it up */
- if (use_fbo) {
- glDisable(GL_CULL_FACE);
+ /* If using FBO, set it up */
+ if (use_fbo) {
+ glDisable(GL_CULL_FACE);
- glGenTextures(1, &tex);
- glBindTexture(GL_TEXTURE_2D, tex);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, fbo_width, fbo_height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
+ glGenTextures(1, &tex);
+ glBindTexture(GL_TEXTURE_2D, tex);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, fbo_width, fbo_height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
- glGenFramebuffersEXT(1, &fb);
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
- glViewport(0, 0, fbo_width, fbo_height);
+ glGenFramebuffersEXT(1, &fb);
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
+ glViewport(0, 0, fbo_width, fbo_height);
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
- GL_COLOR_ATTACHMENT0_EXT,
- GL_TEXTURE_2D,
- tex,
- 0);
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
+ GL_COLOR_ATTACHMENT0_EXT,
+ GL_TEXTURE_2D,
+ tex,
+ 0);
- assert(glGetError() == 0);
- assert(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT);
+ assert(glGetError() == 0);
+ assert(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT);
- glBindTexture(GL_TEXTURE_2D, 0);
- }
+ glBindTexture(GL_TEXTURE_2D, 0);
+ }
- /* Set render state */
- glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
- glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+ /* Set render state */
+ glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
+ glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
- glEnable(GL_BLEND);
- glBlendEquation(GL_FUNC_ADD);
- glBlendFunc(GL_ONE, GL_ONE);
+ glEnable(GL_BLEND);
+ glBlendEquation(GL_FUNC_ADD);
+ glBlendFunc(GL_ONE, GL_ONE);
- glViewport(0, 0, fbo_width, fbo_height);
- piglit_ortho_projection(fbo_width, fbo_height, GL_FALSE);
+ glViewport(0, 0, fbo_width, fbo_height);
+ piglit_ortho_projection(fbo_width, fbo_height, GL_FALSE);
- /* Perform test */
- GLboolean pass = GL_TRUE;
- if (piglit_automatic) {
- int fail_count = 0;
+ /* Perform test */
+ GLboolean pass = GL_TRUE;
+ if (piglit_automatic) {
+ int fail_count = 0;
- printf("Running %d fixed tests\n", (int)fixed_tests.size());
- for (std::vector<Triangle>::iterator itr = fixed_tests.begin(); itr != fixed_tests.end() && !(fail_count && break_on_fail); ++itr) {
- if (!test_triangle(*itr))
- ++fail_count;
- }
+ printf("Running %d fixed tests\n", (int)fixed_tests.size());
+ for (std::vector<Triangle>::iterator itr = fixed_tests.begin(); itr != fixed_tests.end() && !(fail_count && break_on_fail); ++itr) {
+ if (!test_triangle(*itr))
+ ++fail_count;
+ }
- printf("Running %d random tests\n", random_test_count);
- for (int i = 0; i < random_test_count && !(fail_count && break_on_fail); ++i) {
- Triangle tri;
- random_triangle(tri);
+ printf("Running %d random tests\n", random_test_count);
+ for (int i = 0; i < random_test_count && !(fail_count && break_on_fail); ++i) {
+ Triangle tri;
+ random_triangle(tri);
- if (!test_triangle(tri))
- ++fail_count;
- }
+ if (!test_triangle(tri))
+ ++fail_count;
+ }
- printf("Failed %d tests\n", fail_count);
- fflush(stdout);
+ printf("Failed %d tests\n", fail_count);
+ fflush(stdout);
- if (fail_count)
- pass = GL_FALSE;
- } else {
- Triangle tri;
- random_triangle(tri);
- pass &= test_triangle(tri);
+ if (fail_count)
+ pass = GL_FALSE;
+ } else {
+ Triangle tri;
+ random_triangle(tri);
+ pass &= test_triangle(tri);
- glDisable(GL_BLEND);
+ glDisable(GL_BLEND);
- /* If using FBO, draw the fbo to screen */
- if (use_fbo) {
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
- glViewport(0, 0, piglit_width, piglit_height);
- piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
+ /* If using FBO, draw the fbo to screen */
+ if (use_fbo) {
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+ glViewport(0, 0, piglit_width, piglit_height);
+ piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
- glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
- glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
- glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, tex);
+ glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, tex);
- piglit_draw_rect_tex(0, 0, piglit_width, piglit_height, 0, 0, 1, 1);
+ piglit_draw_rect_tex(0, 0, piglit_width, piglit_height, 0, 0, 1, 1);
- glDisable(GL_TEXTURE_2D);
- }
+ glDisable(GL_TEXTURE_2D);
+ }
- piglit_present_results();
- }
+ piglit_present_results();
+ }
- /* Cleanup FBO if necessary */
- if (use_fbo) {
- glDeleteTextures(1, &tex);
- glDeleteFramebuffersEXT(1, &fb);
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
- }
+ /* Cleanup FBO if necessary */
+ if (use_fbo) {
+ glDeleteTextures(1, &tex);
+ glDeleteFramebuffersEXT(1, &fb);
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+ }
- assert(glGetError() == 0);
+ assert(glGetError() == 0);
- return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+ return pass ? PIGLIT_PASS : PIGLIT_FAIL;
}
@@ -483,46 +486,46 @@ piglit_display(void)
*/
void init_fixed_tests()
{
- const float mid = 0.5f;
- const float shift = 1.0f / FIXED_ONE;
- const float size = 3.0f / FIXED_ONE;
-
- Vector vv[] = {
- Vector(mid, mid + size),
- Vector(mid, mid - size),
- };
-
- Vector vh[] = {
- Vector(mid - size, mid),
- Vector(mid + size, mid),
- };
-
- Vector vm(mid, mid);
-
- /* Loop through the 4 possible triangles */
- for (int vy = 0; vy < 2; ++vy) {
- for (int vx = 0; vx < 2; ++vx) {
- Triangle tri;
-
- tri[0] = vh[vx];
- tri[1] = vv[vy];
- tri[2] = vm;
-
- /* Loop through the x and y shifts */
- for (int y = -1; y <= 1; ++y) {
- for (int x = -1; x <= 1; ++x) {
- Triangle shifted = tri;
-
- for (int i = 0; i < 3; ++i) {
- shifted[i].x += x * shift;
- shifted[i].y += y * shift;
- }
-
- fixed_tests.push_back(shifted);
- }
- }
- }
- }
+ const float mid = 0.5f;
+ const float shift = 1.0f / FIXED_ONE;
+ const float size = 3.0f / FIXED_ONE;
+
+ Vector vv[] = {
+ Vector(mid, mid + size),
+ Vector(mid, mid - size),
+ };
+
+ Vector vh[] = {
+ Vector(mid - size, mid),
+ Vector(mid + size, mid),
+ };
+
+ Vector vm(mid, mid);
+
+ /* Loop through the 4 possible triangles */
+ for (int vy = 0; vy < 2; ++vy) {
+ for (int vx = 0; vx < 2; ++vx) {
+ Triangle tri;
+
+ tri[0] = vh[vx];
+ tri[1] = vv[vy];
+ tri[2] = vm;
+
+ /* Loop through the x and y shifts */
+ for (int y = -1; y <= 1; ++y) {
+ for (int x = -1; x <= 1; ++x) {
+ Triangle shifted = tri;
+
+ for (int i = 0; i < 3; ++i) {
+ shifted[i].x += x * shift;
+ shifted[i].y += y * shift;
+ }
+
+ fixed_tests.push_back(shifted);
+ }
+ }
+ }
+ }
}
@@ -530,34 +533,34 @@ void init_fixed_tests()
void
piglit_init(int argc, char **argv)
{
- uint32_t seed = 0xfacebeef ^ time(NULL);
-
- for (int i = 1; i < argc; ++i) {
- if (strcmp(argv[i], "-break_on_fail") == 0){
- break_on_fail = true;
- printf("Execution will stop on first fail\n");
- } else if (strcmp(argv[i], "-print_triangle") == 0){
- print_triangle = true;
- } else if (strcmp(argv[i], "-max_size") == 0){
- glGetIntegerv(GL_MAX_TEXTURE_SIZE, &fbo_width);
-
- fbo_height = fbo_width;
- piglit_width = fbo_width;
- piglit_height = fbo_height;
- } else if (strcmp(argv[i], "-use_fbo") == 0){
- use_fbo = true;
- printf("FBOs are in use\n");
- } else if (i + 1 < argc) {
- if (strcmp(argv[i], "-count") == 0) {
- random_test_count = strtoul(argv[++i], NULL, 0);
- } else if (strcmp(argv[i], "-seed") == 0) {
- seed = strtoul(argv[++i], NULL, 0);
- }
- }
- }
-
- printf("Random seed: 0x%08X\n", seed);
- mersenne.init(seed);
-
- init_fixed_tests();
+ uint32_t seed = 0xfacebeef ^ time(NULL);
+
+ for (int i = 1; i < argc; ++i) {
+ if (strcmp(argv[i], "-break_on_fail") == 0){
+ break_on_fail = true;
+ printf("Execution will stop on first fail\n");
+ } else if (strcmp(argv[i], "-print_triangle") == 0){
+ print_triangle = true;
+ } else if (strcmp(argv[i], "-max_size") == 0){
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, &fbo_width);
+
+ fbo_height = fbo_width;
+ piglit_width = fbo_width;
+ piglit_height = fbo_height;
+ } else if (strcmp(argv[i], "-use_fbo") == 0){
+ use_fbo = true;
+ printf("FBOs are in use\n");
+ } else if (i + 1 < argc) {
+ if (strcmp(argv[i], "-count") == 0) {
+ random_test_count = strtoul(argv[++i], NULL, 0);
+ } else if (strcmp(argv[i], "-seed") == 0) {
+ seed = strtoul(argv[++i], NULL, 0);
+ }
+ }
+ }
+
+ printf("Random seed: 0x%08X\n", seed);
+ mersenne.init(seed);
+
+ init_fixed_tests();
}