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 z, d; };
|
||||||
union { unsigned n, bpp; };
|
union { unsigned n, bpp; };
|
||||||
handle id, unit;
|
handle id, unit;
|
||||||
|
unsigned texel_type;
|
||||||
unsigned flags;
|
unsigned flags;
|
||||||
char* filename;
|
char* filename;
|
||||||
bool transparent;
|
bool transparent;
|
||||||
|
@ -2358,6 +2359,16 @@ int texture_width;
|
||||||
void shader_colormap(const char *name, colormap_t cm);
|
void shader_colormap(const char *name, colormap_t cm);
|
||||||
unsigned shader_get_active();
|
unsigned shader_get_active();
|
||||||
void shader_destroy(unsigned shader);
|
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 {
|
enum MESH_FLAGS {
|
||||||
MESH_STATIC = 0,
|
MESH_STATIC = 0,
|
||||||
MESH_STREAM = 1,
|
MESH_STREAM = 1,
|
||||||
|
|
|
@ -16280,6 +16280,7 @@ typedef struct texture_t {
|
||||||
union { unsigned z, d; };
|
union { unsigned z, d; };
|
||||||
union { unsigned n, bpp; };
|
union { unsigned n, bpp; };
|
||||||
handle id, unit;
|
handle id, unit;
|
||||||
|
unsigned texel_type;
|
||||||
unsigned flags;
|
unsigned flags;
|
||||||
char* filename;
|
char* filename;
|
||||||
bool transparent;
|
bool transparent;
|
||||||
|
@ -16481,6 +16482,19 @@ API void shader_colormap(const char *name, colormap_t cm);
|
||||||
API unsigned shader_get_active();
|
API unsigned shader_get_active();
|
||||||
API void shader_destroy(unsigned shader);
|
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?)
|
// meshes (@fixme: deprecate?)
|
||||||
|
|
||||||
|
@ -340094,6 +340108,56 @@ unsigned shader(const char *vs, const char *fs, const char *attribs, const char
|
||||||
return program;
|
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){
|
void shader_destroy(unsigned program){
|
||||||
if( program == ~0u ) return;
|
if( program == ~0u ) return;
|
||||||
glDeleteProgram(program);
|
glDeleteProgram(program);
|
||||||
|
@ -340126,6 +340190,13 @@ void shader_texture_unit(const char *sampler, unsigned id, unsigned unit) {
|
||||||
glActiveTexture(GL_TEXTURE0 + unit);
|
glActiveTexture(GL_TEXTURE0 + unit);
|
||||||
glBindTexture(GL_TEXTURE_2D, id);
|
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 ) {
|
void shader_colormap(const char *name, colormap_t c ) {
|
||||||
// assumes shader uses `struct { vec4 color; bool has_tex } name + sampler2D name_tex;`
|
// 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 };
|
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;
|
GLenum pixel_storage = flags & TEXTURE_FLOAT ? GL_FLOAT : GL_UNSIGNED_BYTE;
|
||||||
GLuint pixel_type = pixel_types[ n ];
|
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 wrap = GL_CLAMP_TO_EDGE;
|
||||||
GLenum min_filter = GL_NEAREST, mag_filter = GL_NEAREST;
|
GLenum min_filter = GL_NEAREST, mag_filter = GL_NEAREST;
|
||||||
// GLfloat color = (flags&7)/7.f, border_color[4] = { color, color, color, 1.f };
|
// 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 );
|
//glfwWindowHint( GLFW_COCOA_MENUBAR, GLFW_FALSE );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
/* We need to explicitly ask for a 3.2 context on OS X */
|
/* We need to explicitly ask for a 3.2 context on OS X */
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // osx
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // osx
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); // osx, 2:#version150,3:330
|
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__
|
#ifdef __APPLE__
|
||||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); //osx
|
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); //osx
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -194,6 +194,56 @@ unsigned shader(const char *vs, const char *fs, const char *attribs, const char
|
||||||
return program;
|
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){
|
void shader_destroy(unsigned program){
|
||||||
if( program == ~0u ) return;
|
if( program == ~0u ) return;
|
||||||
glDeleteProgram(program);
|
glDeleteProgram(program);
|
||||||
|
@ -226,6 +276,13 @@ void shader_texture_unit(const char *sampler, unsigned id, unsigned unit) {
|
||||||
glActiveTexture(GL_TEXTURE0 + unit);
|
glActiveTexture(GL_TEXTURE0 + unit);
|
||||||
glBindTexture(GL_TEXTURE_2D, id);
|
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 ) {
|
void shader_colormap(const char *name, colormap_t c ) {
|
||||||
// assumes shader uses `struct { vec4 color; bool has_tex } name + sampler2D name_tex;`
|
// 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 };
|
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;
|
GLenum pixel_storage = flags & TEXTURE_FLOAT ? GL_FLOAT : GL_UNSIGNED_BYTE;
|
||||||
GLuint pixel_type = pixel_types[ n ];
|
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 wrap = GL_CLAMP_TO_EDGE;
|
||||||
GLenum min_filter = GL_NEAREST, mag_filter = GL_NEAREST;
|
GLenum min_filter = GL_NEAREST, mag_filter = GL_NEAREST;
|
||||||
// GLfloat color = (flags&7)/7.f, border_color[4] = { color, color, color, 1.f };
|
// 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 z, d; };
|
||||||
union { unsigned n, bpp; };
|
union { unsigned n, bpp; };
|
||||||
handle id, unit;
|
handle id, unit;
|
||||||
|
unsigned texel_type;
|
||||||
unsigned flags;
|
unsigned flags;
|
||||||
char* filename;
|
char* filename;
|
||||||
bool transparent;
|
bool transparent;
|
||||||
|
@ -326,6 +327,19 @@ API void shader_colormap(const char *name, colormap_t cm);
|
||||||
API unsigned shader_get_active();
|
API unsigned shader_get_active();
|
||||||
API void shader_destroy(unsigned shader);
|
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?)
|
// meshes (@fixme: deprecate?)
|
||||||
|
|
||||||
|
|
|
@ -169,9 +169,14 @@ void window_hints(unsigned flags) {
|
||||||
//glfwWindowHint( GLFW_COCOA_MENUBAR, GLFW_FALSE );
|
//glfwWindowHint( GLFW_COCOA_MENUBAR, GLFW_FALSE );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
/* We need to explicitly ask for a 3.2 context on OS X */
|
/* We need to explicitly ask for a 3.2 context on OS X */
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // osx
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // osx
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); // osx, 2:#version150,3:330
|
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__
|
#ifdef __APPLE__
|
||||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); //osx
|
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); //osx
|
||||||
#endif
|
#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;
|
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){
|
void shader_destroy(unsigned program){
|
||||||
if( program == ~0u ) return;
|
if( program == ~0u ) return;
|
||||||
glDeleteProgram(program);
|
glDeleteProgram(program);
|
||||||
|
@ -11140,6 +11190,13 @@ void shader_texture_unit(const char *sampler, unsigned id, unsigned unit) {
|
||||||
glActiveTexture(GL_TEXTURE0 + unit);
|
glActiveTexture(GL_TEXTURE0 + unit);
|
||||||
glBindTexture(GL_TEXTURE_2D, id);
|
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 ) {
|
void shader_colormap(const char *name, colormap_t c ) {
|
||||||
// assumes shader uses `struct { vec4 color; bool has_tex } name + sampler2D name_tex;`
|
// 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 };
|
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;
|
GLenum pixel_storage = flags & TEXTURE_FLOAT ? GL_FLOAT : GL_UNSIGNED_BYTE;
|
||||||
GLuint pixel_type = pixel_types[ n ];
|
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 wrap = GL_CLAMP_TO_EDGE;
|
||||||
GLenum min_filter = GL_NEAREST, mag_filter = GL_NEAREST;
|
GLenum min_filter = GL_NEAREST, mag_filter = GL_NEAREST;
|
||||||
// GLfloat color = (flags&7)/7.f, border_color[4] = { color, color, color, 1.f };
|
// 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 );
|
//glfwWindowHint( GLFW_COCOA_MENUBAR, GLFW_FALSE );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
/* We need to explicitly ask for a 3.2 context on OS X */
|
/* We need to explicitly ask for a 3.2 context on OS X */
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // osx
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // osx
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); // osx, 2:#version150,3:330
|
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__
|
#ifdef __APPLE__
|
||||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); //osx
|
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); //osx
|
||||||
#endif
|
#endif
|
||||||
|
|
14
engine/v4k.h
14
engine/v4k.h
|
@ -2363,6 +2363,7 @@ typedef struct texture_t {
|
||||||
union { unsigned z, d; };
|
union { unsigned z, d; };
|
||||||
union { unsigned n, bpp; };
|
union { unsigned n, bpp; };
|
||||||
handle id, unit;
|
handle id, unit;
|
||||||
|
unsigned texel_type;
|
||||||
unsigned flags;
|
unsigned flags;
|
||||||
char* filename;
|
char* filename;
|
||||||
bool transparent;
|
bool transparent;
|
||||||
|
@ -2564,6 +2565,19 @@ API void shader_colormap(const char *name, colormap_t cm);
|
||||||
API unsigned shader_get_active();
|
API unsigned shader_get_active();
|
||||||
API void shader_destroy(unsigned shader);
|
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?)
|
// meshes (@fixme: deprecate?)
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue