Created
May 10, 2019 21:39
-
-
Save tildearrow/dce93cc1116cabea3bae15397a594e6c to your computer and use it in GitHub Desktop.
Mesa VSync bug test program
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// as seen on https://gfycat.com/UniqueSpiritedApatosaur | |
// compile with: | |
// g++ -o triangle main.cpp -lGL -lGLEW -lglfw | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <math.h> | |
#include <unistd.h> | |
#include <time.h> | |
#include <GL/glew.h> | |
#include <GL/glxew.h> | |
#define GLFW_EXPOSE_NATIVE_X11 | |
#define GLFW_EXPOSE_NATIVE_GLX | |
#include <GLFW/glfw3.h> | |
#include <GLFW/glfw3native.h> | |
#include <X11/Xlib.h> | |
double curVPos; | |
int frameCount; | |
bool useOML; | |
int pc1, pc2; | |
long cust, cmsc, csbc; | |
Display* disp; | |
GLXWindow gxw; | |
float v[6]={ | |
0.0f, 0.5f, // Vertex 1 (X, Y) | |
0.5f, -0.5f, // Vertex 2 (X, Y) | |
-0.5f, -0.5f // Vertex 3 (X, Y) | |
}; | |
const char* vertS="\ | |
#version 150\n\ | |
in vec2 position;\n\ | |
void main() {\n\ | |
gl_Position=vec4(position, 0.0, 1.0);\n\ | |
}"; | |
const char* fragS="\ | |
#version 150\n\ | |
out vec4 outColor;\n\ | |
void main() {\n\ | |
outColor=vec4(1.0, 1.0, 1.0, 1.0);\n\ | |
}"; | |
long long perfCount() { | |
#ifdef _WIN32 | |
LARGE_INTEGER temp, prec; | |
QueryPerformanceCounter(&temp); | |
QueryPerformanceFrequency(&prec); | |
return temp.QuadPart*(1000000000/prec.QuadPart); | |
#else | |
#ifdef __MACH__ | |
return mach_absolute_time(); | |
#else | |
struct timespec temp; | |
clock_gettime(CLOCK_MONOTONIC,&temp); | |
return (temp.tv_sec*1000000000)+temp.tv_nsec; | |
#endif | |
#endif | |
} | |
char* load(const char* name) { | |
char* ret; | |
size_t siz; | |
FILE* f; | |
f=fopen(name,"r"); | |
if (f==NULL) { | |
return NULL; | |
} | |
fseek(f,0,SEEK_END); | |
siz=ftell(f); | |
ret=new char[siz+1]; | |
fseek(f,0,SEEK_SET); | |
fread(ret,1,siz,f); | |
ret[siz]=0; | |
fclose(f); | |
return ret; | |
} | |
int main(int argc, char** argv) { | |
GLFWwindow* window; | |
GLuint vertexBuffer; | |
// IF UNDER MESA, CHANGE THIS TO "true" TO SIMULATE | |
// HOW IT SHOULD REALLY BEHAVE | |
useOML=false; | |
/* Initialize the library */ | |
if (!glfwInit()) { | |
printf("no init\n"); | |
return 1; | |
} | |
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); | |
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); | |
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); | |
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); | |
/* Create a windowed mode window and its OpenGL context */ | |
window = glfwCreateWindow(512, 512, "Hello World", NULL, NULL); | |
if (!window) { | |
glfwTerminate(); | |
return 1; | |
} | |
disp=glfwGetX11Display(); | |
gxw=glfwGetGLXWindow(window); | |
/* Make the window's context current */ | |
glfwMakeContextCurrent(window); | |
glewExperimental=1; | |
glewInit(); | |
if (GLXEW_OML_sync_control) { | |
printf("good. good!\n"); | |
} | |
glGenBuffers(1,&vertexBuffer); | |
glBindBuffer(GL_ARRAY_BUFFER,vertexBuffer); | |
glBufferData(GL_ARRAY_BUFFER,sizeof(v),v,GL_DYNAMIC_DRAW); | |
GLint status; | |
GLuint vertexShader=glCreateShader(GL_VERTEX_SHADER); | |
glShaderSource(vertexShader, 1, &vertS, NULL); | |
glCompileShader(vertexShader); | |
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &status); | |
if (!status) { | |
printf("can't load v\n"); exit(1); | |
} | |
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); | |
glShaderSource(fragmentShader, 1, &fragS, NULL); | |
glCompileShader(fragmentShader); | |
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &status); | |
if (!status) { | |
printf("can't load f\n"); exit(1); | |
} | |
GLuint shaderProgram = glCreateProgram(); | |
glAttachShader(shaderProgram, vertexShader); | |
glAttachShader(shaderProgram, fragmentShader); | |
//glBindFragDataLocation(shaderProgram, 0, "outColor"); | |
glLinkProgram(shaderProgram); | |
glUseProgram(shaderProgram); | |
GLuint vao; | |
glGenVertexArrays(1, &vao); | |
glBindVertexArray(vao); | |
GLint posAttrib=glGetAttribLocation(shaderProgram, "position"); | |
glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0); | |
glEnableVertexAttribArray(posAttrib); | |
/* set */ | |
//glfwSwapInterval(0); | |
glfwSwapInterval(1); | |
/* Loop until the user closes the window */ | |
while (!glfwWindowShouldClose(window)) { | |
/* Render here */ | |
glClear(GL_COLOR_BUFFER_BIT); | |
curVPos+=0.005; | |
curVPos-=(int)curVPos; | |
for (int i=0; i<3; i++) { | |
v[i*2]=cos(((i*0.33333333333)+curVPos)*2*M_PI)*0.5; | |
v[i*2+1]=sin(((i*0.33333333333)+curVPos)*2*M_PI)*0.5; | |
} | |
glBindBuffer(GL_ARRAY_BUFFER,vertexBuffer); | |
glBufferData(GL_ARRAY_BUFFER,sizeof(v),v,GL_DYNAMIC_DRAW); | |
glDrawArrays(GL_TRIANGLES, 0, 3); | |
frameCount++; | |
pc2=pc1; | |
pc1=perfCount(); | |
printf("pc for %d: %d\n",frameCount,(pc1-pc2)/1000); | |
glXGetSyncValuesOML(disp,gxw,&cust,&cmsc,&csbc); | |
printf("%d %d %d\n",cust,cmsc,csbc); | |
if ((frameCount%30)==0) { | |
printf("sleeping 500ms...\n"); | |
usleep(500000); | |
} | |
/* Swap front and back buffers */ | |
if (useOML) glXWaitForMscOML(disp,gxw,csbc+1,1,0,&cust,&cmsc,&csbc); | |
glfwSwapBuffers(window); | |
/* Poll for and process events */ | |
glfwPollEvents(); | |
} | |
glfwTerminate(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment