compute shaders!
parent
1d7e68f18c
commit
51320bfab1
|
@ -0,0 +1,19 @@
|
|||
#include "v4k.h"
|
||||
|
||||
int main() {
|
||||
// 75% sized, MSAAx2
|
||||
window_create(50, WINDOW_SQUARE);
|
||||
window_title(__FILE__);
|
||||
|
||||
unsigned comp = compute(vfs_read("shaders/compute-test.glsl"));
|
||||
texture_t tex = texture_create(512, 512, 4, 0, TEXTURE_LINEAR|TEXTURE_FLOAT);
|
||||
|
||||
while ( window_swap() && !input_down(KEY_ESC) ){
|
||||
shader_bind(comp);
|
||||
shader_float("t", (float)window_time());
|
||||
shader_image(&tex, 0, 0, -1, READ);
|
||||
dispatch(512, 512, 1);
|
||||
imageWriteBarrier();
|
||||
fullscreen_quad_rgb(tex, 2.2);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
layout (local_size_x = 10, local_size_y = 10, local_size_z = 1) in;
|
||||
|
||||
layout(rgba32f, binding = 0) uniform image2D imgOutput;
|
||||
|
||||
layout (location = 0) uniform float t; /** Time */
|
||||
|
||||
void main() {
|
||||
vec4 value = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
ivec2 texelCoord = ivec2(gl_GlobalInvocationID.xy);
|
||||
|
||||
float speed = 100;
|
||||
// the width of the texture
|
||||
float width = 1000;
|
||||
|
||||
value.x = mod(float(texelCoord.x) + t * speed, width) / (gl_NumWorkGroups.x * gl_WorkGroupSize.x);
|
||||
value.y = float(texelCoord.y)/(gl_NumWorkGroups.y*gl_WorkGroupSize.y);
|
||||
imageStore(imgOutput, texelCoord, value);
|
||||
}
|
|
@ -2230,6 +2230,7 @@ union { unsigned y, h; };
|
|||
union { unsigned z, d; };
|
||||
union { unsigned n, bpp; };
|
||||
handle id, unit;
|
||||
unsigned texel_type;
|
||||
unsigned flags;
|
||||
char* filename;
|
||||
bool transparent;
|
||||
|
@ -2358,6 +2359,16 @@ int texture_width;
|
|||
void shader_colormap(const char *name, colormap_t cm);
|
||||
unsigned shader_get_active();
|
||||
void shader_destroy(unsigned shader);
|
||||
enum ACCESS_MODE {
|
||||
READ,
|
||||
WRITE,
|
||||
READ_WRITE
|
||||
};
|
||||
unsigned compute(const char *cs);
|
||||
void dispatch(unsigned wx, unsigned wy, unsigned wz);
|
||||
void shader_image(texture_t *t, unsigned unit, unsigned level, int layer , unsigned access);
|
||||
void shader_image_unit(unsigned texture, unsigned unit, unsigned level, int layer , unsigned texel_type, unsigned access);
|
||||
void imageWriteBarrier();
|
||||
enum MESH_FLAGS {
|
||||
MESH_STATIC = 0,
|
||||
MESH_STREAM = 1,
|
||||
|
|
|
@ -16280,6 +16280,7 @@ typedef struct texture_t {
|
|||
union { unsigned z, d; };
|
||||
union { unsigned n, bpp; };
|
||||
handle id, unit;
|
||||
unsigned texel_type;
|
||||
unsigned flags;
|
||||
char* filename;
|
||||
bool transparent;
|
||||
|
@ -16481,6 +16482,19 @@ API void shader_colormap(const char *name, colormap_t cm);
|
|||
API unsigned shader_get_active();
|
||||
API void shader_destroy(unsigned shader);
|
||||
|
||||
// compute shaders
|
||||
enum ACCESS_MODE {
|
||||
READ,
|
||||
WRITE,
|
||||
READ_WRITE
|
||||
};
|
||||
|
||||
API unsigned compute(const char *cs);
|
||||
API void dispatch(unsigned wx, unsigned wy, unsigned wz);
|
||||
API void shader_image(texture_t *t, unsigned unit, unsigned level, int layer /* -1 to disable layered access */, unsigned access);
|
||||
API void shader_image_unit(unsigned texture, unsigned unit, unsigned level, int layer /* -1 to disable layered access */, unsigned texel_type, unsigned access);
|
||||
API void imageWriteBarrier();
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// meshes (@fixme: deprecate?)
|
||||
|
||||
|
@ -340094,6 +340108,56 @@ unsigned shader(const char *vs, const char *fs, const char *attribs, const char
|
|||
return program;
|
||||
}
|
||||
|
||||
unsigned compute(const char *cs){
|
||||
#if is(ems)
|
||||
return 0;
|
||||
#else
|
||||
PRINTF(/*"!"*/"Compiling compute shader\n");
|
||||
|
||||
cs = cs[0] == '#' && cs[1] == 'c' ? cs : va("#version 430 core\n%s", cs ? cs : "");
|
||||
|
||||
GLuint comp = shader_compile(GL_COMPUTE_SHADER, cs);
|
||||
GLuint program = 0;
|
||||
|
||||
if( comp ) {
|
||||
program = glCreateProgram();
|
||||
|
||||
glAttachShader(program, comp);
|
||||
|
||||
glLinkProgram(program);
|
||||
|
||||
GLint status = GL_FALSE, length;
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &status);
|
||||
#ifdef DEBUG_SHADER
|
||||
if (status != GL_FALSE && program == DEBUG_SHADER) {
|
||||
#else
|
||||
if (status == GL_FALSE) {
|
||||
#endif
|
||||
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
|
||||
char *buf = stack(length+1);
|
||||
glGetProgramInfoLog(program, length, NULL, buf);
|
||||
puts("--- cs:");
|
||||
shader_print(cs);
|
||||
}
|
||||
if (status == GL_FALSE) {
|
||||
PANIC("ERROR: shader(): Shader/program link: %s\n", buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
glDeleteShader(comp);
|
||||
}
|
||||
return program;
|
||||
#endif
|
||||
}
|
||||
|
||||
void dispatch(unsigned wx, unsigned wy, unsigned wz){
|
||||
glDispatchCompute(wx, wy, wz);
|
||||
}
|
||||
|
||||
void imageWriteBarrier(){
|
||||
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
|
||||
}
|
||||
|
||||
void shader_destroy(unsigned program){
|
||||
if( program == ~0u ) return;
|
||||
glDeleteProgram(program);
|
||||
|
@ -340126,6 +340190,13 @@ void shader_texture_unit(const char *sampler, unsigned id, unsigned unit) {
|
|||
glActiveTexture(GL_TEXTURE0 + unit);
|
||||
glBindTexture(GL_TEXTURE_2D, id);
|
||||
}
|
||||
void shader_image(texture_t *t, unsigned unit, unsigned level, int layer /* -1 to disable layered access */, unsigned access){
|
||||
shader_image_unit(t->id, unit, level, layer, t->texel_type, access);
|
||||
}
|
||||
void shader_image_unit(unsigned texture, unsigned unit, unsigned level, int layer, unsigned texel_type, unsigned access){
|
||||
GLenum gl_access[] = {GL_READ_ONLY, GL_WRITE_ONLY, GL_READ_WRITE};
|
||||
glBindImageTexture(unit, texture, level, layer!=-1, layer!=-1?layer:0, gl_access[access], texel_type);
|
||||
}
|
||||
|
||||
void shader_colormap(const char *name, colormap_t c ) {
|
||||
// assumes shader uses `struct { vec4 color; bool has_tex } name + sampler2D name_tex;`
|
||||
|
@ -340251,7 +340322,7 @@ unsigned texture_update(texture_t *t, unsigned w, unsigned h, unsigned n, const
|
|||
GLuint pixel_types[] = { GL_RED, GL_RED, GL_RG, GL_RGB, GL_RGBA, GL_R32F, GL_R32F, GL_RG32F, GL_RGB32F, GL_RGBA32F };
|
||||
GLenum pixel_storage = flags & TEXTURE_FLOAT ? GL_FLOAT : GL_UNSIGNED_BYTE;
|
||||
GLuint pixel_type = pixel_types[ n ];
|
||||
GLuint texel_type = pixel_types[ n + 5 * !!(flags & TEXTURE_FLOAT) ];
|
||||
GLuint texel_type = t->texel_type = pixel_types[ n + 5 * !!(flags & TEXTURE_FLOAT) ];
|
||||
GLenum wrap = GL_CLAMP_TO_EDGE;
|
||||
GLenum min_filter = GL_NEAREST, mag_filter = GL_NEAREST;
|
||||
// GLfloat color = (flags&7)/7.f, border_color[4] = { color, color, color, 1.f };
|
||||
|
@ -349463,9 +349534,14 @@ void window_hints(unsigned flags) {
|
|||
//glfwWindowHint( GLFW_COCOA_MENUBAR, GLFW_FALSE );
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
/* We need to explicitly ask for a 3.2 context on OS X */
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // osx
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); // osx, 2:#version150,3:330
|
||||
#else
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); //osx
|
||||
#endif
|
||||
|
|
|
@ -194,6 +194,56 @@ unsigned shader(const char *vs, const char *fs, const char *attribs, const char
|
|||
return program;
|
||||
}
|
||||
|
||||
unsigned compute(const char *cs){
|
||||
#if is(ems)
|
||||
return 0;
|
||||
#else
|
||||
PRINTF(/*"!"*/"Compiling compute shader\n");
|
||||
|
||||
cs = cs[0] == '#' && cs[1] == 'c' ? cs : va("#version 430 core\n%s", cs ? cs : "");
|
||||
|
||||
GLuint comp = shader_compile(GL_COMPUTE_SHADER, cs);
|
||||
GLuint program = 0;
|
||||
|
||||
if( comp ) {
|
||||
program = glCreateProgram();
|
||||
|
||||
glAttachShader(program, comp);
|
||||
|
||||
glLinkProgram(program);
|
||||
|
||||
GLint status = GL_FALSE, length;
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &status);
|
||||
#ifdef DEBUG_SHADER
|
||||
if (status != GL_FALSE && program == DEBUG_SHADER) {
|
||||
#else
|
||||
if (status == GL_FALSE) {
|
||||
#endif
|
||||
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
|
||||
char *buf = stack(length+1);
|
||||
glGetProgramInfoLog(program, length, NULL, buf);
|
||||
puts("--- cs:");
|
||||
shader_print(cs);
|
||||
}
|
||||
if (status == GL_FALSE) {
|
||||
PANIC("ERROR: shader(): Shader/program link: %s\n", buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
glDeleteShader(comp);
|
||||
}
|
||||
return program;
|
||||
#endif
|
||||
}
|
||||
|
||||
void dispatch(unsigned wx, unsigned wy, unsigned wz){
|
||||
glDispatchCompute(wx, wy, wz);
|
||||
}
|
||||
|
||||
void imageWriteBarrier(){
|
||||
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
|
||||
}
|
||||
|
||||
void shader_destroy(unsigned program){
|
||||
if( program == ~0u ) return;
|
||||
glDeleteProgram(program);
|
||||
|
@ -226,6 +276,13 @@ void shader_texture_unit(const char *sampler, unsigned id, unsigned unit) {
|
|||
glActiveTexture(GL_TEXTURE0 + unit);
|
||||
glBindTexture(GL_TEXTURE_2D, id);
|
||||
}
|
||||
void shader_image(texture_t *t, unsigned unit, unsigned level, int layer /* -1 to disable layered access */, unsigned access){
|
||||
shader_image_unit(t->id, unit, level, layer, t->texel_type, access);
|
||||
}
|
||||
void shader_image_unit(unsigned texture, unsigned unit, unsigned level, int layer, unsigned texel_type, unsigned access){
|
||||
GLenum gl_access[] = {GL_READ_ONLY, GL_WRITE_ONLY, GL_READ_WRITE};
|
||||
glBindImageTexture(unit, texture, level, layer!=-1, layer!=-1?layer:0, gl_access[access], texel_type);
|
||||
}
|
||||
|
||||
void shader_colormap(const char *name, colormap_t c ) {
|
||||
// assumes shader uses `struct { vec4 color; bool has_tex } name + sampler2D name_tex;`
|
||||
|
@ -351,7 +408,7 @@ unsigned texture_update(texture_t *t, unsigned w, unsigned h, unsigned n, const
|
|||
GLuint pixel_types[] = { GL_RED, GL_RED, GL_RG, GL_RGB, GL_RGBA, GL_R32F, GL_R32F, GL_RG32F, GL_RGB32F, GL_RGBA32F };
|
||||
GLenum pixel_storage = flags & TEXTURE_FLOAT ? GL_FLOAT : GL_UNSIGNED_BYTE;
|
||||
GLuint pixel_type = pixel_types[ n ];
|
||||
GLuint texel_type = pixel_types[ n + 5 * !!(flags & TEXTURE_FLOAT) ];
|
||||
GLuint texel_type = t->texel_type = pixel_types[ n + 5 * !!(flags & TEXTURE_FLOAT) ];
|
||||
GLenum wrap = GL_CLAMP_TO_EDGE;
|
||||
GLenum min_filter = GL_NEAREST, mag_filter = GL_NEAREST;
|
||||
// GLfloat color = (flags&7)/7.f, border_color[4] = { color, color, color, 1.f };
|
||||
|
|
|
@ -125,6 +125,7 @@ typedef struct texture_t {
|
|||
union { unsigned z, d; };
|
||||
union { unsigned n, bpp; };
|
||||
handle id, unit;
|
||||
unsigned texel_type;
|
||||
unsigned flags;
|
||||
char* filename;
|
||||
bool transparent;
|
||||
|
@ -326,6 +327,19 @@ API void shader_colormap(const char *name, colormap_t cm);
|
|||
API unsigned shader_get_active();
|
||||
API void shader_destroy(unsigned shader);
|
||||
|
||||
// compute shaders
|
||||
enum ACCESS_MODE {
|
||||
READ,
|
||||
WRITE,
|
||||
READ_WRITE
|
||||
};
|
||||
|
||||
API unsigned compute(const char *cs);
|
||||
API void dispatch(unsigned wx, unsigned wy, unsigned wz);
|
||||
API void shader_image(texture_t *t, unsigned unit, unsigned level, int layer /* -1 to disable layered access */, unsigned access);
|
||||
API void shader_image_unit(unsigned texture, unsigned unit, unsigned level, int layer /* -1 to disable layered access */, unsigned texel_type, unsigned access);
|
||||
API void imageWriteBarrier();
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// meshes (@fixme: deprecate?)
|
||||
|
||||
|
|
|
@ -169,9 +169,14 @@ void window_hints(unsigned flags) {
|
|||
//glfwWindowHint( GLFW_COCOA_MENUBAR, GLFW_FALSE );
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
/* We need to explicitly ask for a 3.2 context on OS X */
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // osx
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); // osx, 2:#version150,3:330
|
||||
#else
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); //osx
|
||||
#endif
|
||||
|
|
64
engine/v4k.c
64
engine/v4k.c
|
@ -11108,6 +11108,56 @@ unsigned shader(const char *vs, const char *fs, const char *attribs, const char
|
|||
return program;
|
||||
}
|
||||
|
||||
unsigned compute(const char *cs){
|
||||
#if is(ems)
|
||||
return 0;
|
||||
#else
|
||||
PRINTF(/*"!"*/"Compiling compute shader\n");
|
||||
|
||||
cs = cs[0] == '#' && cs[1] == 'c' ? cs : va("#version 430 core\n%s", cs ? cs : "");
|
||||
|
||||
GLuint comp = shader_compile(GL_COMPUTE_SHADER, cs);
|
||||
GLuint program = 0;
|
||||
|
||||
if( comp ) {
|
||||
program = glCreateProgram();
|
||||
|
||||
glAttachShader(program, comp);
|
||||
|
||||
glLinkProgram(program);
|
||||
|
||||
GLint status = GL_FALSE, length;
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &status);
|
||||
#ifdef DEBUG_SHADER
|
||||
if (status != GL_FALSE && program == DEBUG_SHADER) {
|
||||
#else
|
||||
if (status == GL_FALSE) {
|
||||
#endif
|
||||
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
|
||||
char *buf = stack(length+1);
|
||||
glGetProgramInfoLog(program, length, NULL, buf);
|
||||
puts("--- cs:");
|
||||
shader_print(cs);
|
||||
}
|
||||
if (status == GL_FALSE) {
|
||||
PANIC("ERROR: shader(): Shader/program link: %s\n", buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
glDeleteShader(comp);
|
||||
}
|
||||
return program;
|
||||
#endif
|
||||
}
|
||||
|
||||
void dispatch(unsigned wx, unsigned wy, unsigned wz){
|
||||
glDispatchCompute(wx, wy, wz);
|
||||
}
|
||||
|
||||
void imageWriteBarrier(){
|
||||
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
|
||||
}
|
||||
|
||||
void shader_destroy(unsigned program){
|
||||
if( program == ~0u ) return;
|
||||
glDeleteProgram(program);
|
||||
|
@ -11140,6 +11190,13 @@ void shader_texture_unit(const char *sampler, unsigned id, unsigned unit) {
|
|||
glActiveTexture(GL_TEXTURE0 + unit);
|
||||
glBindTexture(GL_TEXTURE_2D, id);
|
||||
}
|
||||
void shader_image(texture_t *t, unsigned unit, unsigned level, int layer /* -1 to disable layered access */, unsigned access){
|
||||
shader_image_unit(t->id, unit, level, layer, t->texel_type, access);
|
||||
}
|
||||
void shader_image_unit(unsigned texture, unsigned unit, unsigned level, int layer, unsigned texel_type, unsigned access){
|
||||
GLenum gl_access[] = {GL_READ_ONLY, GL_WRITE_ONLY, GL_READ_WRITE};
|
||||
glBindImageTexture(unit, texture, level, layer!=-1, layer!=-1?layer:0, gl_access[access], texel_type);
|
||||
}
|
||||
|
||||
void shader_colormap(const char *name, colormap_t c ) {
|
||||
// assumes shader uses `struct { vec4 color; bool has_tex } name + sampler2D name_tex;`
|
||||
|
@ -11265,7 +11322,7 @@ unsigned texture_update(texture_t *t, unsigned w, unsigned h, unsigned n, const
|
|||
GLuint pixel_types[] = { GL_RED, GL_RED, GL_RG, GL_RGB, GL_RGBA, GL_R32F, GL_R32F, GL_RG32F, GL_RGB32F, GL_RGBA32F };
|
||||
GLenum pixel_storage = flags & TEXTURE_FLOAT ? GL_FLOAT : GL_UNSIGNED_BYTE;
|
||||
GLuint pixel_type = pixel_types[ n ];
|
||||
GLuint texel_type = pixel_types[ n + 5 * !!(flags & TEXTURE_FLOAT) ];
|
||||
GLuint texel_type = t->texel_type = pixel_types[ n + 5 * !!(flags & TEXTURE_FLOAT) ];
|
||||
GLenum wrap = GL_CLAMP_TO_EDGE;
|
||||
GLenum min_filter = GL_NEAREST, mag_filter = GL_NEAREST;
|
||||
// GLfloat color = (flags&7)/7.f, border_color[4] = { color, color, color, 1.f };
|
||||
|
@ -20477,9 +20534,14 @@ void window_hints(unsigned flags) {
|
|||
//glfwWindowHint( GLFW_COCOA_MENUBAR, GLFW_FALSE );
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
/* We need to explicitly ask for a 3.2 context on OS X */
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // osx
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); // osx, 2:#version150,3:330
|
||||
#else
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); //osx
|
||||
#endif
|
||||
|
|
14
engine/v4k.h
14
engine/v4k.h
|
@ -2363,6 +2363,7 @@ typedef struct texture_t {
|
|||
union { unsigned z, d; };
|
||||
union { unsigned n, bpp; };
|
||||
handle id, unit;
|
||||
unsigned texel_type;
|
||||
unsigned flags;
|
||||
char* filename;
|
||||
bool transparent;
|
||||
|
@ -2564,6 +2565,19 @@ API void shader_colormap(const char *name, colormap_t cm);
|
|||
API unsigned shader_get_active();
|
||||
API void shader_destroy(unsigned shader);
|
||||
|
||||
// compute shaders
|
||||
enum ACCESS_MODE {
|
||||
READ,
|
||||
WRITE,
|
||||
READ_WRITE
|
||||
};
|
||||
|
||||
API unsigned compute(const char *cs);
|
||||
API void dispatch(unsigned wx, unsigned wy, unsigned wz);
|
||||
API void shader_image(texture_t *t, unsigned unit, unsigned level, int layer /* -1 to disable layered access */, unsigned access);
|
||||
API void shader_image_unit(unsigned texture, unsigned unit, unsigned level, int layer /* -1 to disable layered access */, unsigned texel_type, unsigned access);
|
||||
API void imageWriteBarrier();
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// meshes (@fixme: deprecate?)
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue