Skip to content

Instantly share code, notes, and snippets.

@Yves-G
Created June 19, 2016 12:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Yves-G/d2be1569e65a86697824e611c5b80d87 to your computer and use it in GitHub Desktop.
Save Yves-G/d2be1569e65a86697824e611c5b80d87 to your computer and use it in GitHub Desktop.
Reproduces a bug related to bindless textures in the AMD graphics driver that causes the program to hang when too many textures are made resident. Build instructions in a comment in the file.
/*
* Copyright © 2012-2015 Graham Sellers
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/*
* Credits for figuring this one out go to "Alex" on the AMD Dev forums.
*/
/* BUILD INSTRUCTIONS
* 1. git clone https://github.com/openglsuperbible/sb7code
* 2. Make a directory called "reproducer" in sb7code\src and copy reproducer.cpp there
* 3. Add "reproducer" to CMakeLists.txt where all the other directory names are listed
* 4. Build as described in HOWTOBUILD.txt
*/
#include <sb7.h>
#include <iostream>
// This is the number of textures made resident. Change it to < 466 and it runs... On NVidia devices it runs for 4096 and more.
const int count = 512;
class reproducer_app : public sb7::application
{
void init()
{
static const char title[] = "Bindless Texture driver bug reproducer";
sb7::application::init();
memcpy(info.title, title, sizeof(title));
}
virtual void startup()
{
static const char * vs_source[] =
{
"#version 430 \n"
" \n"
"void main(void) \n"
"{ \n"
" const vec4 vertices[] = vec4[](vec4( 0.25, -0.25, 0.5, 1.0), \n"
" vec4(-0.25, -0.25, 0.5, 1.0), \n"
" vec4( 0.25, 0.25, 0.5, 1.0)); \n"
" \n"
" gl_Position = vertices[gl_VertexID]; \n"
"} \n"
};
static const char * fs_source[] =
{
"#version 430 \n"
" \n"
"#extension GL_ARB_bindless_texture : require \n"
" \n"
"layout(bindless_sampler) uniform sampler2D tex; \n"
" \n"
"void main () { \n"
" gl_FragColor = texture(tex, vec2(0.5, 0.5)); \n"
"} \n"
};
program = glCreateProgram();
GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fs, 1, fs_source, NULL);
glCompileShader(fs);
GLuint vs = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vs, 1, vs_source, NULL);
glCompileShader(vs);
glAttachShader(program, vs);
glAttachShader(program, fs);
glLinkProgram(program);
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// Texture related stuff
GLuint texture[count];
glCreateTextures(GL_TEXTURE_2D, count, texture);
if (glGetError() != GL_NO_ERROR)
{
std::cout << "Error during glCreateTextures" << std::endl;
return;
}
float data[128 * 128 * 4];
for (int i = 0; i < 128 * 128 * 4; ++i)
{
data[i] = (i % 2 == 1) ? 1 : 0; // Green
}
for (int i = 0; i < count; ++i)
{
glTextureStorage2D(texture[i], 1, GL_RGBA32F, 128, 128);
if (glGetError() != GL_NO_ERROR)
{
std::cout << "Error during glTextureStorage2D" << std::endl;
return;
}
glTextureSubImage2D(texture[i], 0, 0, 0, 128, 128, GL_RGBA, GL_FLOAT, data);
if (glGetError() != GL_NO_ERROR)
{
std::cout << "Error during glTextureSubImage2D" << std::endl;
return;
}
handles[i] = glGetTextureHandleARB(texture[i]);
}
for (int i = 0; i < count; ++i)
{
glMakeTextureHandleResidentARB(handles[i]);
if (glGetError() != GL_NO_ERROR)
{
std::cout << "Error during glMakeTextureHandleResidentARB" << std::endl;
return;
}
if (glIsTextureHandleResidentARB(handles[i]))
std::cout << "Sucessfully making resident " << i << std::endl;
else
std::cout << "Error making resident " << i << std::endl;
}
}
virtual void render(double currentTime)
{
static const GLfloat green[] = { 0.0f, 0.25f, 0.0f, 1.0f };
glClearBufferfv(GL_COLOR, 0, green);
glUseProgram(program);
if (glGetError() != GL_NO_ERROR)
{
std::cout << "Error during glUseProgram" << std::endl;
return;
}
texHandleID = glGetUniformLocation(program, "tex");
if (glGetError() != GL_NO_ERROR)
{
std::cout << "Error during glGetUniformLocation" << std::endl;
return;
}
for (int i = 0; i < count; ++i)
{
glUniformHandleui64ARB(texHandleID, handles[i]);
glDrawArrays(GL_TRIANGLES, 0, 3);
}
//std::cout << "Rendered" << std::endl;
}
virtual void shutdown()
{
glDeleteVertexArrays(1, &vao);
glDeleteProgram(program);
}
private:
GLuint program;
GLuint vao;
GLint64 handles[count];
GLuint texHandleID;
};
DECLARE_MAIN(reproducer_app)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment