X-Git-Url: https://git.sesse.net/?p=movit;a=blobdiff_plain;f=resource_pool.cpp;h=6939fe01d50a61131d4357858c6d82a4d9361da2;hp=be74b3d96a563120dde3c8a4f3cc50ff6c5539ed;hb=34776d3ed2565ee834405e575bf3bfc7f7933e36;hpb=831150846e1e79b53b02b07fbf12ec7cae289a3a diff --git a/resource_pool.cpp b/resource_pool.cpp index be74b3d..6939fe0 100644 --- a/resource_pool.cpp +++ b/resource_pool.cpp @@ -100,11 +100,23 @@ void ResourcePool::delete_program(GLuint glsl_program_num) program_shaders.erase(shader_it); } -GLuint ResourcePool::compile_glsl_program(const string& vertex_shader, const string& fragment_shader) +GLuint ResourcePool::compile_glsl_program(const string& vertex_shader, + const string& fragment_shader, + const vector& fragment_shader_outputs) { GLuint glsl_program_num; pthread_mutex_lock(&lock); - const pair key(vertex_shader, fragment_shader); + + // Augment the fragment shader program text with the outputs, so that they become + // part of the key. Also potentially useful for debugging. + string fragment_shader_processed = fragment_shader; + for (unsigned output_index = 0; output_index < fragment_shader_outputs.size(); ++output_index) { + char buf[256]; + snprintf(buf, sizeof(buf), "// Bound output: %s\n", fragment_shader_outputs[output_index].c_str()); + fragment_shader_processed += buf; + } + + const pair key(vertex_shader, fragment_shader_processed); if (programs.count(key)) { // Already in the cache. Increment the refcount, or take it off the freelist // if it's zero. @@ -125,12 +137,21 @@ GLuint ResourcePool::compile_glsl_program(const string& vertex_shader, const str check_error(); GLuint vs_obj = compile_shader(vertex_shader, GL_VERTEX_SHADER); check_error(); - GLuint fs_obj = compile_shader(fragment_shader, GL_FRAGMENT_SHADER); + GLuint fs_obj = compile_shader(fragment_shader_processed, GL_FRAGMENT_SHADER); check_error(); glAttachShader(glsl_program_num, vs_obj); check_error(); glAttachShader(glsl_program_num, fs_obj); check_error(); + + // Bind the outputs, if we have multiple ones. + if (fragment_shader_outputs.size() > 1) { + for (unsigned output_index = 0; output_index < fragment_shader_outputs.size(); ++output_index) { + glBindFragDataLocation(glsl_program_num, output_index, + fragment_shader_outputs[output_index].c_str()); + } + } + glLinkProgram(glsl_program_num); check_error(); @@ -153,7 +174,7 @@ GLuint ResourcePool::compile_glsl_program(const string& vertex_shader, const str perror(filename); exit(1); } - fprintf(fp, "%s\n", fragment_shader.c_str()); + fprintf(fp, "%s\n", fragment_shader_processed.c_str()); fclose(fp); } @@ -215,14 +236,18 @@ GLuint ResourcePool::create_2d_texture(GLint internal_format, GLsizei width, GLs case GL_RGBA32F_ARB: case GL_RGBA16F_ARB: case GL_RGBA8: + case GL_RGB10_A2: case GL_SRGB8_ALPHA8: format = GL_RGBA; break; case GL_RGB32F: case GL_RGB16F: + case GL_R11F_G11F_B10F: case GL_RGB8: + case GL_RGB10: case GL_SRGB8: case GL_RGB565: + case GL_RGB9_E5: format = GL_RGB; break; case GL_RG32F: @@ -247,6 +272,8 @@ GLuint ResourcePool::create_2d_texture(GLint internal_format, GLsizei width, GLs case GL_RGBA16F_ARB: case GL_RGB32F: case GL_RGB16F: + case GL_R11F_G11F_B10F: + case GL_RGB9_E5: case GL_RG32F: case GL_RG16F: case GL_R32F: @@ -257,6 +284,8 @@ GLuint ResourcePool::create_2d_texture(GLint internal_format, GLsizei width, GLs case GL_SRGB8: case GL_RGBA8: case GL_RGB8: + case GL_RGB10_A2: + case GL_RGB10: case GL_RG8: case GL_R8: type = GL_UNSIGNED_BYTE; @@ -480,8 +509,16 @@ size_t ResourcePool::estimate_texture_size(const Texture2D &texture_format) case GL_RGB16F_ARB: bytes_per_pixel = 6; break; + case GL_R11F_G11F_B10F: + bytes_per_pixel = 4; + break; + case GL_RGB9_E5: + bytes_per_pixel = 4; + break; case GL_RGBA8: case GL_SRGB8_ALPHA8: + case GL_RGB10_A2: + case GL_RGB10: bytes_per_pixel = 4; break; case GL_RGB8: