Created
February 11, 2023 00:22
-
-
Save rygorous/346f0c30b3cb096c6370050d07ce475e to your computer and use it in GitHub Desktop.
Old bug repros from 2014.
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
#include <stdio.h> | |
#include <stdlib.h> | |
#include <GL/gl3w.h> | |
#include "util.h" | |
#include "radglx.h" | |
#define CHECK_RESULTS // turn this off and we'll keep running until the driver crashes. | |
#define MIN_ALIGN 1 // setting this to 128 (or higher) fixes the bug (both incorrect results and crash) | |
typedef unsigned char U8; | |
static GLuint mk_tex_bind( GLenum target ) | |
{ | |
GLuint tex; | |
glGenTextures( 1, &tex ); | |
glBindTexture( target, tex ); | |
return tex; | |
} | |
static GLuint make_gl_tex( GLenum internalformat, GLsizei w, GLsizei h ) | |
{ | |
GLuint tex = mk_tex_bind( GL_TEXTURE_2D ); | |
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1 ); | |
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); | |
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); | |
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); | |
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); | |
glTexStorage2D( GL_TEXTURE_2D, 1, internalformat, w, h ); | |
return tex; | |
} | |
static GLuint make_gl_tex_buf_range( GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size ) | |
{ | |
GLuint tex = mk_tex_bind( GL_TEXTURE_BUFFER ); | |
glTexBufferRange( GL_TEXTURE_BUFFER, internalformat, buffer, offset, size ); | |
return tex; | |
} | |
static const char shader_code[] = | |
"#version 430 core\n" | |
"layout(local_size_x=16, local_size_y=16) in;\n" | |
"layout(binding=0, r8ui) uniform uimage2D o_img;\n" | |
"void main() {\n" | |
" imageStore(o_img, ivec2(gl_GlobalInvocationID.xy), uvec4(128));\n" | |
"}\n"; | |
int main(int argc, char **argv) | |
{ | |
// Init GL | |
glx_context * glx = glx_init( "gl_bug", 512, 512 ); | |
// Create our textures | |
GLuint tex_out = make_gl_tex( GL_R8UI, 8, 8 ); | |
// Determine texture buffer offset alignment and print it | |
GLint gl_align; | |
glGetIntegerv( GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT, &gl_align ); | |
printf( "align=%d\n", gl_align ); | |
if ( gl_align < MIN_ALIGN ) | |
gl_align = MIN_ALIGN; | |
// Create a buffer and corresponding texture buffer. | |
// Note we specify "gl_align" (i.e. TEXTURE_BUFFER_OFFSET_ALIGNMENT) as offset; | |
// this should be fine. | |
GLuint dc_buf = glx_make_buffer( GL_TEXTURE_BUFFER, 64 * 1024, NULL, GL_DYNAMIC_COPY ); | |
GLuint dc_tex = make_gl_tex_buf_range( dc_buf, GL_R16I, gl_align, 1024 ); | |
// Create block programs | |
GLuint test_prog = glx_compute_program_source( shader_code ); | |
if ( !test_prog ) | |
return 1; | |
int frame = 0; | |
while ( glx_handle_events( glx, false ) ) | |
{ | |
glUseProgram( test_prog ); | |
glBindImageTexture( 0, tex_out, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R8UI ); | |
// comment out the next line (unused image unit!) and the bug disappears | |
glBindImageTexture( 1, dc_tex, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R16I ); | |
glDispatchCompute( 1, 1, 1 ); | |
// make sure texture changes are visible. | |
glMemoryBarrier( GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | GL_TEXTURE_FETCH_BARRIER_BIT ); | |
glx_swap_buffers( glx ); | |
#ifdef CHECK_RESULTS | |
U8 * gpu_out = (U8 *)glx_read_texture_level( tex_out, 0 ); | |
int offs; | |
bool ok = true; | |
// check against reference | |
for ( offs = 0 ; offs < 64 ; offs++ ) | |
{ | |
if ( gpu_out[offs] != 128 ) | |
{ | |
printf( "mismatch at offs=%d: is %d, should be 128.\n", offs, gpu_out[offs] ); | |
ok = false; | |
break; | |
} | |
} | |
free( gpu_out ); | |
if ( !ok ) | |
break; | |
#endif | |
if ( ++frame >= 1000 ) | |
break; | |
} | |
// clean up | |
glUseProgram( 0 ); | |
glDeleteBuffers( 1, &dc_buf ); | |
glDeleteTextures( 1, &tex_out ); | |
glDeleteTextures( 1, &dc_tex ); | |
glDeleteProgram( test_prog ); | |
printf("exiting...\n"); | |
glx_shutdown( glx ); | |
return 0; | |
} | |
// vim:et:sw=4 | |
// @cdep pre $DefaultsConsoleGL | |
// @cdep post $BuildConsoleGL( , ) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment