From 3558254a2400ae27a2e147681ba0848c1a1b19a1 Mon Sep 17 00:00:00 2001 From: Eleni Maria Stea Date: Thu, 8 Mar 2018 12:37:22 +0200 Subject: [PATCH 1/1] test program that renders a quad using spirv shaders, used for debugging SPIR-V at work --- Makefile | 21 +++++ data/pixel2.f.glsl | 11 +++ data/spirv/pixel.spv | Bin 0 -> 1244 bytes data/spirv/vertex.spv | Bin 0 -> 828 bytes data/test.f.glsl | 16 ++++ data/test.v.glsl | 10 ++ src/main.cc | 249 +++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 307 insertions(+) create mode 100644 Makefile create mode 100644 data/pixel2.f.glsl create mode 100644 data/spirv/pixel.spv create mode 100644 data/spirv/vertex.spv create mode 100644 data/test.f.glsl create mode 100644 data/test.v.glsl create mode 100644 src/main.cc diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..210b083 --- /dev/null +++ b/Makefile @@ -0,0 +1,21 @@ +src = $(wildcard src/*.cc) +obj = $(src:.cc=.o) +bin = glquad + +GLSLANG = glslangValidator + +CXXFLAGS = -pedantic -Wall -g +LDFLAGS = -lGL -lGLU -lglut -lGLEW + +$(bin): $(obj) data/spirv/vertex.spv data/spirv/pixel.spv + $(CXX) -o $@ $(obj) $(LDFLAGS) + +data/spirv/vertex.spv: data/test.v.glsl + $(GLSLANG) -G -V -S vert -o $@ $< + +data/spirv/pixel.spv: data/test.f.glsl data/pixel2.f.glsl + $(GLSLANG) -l -G -V -S frag -o $@ $^ + +.PHONY: clean +clean: + rm -f $(obj) $(bin) data/spirv/* diff --git a/data/pixel2.f.glsl b/data/pixel2.f.glsl new file mode 100644 index 0000000..7357abd --- /dev/null +++ b/data/pixel2.f.glsl @@ -0,0 +1,11 @@ +#version 450 + +vec4 ambient(float num, vec4 c) +{ + float r = min(c.r + num, 1.0); + float g = min(c.g + num, 1.0); + float b = min(c.b + num, 1.0); + float a = 1.0; + + return vec4(r, g, b, a); +} diff --git a/data/spirv/pixel.spv b/data/spirv/pixel.spv new file mode 100644 index 0000000000000000000000000000000000000000..46a1aaeee28c5dc019d9056ade6e06ad939dcaa1 GIT binary patch literal 1244 zcmY+C+fI{F5QPW+7EuvI1U%b{3JO**;2{kfuejmD#0M}1#gN$6VDVaC&1-xgZ!~`2 zrW0$M$*eWA_8j*9tMR2X5o1x0$=Hh1-)xK%i8vn<#qaFC-EDmtyl-u8t*e-hstDE0 zpsC@tZs)LP;$pF?#3+usqGH4k4%CT`YU`Z8K(5o>JN(catQ>5#zaDJ1(N*-1=pA

@(iE!BfX*1rQbo_q;B+V3u0jq&VfpX_Ho`?Lkq1O;w;=;CyZW2B9+xk_#1f6f) z6=yljoik_d%$+S3j!I@L=GmI<+uUka5Mx$0KlR;Szt@>2ubs2=Qxp{|rb0AT)nTi` z`@qGV*M%LSDHQb;ASBGU7n-2a`%xNKe%Z!h=<`K$1BKvMA0JWXn2$HivPrtxylrvx ze3XKDvGUw4IP!4II%a{RZ(hq8j=gl1;XZWqqBp&;x>)!_X{h1c)XA3*gqHOBk!j3b zfnxp)TKKChX5VnfimBZY%)W2)IDf~9s;Ju((7*%E4b^VR2LeVdaYf+02a2om+z;2* ziFf7mkps+FlV=|C%t*}s;pkJB4+QR|5Am*mQQwd!m%oviy}@1R|F9?afpO=r7*GC2 f5xd}h*HTd55~#hCg5B*2%tAl(#AyC>`=#&?1>rRH literal 0 HcmV?d00001 diff --git a/data/test.f.glsl b/data/test.f.glsl new file mode 100644 index 0000000..3f827db --- /dev/null +++ b/data/test.f.glsl @@ -0,0 +1,16 @@ +#version 450 + +//layout(location = 1) in vec4 vcol; +layout(location = 0) out vec4 out_color; +const vec4 vcol = vec4(0.1, 1.0, 1.0, 1.0); + +/*layout(std140, binding = 0) uniform Ubo { + vec4 color; +} u;*/ + +vec4 ambient(float num, vec4 c); + +void main() +{ + out_color = ambient(0.1, vcol);// + u.color); +} diff --git a/data/test.v.glsl b/data/test.v.glsl new file mode 100644 index 0000000..a2fd8aa --- /dev/null +++ b/data/test.v.glsl @@ -0,0 +1,10 @@ +#version 450 + +layout(location = 0) in vec4 vertex; +layout(location = 1) out vec4 vcol; + +void main() +{ + vcol = vec4(1.0, 0.0, 0.0, 1.0); + gl_Position = vertex; +} diff --git a/src/main.cc b/src/main.cc new file mode 100644 index 0000000..5042980 --- /dev/null +++ b/src/main.cc @@ -0,0 +1,249 @@ +#include + +#include +#include +#include + +#include + +#include +#include +#include + +#define VERTEX_LOC 0 + +struct Ubo { + float color[4] = {0, 1, 0, 1}; +}; + +static bool init(); +static void cleanup(); + +static void display(); +static void keydown(unsigned char key, int x, int y); +static unsigned int load_shader(const char *fname, int type); +static unsigned int create_program(const char *vfname, const char *pfname); +static bool link_program(unsigned int prog); + +static const char *vs_path = "data/spirv/vertex.spv"; +static const char *fs_path = "data/spirv/pixel.spv"; + +static unsigned int sprog; +static unsigned int vbo; +static unsigned int vao; + +static float vertices[] = { + -0.5, -0.5, + 0.5, -0.5, + 0.5, 0.5, + + -0.5, -0.5, + 0.5, 0.5, + -0.5, 0.5 +}; + +static int num_vertices = 6; +static Ubo test_ubo; +static unsigned int ubo; + +int main(int argc, char **argv) +{ + glutInitContextProfile(GLUT_CORE_PROFILE); + glutInitContextVersion(4, 5); + + glutInit(&argc, argv); + + glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); + glutInitWindowSize(800, 600); + glutCreateWindow("gltest"); + + + glClear(GL_COLOR_BUFFER_BIT); + + glutDisplayFunc(display); + glutKeyboardFunc(keydown); + + if(!init()) + return 1; + + atexit(cleanup); + glutMainLoop(); +} + +static bool init() +{ + glewInit(); + + glClearColor(0.0, 0.0, 1.0, 1.0); + + glGenBuffers(1, &ubo); + glBindBuffer(GL_UNIFORM_BUFFER, ubo); + glBufferData(GL_UNIFORM_BUFFER, sizeof test_ubo, &test_ubo, GL_STREAM_DRAW); + + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + + glGenBuffers(1, &vbo); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof vertices, vertices, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + if(!(sprog = create_program(vs_path, fs_path))) { + fprintf(stderr, "Failed to create shader program.\n"); + return false; + } + + glUseProgram(sprog); + + assert(glGetError() == GL_NO_ERROR); + return true; +} + +static void display() +{ + glEnableVertexAttribArray(VERTEX_LOC); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + + glVertexAttribPointer(VERTEX_LOC, 2, GL_FLOAT, GL_FALSE, 0, 0); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + + glBindBuffer(GL_UNIFORM_BUFFER, ubo); + glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof test_ubo, &test_ubo); + glBindBufferBase(GL_UNIFORM_BUFFER, 0, ubo); + + glDrawArrays(GL_TRIANGLES, 0, num_vertices); + + assert(glGetError() == GL_NO_ERROR); + + glutSwapBuffers(); +} + +static void keydown(unsigned char key, int /*x*/, int /*y*/) +{ + switch(key) { + case 27: + exit(0); + } +} + +static unsigned int create_program(const char *vfname, const char *pfname) +{ + unsigned int vs, ps; + unsigned int prog; + + if(!(vs = load_shader(vfname, GL_VERTEX_SHADER))) + return false; + if(!(ps = load_shader(pfname, GL_FRAGMENT_SHADER))) { + glDeleteShader(vs); + return false; + } + + prog = glCreateProgram(); + glAttachShader(prog, vs); + glAttachShader(prog, ps); + + if(!link_program(prog)) { + glDeleteShader(vs); + glDeleteShader(ps); + glDeleteProgram(prog); + return false; + } + + glDetachShader(prog, vs); + glDetachShader(prog, ps); + + return prog; +} + +static bool link_program(unsigned int prog) +{ + int status, loglen; + char *buf; + + glLinkProgram(prog); + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if(status) { + printf("successfully linked shader program\n"); + } else { + printf("failed to link shader program\n"); + } + + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &loglen); + if(loglen > 0 && (buf = (char*)malloc(loglen + 1))) { + glGetProgramInfoLog(prog, loglen, 0, buf); + buf[loglen] = 0; + printf("%s\n", buf); + free(buf); + } + + return status ? true : false; +} + +unsigned int load_shader(const char *fname, int type) +{ + unsigned int sdr; + unsigned int fsz; + char *buf; + FILE *fp; + int status, loglen; + + if(!(fp = fopen(fname, "rb"))) { + fprintf(stderr, "failed to open shader: %s\n", fname); + return 0; + } + fseek(fp, 0, SEEK_END); + fsz = ftell(fp); + rewind(fp); + + if(!(buf = (char*)malloc(fsz + 1))) { + fprintf(stderr, "failed to allocate %d bytes\n", fsz + 1); + fclose(fp); + return 0; + } + if(fread(buf, 1, fsz, fp) < fsz) { + fprintf(stderr, "failed to read shader: %s\n", fname); + free(buf); + fclose(fp); + return 0; + } + buf[fsz] = 0; + fclose(fp); + + sdr = glCreateShader(type); + + glShaderBinary(1, &sdr, GL_SHADER_BINARY_FORMAT_SPIR_V_ARB, buf, fsz); + glSpecializeShaderARB(sdr, "main", 0, 0, 0); + + free(buf); + + glGetShaderiv(sdr, GL_COMPILE_STATUS, &status); + if(status) { + printf("successfully compiled shader: %s\n", fname); + } else { + printf("failed to compile shader: %s\n", fname); + } + + glGetShaderiv(sdr, GL_INFO_LOG_LENGTH, &loglen); + if(loglen > 0 && (buf = (char*)malloc(loglen + 1))) { + glGetShaderInfoLog(sdr, loglen, 0, buf); + buf[loglen] = 0; + printf("%s\n", buf); + free(buf); + } + + if(!status) { + glDeleteShader(sdr); + return 0; + } + + return sdr; +} + +static void cleanup() +{ + glDeleteVertexArrays(1, &vao); + glDeleteBuffers(1, &vbo); + glDeleteBuffers(1, &ubo); +} -- 1.7.10.4