shithub: tinygl

Download patch

ref: afade9570e1da804507622248a666d1e51f51671
parent: 6a213254b9ed856592b4a024508ffdc80cceb534
author: David <gek@katherine>
date: Sun Feb 21 20:32:21 EST 2021

Improved runtime and compiletime compatibility tests

--- a/README.md
+++ b/README.md
@@ -1,12 +1,29 @@
 # TinyGL- New and Improved
 
-A rework of Fabrice Bellard's TinyGL (still compiling with -std=c99) to be
+A major overhaul of Fabrice Bellard's TinyGL (still compiling with -std=c99) to be
 more useful as a software rasterizer.
 
-Tightly tweaked for performance.
+## Tightly tweaked for performance
 
-Valgrind'd for memory leaks in the demos.
+On a single thread on an i7-6700 (Skylake, 2015),
+the standard "gears" demo runs at a higher framerate than glxgears on Mesa using a Ryzen 3900x (2019)
+(NOTE: TinyGL Compared without SDL overhead)
 
+I think I can safely say, this is the fastest single-threaded FOSS software GL implementation in existence.
+
+It's probably also the most portable
+
+## Incredibly portable
+
+TinyGL is written in pure C99, and requires very few functions from the C standard library, it doesn't even require malloc and free
+(The calls are aliased to gl_malloc() and gl_free(), which you can replace with your own memory management model if you desire)
+
+If you are unsure if your target platform can support TinyGL, compile it with the buildtime and runtime tests enabled (They are, by default)
+
+if you get a TGL_BUILDT error, then you've failed the buildtime test.
+
+if you try to initialize the library and you get a crash with a print to standard out "TINYGL_FAILED_RUNTIME_COMPAT_TEST" then you've failed the runtime test.
+
 Without Polygon Stipple:
 
 ![GIF Video of demo](capture.gif)
@@ -245,6 +262,8 @@
 GL_FLAT, causing the hello world triangle to look rather...
 wrong. Additionally, per vertex color is just cool.
 
+The whole library was filled with memory leaks and read-past-by-one type errors, and they have been corrected.
+
 ## Notorious bugs from the original that have been fixed
 
 * GLParam is a union of float, int, uint, and void* which is assumed to be 32 bit... but isn't on 64 bit systems
@@ -256,6 +275,8 @@
 * Little endian was assumed in a thousand places in the code
 
 * Non-normalized position was used for lights at infinity.
+
+* Lack of error checking functionality
 
 * Insert unknown bugs here.
 
--- a/config.mk
+++ b/config.mk
@@ -2,7 +2,7 @@
 # C compiler
 
 CC= gcc
-CFLAGS= -Wall -O3 -g -std=c99 -Wno-undef -march=native -DNDEBUG
+CFLAGS= -Wall -O3 -g -std=c99 -Wno-undef -DNDEBUG
 #CFLAGS= -Wall -O1 -g -std=c99 -Wno-undef -DNDEBUG
 LFLAGS=
 
--- a/include/GL/gl.h
+++ b/include/GL/gl.h
@@ -733,6 +733,9 @@
 //#error "GLbyte is wrong size!"
 //#endif
 extern char TGL_BUILDT_GLbyte[ 1-2*(sizeof(GLbyte) != 1)];
+#ifndef __STDC_IEC_559__
+#error C99 Compiler Using Non-Compliant Float Type! Compatibility not guaranteed.
+#endif
 //extern char __BUILDT_error[ 1-2*(sizeof(GLbyte) != 4)];
 extern char TGL_BUILDT_GLshort[ 1-2*(sizeof(GLshort) != 2)];
 extern char TGL_BUILDT_GLint[ 1-2*(sizeof(GLint) != 4)];
--- a/src/init.c
+++ b/src/init.c
@@ -75,15 +75,17 @@
 			gl_free(s->buffers[i]);
 		}
 	}
+	gl_free(s->buffers);
 }
 
 #if TGL_FEATURE_TINYGL_RUNTIME_COMPAT_TEST == 1
 
-#define TGL_RUNT_UNION_CAST(i) ((union{GLuint l; GLfloat f;}){i})
+#define TGL_RUNT_UNION_CAST(i) ((union{GLuint l; GLint ii; GLfloat f;}){i})
+#define TGL_FLOAT_ERR(a,b) ((a-b)/b)
 int TinyGLRuntimeCompatibilityTest(){
-	GLfloat t = -0;
+	GLfloat t = -0, tf2;
 	GLint t2 = 1<<31;
-	if(TGL_RUNT_UNION_CAST(t2).f != -0)
+	if(TGL_RUNT_UNION_CAST(t2).f != t)
 		return 1;
 	t2 = 3212836864;
 	t = -1;
@@ -98,6 +100,37 @@
 	if((GLushort)65280>>8 != 255) return 1;
 	if(((GLshort)255<<8) != 65280) return 1;
 	if((GLshort)65280>>8 != -1) return 1;
+#if TGL_FEATURE_FISR == 1
+	t = fastInvSqrt(37);
+	tf2 = 1.0/sqrt(37);
+	if(TGL_FLOAT_ERR(t,tf2) > 0.05) return 1;
+	t = fastInvSqrt(59);
+	tf2 = 1.0/sqrt(59);
+	if(TGL_FLOAT_ERR(t,tf2) > 0.05) return 1;
+	t = fastInvSqrt(1023);
+	tf2 = 1.0/sqrt(1023);
+	if(TGL_FLOAT_ERR(t,tf2) > 0.05) return 1;
+
+	t = fastInvSqrt(10000);
+	tf2 = 1.0/sqrt(10000);
+	if(TGL_FLOAT_ERR(t,tf2) > 0.05) return 1;
+#endif
+	{	//MEMCPY COMPATIBILITY TEST
+		GLuint buf1[10];
+		GLuint buf2[10];
+		for(int i = 0; i < 10; i++) buf1[i] = (1023<<i) + i + i%-1;
+		for(int i = 0; i < 10; i++) buf2[i] = (14<<i) + i + i%-4;
+		memcpy(buf1,buf2,10*4);
+		for(int i = 0; i < 10; i++) if(buf2[i] != buf1[i]) return 1;
+	}
+	if(sizeof(void*) < 4) return 1;
+	//ZALLOC TEST
+	for(int i = 0; i < 10; i++){
+		GLubyte* data = gl_zalloc(1024); //A kilobyte.
+		if(!data) return 1;
+		for(int i = 0; i <1024; i++) if(data[i] != 0) return 1;
+		gl_free(data);
+	}
 	return 0;
 }
 #endif