diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2022-01-25 20:48:40 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2022-01-25 20:48:58 +0300 |
commit | 2637f94358329e1a8fce59dd036c577459e5a847 (patch) | |
tree | b8a434b788565700694b4722e2f2a9cf6f2d5a41 /source/blender/gpu | |
parent | 3e2591c83ed6c4eb8adecfe06c976717f161cd23 (diff) |
GLShader: Fix buffer overflow caused by workaround uniform
In order to use a workaround builtin uniform, we need to count it
just like other uniforms and give it some space in the name buffer.
This also fixes extensions being added after the uniform declaration.
All `#extension` directives are now part of the gl backend.
Diffstat (limited to 'source/blender/gpu')
-rw-r--r-- | source/blender/gpu/opengl/gl_shader.cc | 12 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_shader_interface.cc | 33 |
2 files changed, 36 insertions, 9 deletions
diff --git a/source/blender/gpu/opengl/gl_shader.cc b/source/blender/gpu/opengl/gl_shader.cc index 532065ed08f..ac9aec5af04 100644 --- a/source/blender/gpu/opengl/gl_shader.cc +++ b/source/blender/gpu/opengl/gl_shader.cc @@ -587,6 +587,18 @@ static char *glsl_patch_default_get() STR_CONCAT(patch, slen, "#extension GL_ARB_texture_cube_map_array : enable\n"); STR_CONCAT(patch, slen, "#define GPU_ARB_texture_cube_map_array\n"); } + if (GLEW_ARB_conservative_depth) { + STR_CONCAT(patch, slen, "#extension GL_ARB_conservative_depth : enable\n"); + } + if (GPU_shader_image_load_store_support()) { + STR_CONCAT(patch, slen, "#extension GL_ARB_shader_image_load_store: enable\n"); + STR_CONCAT(patch, slen, "#extension GL_ARB_shading_language_420pack: enable\n"); + } + + if (!GLContext::shader_draw_parameters_support) { + /* Fallback: Emulate base instance using a uniform. */ + STR_CONCAT(patch, slen, "uniform int gpu_BaseInstance;\n"); + } /* Fallbacks. */ if (!GLContext::shader_draw_parameters_support) { diff --git a/source/blender/gpu/opengl/gl_shader_interface.cc b/source/blender/gpu/opengl/gl_shader_interface.cc index 4414ba0464b..299ea150408 100644 --- a/source/blender/gpu/opengl/gl_shader_interface.cc +++ b/source/blender/gpu/opengl/gl_shader_interface.cc @@ -355,13 +355,28 @@ GLShaderInterface::GLShaderInterface(GLuint program, const shader::ShaderCreateI } } + size_t workaround_names_size = 0; + Vector<StringRefNull> workaround_uniform_names; + auto check_enabled_uniform = [&](const char *uniform_name) { + if (glGetUniformLocation(program, uniform_name) != -1) { + workaround_uniform_names.append(uniform_name); + workaround_names_size += StringRefNull(uniform_name).size() + 1; + uniform_len_++; + } + }; + + if (!GLContext::shader_draw_parameters_support) { + check_enabled_uniform("gpu_BaseInstance"); + } + BLI_assert_msg(ubo_len_ <= 16, "enabled_ubo_mask_ is uint16_t"); int input_tot_len = attr_len_ + ubo_len_ + uniform_len_ + ssbo_len_; inputs_ = (ShaderInput *)MEM_callocN(sizeof(ShaderInput) * input_tot_len, __func__); ShaderInput *input = inputs_; - name_buffer_ = (char *)MEM_mallocN(info.interface_names_size_, "name_buffer"); + name_buffer_ = (char *)MEM_mallocN(info.interface_names_size_ + workaround_names_size, + "name_buffer"); uint32_t name_buffer_offset = 0; /* Necessary to make #glUniform works. TODO(fclem) Remove. */ @@ -430,6 +445,14 @@ GLShaderInterface::GLShaderInterface(GLuint program, const shader::ShaderCreateI input++; } + /* Compatibility uniforms. */ + for (auto &name : workaround_uniform_names) { + copy_input_name(input, name, name_buffer_, name_buffer_offset); + input->location = glGetUniformLocation(program, name_buffer_ + input->name_offset); + input->binding = -1; + input++; + } + /* SSBOs */ for (const ShaderCreateInfo::Resource &res : all_resources) { if (res.bind_type == ShaderCreateInfo::Resource::BindType::STORAGE_BUFFER) { @@ -440,14 +463,6 @@ GLShaderInterface::GLShaderInterface(GLuint program, const shader::ShaderCreateI } } - /* Compatibility uniforms. */ - if (!GLContext::shader_draw_parameters_support) { - input->location = glGetUniformLocation(program, "gpu_BaseInstance"); - copy_input_name(input, "gpu_BaseInstance", name_buffer_, name_buffer_offset); - input->binding = -1; - input++; - } - /* Builtin Uniforms */ for (int32_t u_int = 0; u_int < GPU_NUM_UNIFORMS; u_int++) { GPUUniformBuiltin u = static_cast<GPUUniformBuiltin>(u_int); |