From 9d3f35a0bf1bf5776363bfd61d53a7c85b5827a4 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Mon, 17 Jan 2022 14:45:22 +0100 Subject: Revert "Revert "GPUShaderCreateInfo for interface abstraction"" This reverts commit edee5a947b7ea3e1324aa334a22c7c9bbf47f5f7. Fixes compilation error (Missing file BLI_float2.hh) --- source/blender/gpu/opengl/gl_backend.cc | 2 + source/blender/gpu/opengl/gl_context.hh | 1 + source/blender/gpu/opengl/gl_shader.cc | 440 ++++++++++++++++++++++- source/blender/gpu/opengl/gl_shader.hh | 12 +- source/blender/gpu/opengl/gl_shader_interface.cc | 133 +++++++ source/blender/gpu/opengl/gl_shader_interface.hh | 2 + 6 files changed, 586 insertions(+), 4 deletions(-) (limited to 'source/blender/gpu/opengl') diff --git a/source/blender/gpu/opengl/gl_backend.cc b/source/blender/gpu/opengl/gl_backend.cc index 7bb88894b81..33574da9f58 100644 --- a/source/blender/gpu/opengl/gl_backend.cc +++ b/source/blender/gpu/opengl/gl_backend.cc @@ -434,6 +434,7 @@ bool GLContext::clear_texture_support = false; bool GLContext::copy_image_support = false; bool GLContext::debug_layer_support = false; bool GLContext::direct_state_access_support = false; +bool GLContext::explicit_location_support = false; bool GLContext::fixed_restart_index_support = false; bool GLContext::multi_bind_support = false; bool GLContext::multi_draw_indirect_support = false; @@ -492,6 +493,7 @@ void GLBackend::capabilities_init() GLContext::copy_image_support = GLEW_ARB_copy_image; GLContext::debug_layer_support = GLEW_VERSION_4_3 || GLEW_KHR_debug || GLEW_ARB_debug_output; GLContext::direct_state_access_support = GLEW_ARB_direct_state_access; + GLContext::explicit_location_support = GLEW_VERSION_4_3; GLContext::fixed_restart_index_support = GLEW_ARB_ES3_compatibility; GLContext::multi_bind_support = GLEW_ARB_multi_bind; GLContext::multi_draw_indirect_support = GLEW_ARB_multi_draw_indirect; diff --git a/source/blender/gpu/opengl/gl_context.hh b/source/blender/gpu/opengl/gl_context.hh index 656f4a1caf2..eb365382d53 100644 --- a/source/blender/gpu/opengl/gl_context.hh +++ b/source/blender/gpu/opengl/gl_context.hh @@ -69,6 +69,7 @@ class GLContext : public Context { static bool copy_image_support; static bool debug_layer_support; static bool direct_state_access_support; + static bool explicit_location_support; static bool fixed_restart_index_support; static bool multi_bind_support; static bool multi_draw_indirect_support; diff --git a/source/blender/gpu/opengl/gl_shader.cc b/source/blender/gpu/opengl/gl_shader.cc index 8367b0de02b..fe5ffe5a2ad 100644 --- a/source/blender/gpu/opengl/gl_shader.cc +++ b/source/blender/gpu/opengl/gl_shader.cc @@ -38,6 +38,7 @@ using namespace blender; using namespace blender::gpu; +using namespace blender::gpu::shader; /* -------------------------------------------------------------------- */ /** \name Creation / Destruction @@ -70,6 +71,429 @@ GLShader::~GLShader() /** \} */ +/* -------------------------------------------------------------------- */ +/** \name Create Info + * \{ */ + +static const char *to_string(const Interpolation &interp) +{ + switch (interp) { + case Interpolation::SMOOTH: + return "smooth"; + case Interpolation::FLAT: + return "flat"; + case Interpolation::NO_PERSPECTIVE: + return "noperspective"; + default: + return "unkown"; + } +} + +static const char *to_string(const Type &type) +{ + switch (type) { + case Type::FLOAT: + return "float"; + case Type::VEC2: + return "vec2"; + case Type::VEC3: + return "vec3"; + case Type::VEC4: + return "vec4"; + case Type::MAT3: + return "mat3"; + case Type::MAT4: + return "mat4"; + case Type::UINT: + return "uint"; + case Type::UVEC2: + return "uvec2"; + case Type::UVEC3: + return "uvec3"; + case Type::UVEC4: + return "uvec4"; + case Type::INT: + return "int"; + case Type::IVEC2: + return "ivec2"; + case Type::IVEC3: + return "ivec3"; + case Type::IVEC4: + return "ivec4"; + case Type::BOOL: + return "bool"; + default: + return "unkown"; + } +} + +static const char *to_string(const InputLayout &layout) +{ + switch (layout) { + case InputLayout::POINTS: + return "points"; + case InputLayout::LINES: + return "lines"; + case InputLayout::LINES_ADJACENCY: + return "lines_adjacency"; + case InputLayout::TRIANGLES: + return "triangles"; + case InputLayout::TRIANGLES_ADJACENCY: + return "triangles_adjacency"; + default: + return "unknown"; + } +} + +static const char *to_string(const OutputLayout &layout) +{ + switch (layout) { + case OutputLayout::POINTS: + return "points"; + case OutputLayout::LINE_STRIP: + return "line_strip"; + case OutputLayout::TRIANGLE_STRIP: + return "triangle_strip"; + default: + return "unknown"; + } +} + +static void print_image_type(std::ostream &os, + const ImageType &type, + const ShaderCreateInfo::Resource::BindType bind_type) +{ + switch (type) { + case ImageType::INT_BUFFER: + case ImageType::INT_1D: + case ImageType::INT_1D_ARRAY: + case ImageType::INT_2D: + case ImageType::INT_2D_ARRAY: + case ImageType::INT_3D: + case ImageType::INT_CUBE: + case ImageType::INT_CUBE_ARRAY: + os << "i"; + break; + case ImageType::UINT_BUFFER: + case ImageType::UINT_1D: + case ImageType::UINT_1D_ARRAY: + case ImageType::UINT_2D: + case ImageType::UINT_2D_ARRAY: + case ImageType::UINT_3D: + case ImageType::UINT_CUBE: + case ImageType::UINT_CUBE_ARRAY: + os << "u"; + break; + default: + break; + } + + if (bind_type == ShaderCreateInfo::Resource::BindType::IMAGE) { + os << "image"; + } + else { + os << "sampler"; + } + + switch (type) { + case ImageType::FLOAT_BUFFER: + case ImageType::INT_BUFFER: + case ImageType::UINT_BUFFER: + os << "Buffer"; + break; + case ImageType::FLOAT_1D: + case ImageType::FLOAT_1D_ARRAY: + case ImageType::INT_1D: + case ImageType::INT_1D_ARRAY: + case ImageType::UINT_1D: + case ImageType::UINT_1D_ARRAY: + os << "1D"; + break; + case ImageType::FLOAT_2D: + case ImageType::FLOAT_2D_ARRAY: + case ImageType::INT_2D: + case ImageType::INT_2D_ARRAY: + case ImageType::UINT_2D: + case ImageType::UINT_2D_ARRAY: + case ImageType::SHADOW_2D: + case ImageType::SHADOW_2D_ARRAY: + os << "2D"; + break; + case ImageType::FLOAT_3D: + case ImageType::INT_3D: + case ImageType::UINT_3D: + os << "3D"; + break; + case ImageType::FLOAT_CUBE: + case ImageType::FLOAT_CUBE_ARRAY: + case ImageType::INT_CUBE: + case ImageType::INT_CUBE_ARRAY: + case ImageType::UINT_CUBE: + case ImageType::UINT_CUBE_ARRAY: + case ImageType::SHADOW_CUBE: + case ImageType::SHADOW_CUBE_ARRAY: + os << "Cube"; + break; + default: + break; + } + + switch (type) { + case ImageType::FLOAT_1D_ARRAY: + case ImageType::FLOAT_2D_ARRAY: + case ImageType::FLOAT_CUBE_ARRAY: + case ImageType::INT_1D_ARRAY: + case ImageType::INT_2D_ARRAY: + case ImageType::INT_CUBE_ARRAY: + case ImageType::UINT_1D_ARRAY: + case ImageType::UINT_2D_ARRAY: + case ImageType::UINT_CUBE_ARRAY: + case ImageType::SHADOW_2D_ARRAY: + case ImageType::SHADOW_CUBE_ARRAY: + os << "Array"; + break; + default: + break; + } + + switch (type) { + case ImageType::SHADOW_2D: + case ImageType::SHADOW_2D_ARRAY: + case ImageType::SHADOW_CUBE: + case ImageType::SHADOW_CUBE_ARRAY: + os << "Shadow"; + break; + default: + break; + } + os << " "; +} + +static std::ostream &print_qualifier(std::ostream &os, const Qualifier &qualifiers) +{ + if ((qualifiers & Qualifier::RESTRICT) != Qualifier::RESTRICT) { + os << "restrict"; + } + if ((qualifiers & Qualifier::READ_ONLY) != Qualifier::READ_ONLY) { + os << "readonly"; + } + if ((qualifiers & Qualifier::WRITE_ONLY) != Qualifier::WRITE_ONLY) { + os << "writeonly"; + } + return os << " "; +} + +static void print_resource(std::ostream &os, const ShaderCreateInfo::Resource &res) +{ + if (res.bind_type != ShaderCreateInfo::Resource::BindType::SAMPLER || + GLContext::explicit_location_support) { + os << "layout(binding = " << res.slot; + if (res.bind_type == ShaderCreateInfo::Resource::BindType::IMAGE) { + os << ", " << res.image.format; + } + else if (res.bind_type == ShaderCreateInfo::Resource::BindType::UNIFORM_BUFFER) { + os << ", std140"; + } + else if (res.bind_type == ShaderCreateInfo::Resource::BindType::STORAGE_BUFFER) { + os << ", std430"; + } + os << ") "; + } + + int64_t array_offset; + StringRef name_no_array; + + switch (res.bind_type) { + case ShaderCreateInfo::Resource::BindType::SAMPLER: + os << "uniform "; + print_image_type(os, res.sampler.type, res.bind_type); + os << res.sampler.name << ";\n"; + break; + case ShaderCreateInfo::Resource::BindType::IMAGE: + os << "uniform "; + print_qualifier(os, res.image.qualifiers); + print_image_type(os, res.image.type, res.bind_type); + os << res.image.name << ";\n"; + break; + case ShaderCreateInfo::Resource::BindType::UNIFORM_BUFFER: + array_offset = res.uniformbuf.name.find_first_of("["); + name_no_array = (array_offset == -1) ? res.uniformbuf.name : + StringRef(res.uniformbuf.name.c_str(), array_offset); + os << "uniform " << name_no_array << " { " << res.uniformbuf.type_name << " _" + << res.uniformbuf.name << "; };\n"; + break; + case ShaderCreateInfo::Resource::BindType::STORAGE_BUFFER: + array_offset = res.storagebuf.name.find_first_of("["); + name_no_array = (array_offset == -1) ? res.storagebuf.name : + StringRef(res.storagebuf.name.c_str(), array_offset); + os << "buffer "; + print_qualifier(os, res.storagebuf.qualifiers); + os << name_no_array << " { " << res.storagebuf.type_name << " _" << res.storagebuf.name + << "; };\n"; + break; + } +} + +static void print_resource_alias(std::ostream &os, const ShaderCreateInfo::Resource &res) +{ + int64_t array_offset; + StringRef name_no_array; + + switch (res.bind_type) { + case ShaderCreateInfo::Resource::BindType::UNIFORM_BUFFER: + array_offset = res.uniformbuf.name.find_first_of("["); + name_no_array = (array_offset == -1) ? res.uniformbuf.name : + StringRef(res.uniformbuf.name.c_str(), array_offset); + os << "#define " << name_no_array << " (_" << name_no_array << ")\n"; + break; + case ShaderCreateInfo::Resource::BindType::STORAGE_BUFFER: + array_offset = res.storagebuf.name.find_first_of("["); + name_no_array = (array_offset == -1) ? res.storagebuf.name : + StringRef(res.storagebuf.name.c_str(), array_offset); + os << "#define " << name_no_array << " (_" << name_no_array << ")\n"; + break; + default: + break; + } +} + +static void print_interface(std::ostream &os, + const StringRefNull &prefix, + const StageInterfaceInfo &iface, + const StringRefNull &suffix = "") +{ + /* TODO(fclem) Move that to interface check. */ + // if (iface.instance_name.is_empty()) { + // BLI_assert_msg(0, "Interfaces require an instance name for geometry shader."); + // std::cout << iface.name << ": Interfaces require an instance name for geometry shader.\n"; + // continue; + // } + os << prefix << " " << iface.name << "{" << std::endl; + for (const StageInterfaceInfo::InOut &inout : iface.inouts) { + os << " " << to_string(inout.interp) << " " << to_string(inout.type) << " " << inout.name + << ";\n"; + } + os << "}"; + os << (iface.instance_name.is_empty() ? "" : "\n") << iface.instance_name << suffix << ";\n"; +} + +std::string GLShader::resources_declare(const ShaderCreateInfo &info) const +{ + std::stringstream ss; + + /* NOTE: We define macros in GLSL to trigger compilation error if the resource names + * are reused for local variables. This is to match other backend behavior which needs accessors + * macros. */ + + ss << "\n/* Pass Resources. */\n"; + for (const ShaderCreateInfo::Resource &res : info.pass_resources_) { + print_resource(ss, res); + } + for (const ShaderCreateInfo::Resource &res : info.pass_resources_) { + print_resource_alias(ss, res); + } + ss << "\n/* Batch Resources. */\n"; + for (const ShaderCreateInfo::Resource &res : info.batch_resources_) { + print_resource(ss, res); + } + for (const ShaderCreateInfo::Resource &res : info.batch_resources_) { + print_resource_alias(ss, res); + } + ss << "\n/* Push Constants. */\n"; + for (const ShaderCreateInfo::PushConst &uniform : info.push_constants_) { + if (GLContext::explicit_location_support) { + ss << "layout(location = " << uniform.index << ") "; + } + ss << "uniform " << to_string(uniform.type) << " " << uniform.name; + if (uniform.array_size > 0) { + ss << "[" << uniform.array_size << "]"; + } + ss << ";\n"; + } + for (const ShaderCreateInfo::PushConst &uniform : info.push_constants_) { + ss << "#define " << uniform.name << " (" << uniform.name << ")\n"; + } + ss << "\n"; + return ss.str(); +} + +std::string GLShader::vertex_interface_declare(const ShaderCreateInfo &info) const +{ + std::stringstream ss; + + ss << "\n/* Inputs. */\n"; + for (const ShaderCreateInfo::VertIn &attr : info.vertex_inputs_) { + if (GLContext::explicit_location_support) { + ss << "layout(location = " << attr.index << ") "; + } + ss << "in " << to_string(attr.type) << " " << attr.name << ";\n"; + } + ss << "\n/* Interfaces. */\n"; + for (const StageInterfaceInfo *iface : info.vertex_out_interfaces_) { + print_interface(ss, "out", *iface); + } + ss << "\n"; + return ss.str(); +} + +std::string GLShader::fragment_interface_declare(const ShaderCreateInfo &info) const +{ + std::stringstream ss; + ss << "\n/* Interfaces. */\n"; + const Vector &in_interfaces = (info.geometry_source_.is_empty()) ? + info.vertex_out_interfaces_ : + info.geometry_out_interfaces_; + for (const StageInterfaceInfo *iface : in_interfaces) { + print_interface(ss, "in", *iface); + } + ss << "\n/* Outputs. */\n"; + for (const ShaderCreateInfo::FragOut &output : info.fragment_outputs_) { + ss << "layout(location = " << output.index; + switch (output.blend) { + case DualBlend::SRC_0: + ss << ", index = 0"; + break; + case DualBlend::SRC_1: + ss << ", index = 1"; + break; + default: + break; + } + ss << ") "; + ss << "out " << to_string(output.type) << " " << output.name << ";\n"; + } + ss << "\n"; + return ss.str(); +} + +std::string GLShader::geometry_layout_declare(const ShaderCreateInfo &info) const +{ + std::stringstream ss; + ss << "\n/* Layout. */\n"; + ss << "layout(" << to_string(info.geom_in_.layout) << ") in;\n"; + ss << "layout(" << to_string(info.geom_out_.layout) + << ", max_vertices = " << info.geom_out_.max_vertices << ") out;\n"; + ss << "\n"; + return ss.str(); +} + +std::string GLShader::geometry_interface_declare(const ShaderCreateInfo &info) const +{ + std::stringstream ss; + ss << "\n/* Interfaces. */\n"; + for (const StageInterfaceInfo *iface : info.vertex_out_interfaces_) { + print_interface(ss, "in", *iface, "[]"); + } + ss << "\n"; + for (const StageInterfaceInfo *iface : info.geometry_out_interfaces_) { + print_interface(ss, "out", *iface); + } + ss << "\n"; + return ss.str(); +} + +/** \} */ + /* -------------------------------------------------------------------- */ /** \name Shader stage creation * \{ */ @@ -84,7 +508,12 @@ static char *glsl_patch_default_get() size_t slen = 0; /* Version need to go first. */ - STR_CONCAT(patch, slen, "#version 330\n"); + if (GLEW_VERSION_4_3) { + STR_CONCAT(patch, slen, "#version 430\n"); + } + else { + STR_CONCAT(patch, slen, "#version 330\n"); + } /* Enable extensions for features that are not part of our base GLSL version * don't use an extension for something already available! */ @@ -206,7 +635,7 @@ void GLShader::compute_shader_from_glsl(MutableSpan sources) compute_shader_ = this->create_shader_stage(GL_COMPUTE_SHADER, sources); } -bool GLShader::finalize() +bool GLShader::finalize(const shader::ShaderCreateInfo *info) { if (compilation_failed_) { return false; @@ -225,7 +654,12 @@ bool GLShader::finalize() return false; } - interface = new GLShaderInterface(shader_program_); + if (info != nullptr) { + interface = new GLShaderInterface(shader_program_, *info); + } + else { + interface = new GLShaderInterface(shader_program_); + } return true; } diff --git a/source/blender/gpu/opengl/gl_shader.hh b/source/blender/gpu/opengl/gl_shader.hh index 9ea1334b862..af92c77db54 100644 --- a/source/blender/gpu/opengl/gl_shader.hh +++ b/source/blender/gpu/opengl/gl_shader.hh @@ -27,6 +27,7 @@ #include "glew-mx.h" +#include "gpu_shader_create_info.hh" #include "gpu_shader_private.hh" namespace blender { @@ -36,6 +37,9 @@ namespace gpu { * Implementation of shader compilation and uniforms handling using OpenGL. */ class GLShader : public Shader { + friend shader::ShaderCreateInfo; + friend shader::StageInterfaceInfo; + private: /** Handle for full program (links shader stages below). */ GLuint shader_program_ = 0; @@ -58,7 +62,13 @@ class GLShader : public Shader { void geometry_shader_from_glsl(MutableSpan sources) override; void fragment_shader_from_glsl(MutableSpan sources) override; void compute_shader_from_glsl(MutableSpan sources) override; - bool finalize() override; + bool finalize(const shader::ShaderCreateInfo *info = nullptr) override; + + std::string resources_declare(const shader::ShaderCreateInfo &info) const override; + std::string vertex_interface_declare(const shader::ShaderCreateInfo &info) const override; + std::string fragment_interface_declare(const shader::ShaderCreateInfo &info) const override; + std::string geometry_interface_declare(const shader::ShaderCreateInfo &info) const override; + std::string geometry_layout_declare(const shader::ShaderCreateInfo &info) const override; /** Should be called before linking. */ void transform_feedback_names_set(Span name_list, diff --git a/source/blender/gpu/opengl/gl_shader_interface.cc b/source/blender/gpu/opengl/gl_shader_interface.cc index 9900a4e0766..9dd7b1d57c3 100644 --- a/source/blender/gpu/opengl/gl_shader_interface.cc +++ b/source/blender/gpu/opengl/gl_shader_interface.cc @@ -25,7 +25,9 @@ #include "BLI_bitmap.h" +#include "gl_backend.hh" #include "gl_batch.hh" +#include "gl_context.hh" #include "gl_shader_interface.hh" @@ -323,6 +325,137 @@ GLShaderInterface::GLShaderInterface(GLuint program) this->sort_inputs(); } +GLShaderInterface::GLShaderInterface(GLuint program, const shader::ShaderCreateInfo &info) +{ + using namespace blender::gpu::shader; + + attr_len_ = info.vertex_inputs_.size(); + uniform_len_ = info.push_constants_.size(); + ubo_len_ = 0; + ssbo_len_ = 0; + + Vector all_resources; + all_resources.extend(info.pass_resources_); + all_resources.extend(info.batch_resources_); + + for (ShaderCreateInfo::Resource &res : all_resources) { + switch (res.bind_type) { + case ShaderCreateInfo::Resource::BindType::UNIFORM_BUFFER: + ubo_len_++; + break; + case ShaderCreateInfo::Resource::BindType::STORAGE_BUFFER: + ssbo_len_++; + break; + case ShaderCreateInfo::Resource::BindType::SAMPLER: + uniform_len_++; + break; + case ShaderCreateInfo::Resource::BindType::IMAGE: + uniform_len_++; + break; + } + } + + 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"); + uint32_t name_buffer_offset = 0; + + /* Attributes */ + for (const ShaderCreateInfo::VertIn &attr : info.vertex_inputs_) { + copy_input_name(input, attr.name, name_buffer_, name_buffer_offset); + if (true || !GLContext::explicit_location_support) { + input->location = input->binding = glGetAttribLocation(program, attr.name.c_str()); + } + else { + input->location = input->binding = attr.index; + } + enabled_attr_mask_ |= (1 << input->location); + input++; + } + + /* Uniform Blocks */ + for (const ShaderCreateInfo::Resource &res : all_resources) { + if (res.bind_type == ShaderCreateInfo::Resource::BindType::UNIFORM_BUFFER) { + copy_input_name(input, res.uniformbuf.name, name_buffer_, name_buffer_offset); + if (true || !GLContext::explicit_location_support) { + input->location = glGetUniformBlockIndex(program, res.uniformbuf.name.c_str()); + glUniformBlockBinding(program, input->location, res.slot); + } + input->binding = res.slot; + enabled_ubo_mask_ |= (1 << input->binding); + input++; + } + } + + /* Uniforms & samplers & images */ + for (const ShaderCreateInfo::Resource &res : all_resources) { + if (res.bind_type == ShaderCreateInfo::Resource::BindType::SAMPLER) { + copy_input_name(input, res.sampler.name, name_buffer_, name_buffer_offset); + /* Until we make use of explicit uniform location or eliminate all + * sampler manually changing. */ + if (true || !GLContext::explicit_location_support) { + input->location = glGetUniformLocation(program, res.sampler.name.c_str()); + glUniform1i(input->location, res.slot); + } + input->binding = res.slot; + enabled_tex_mask_ |= (1 << input->binding); + input++; + } + else if (res.bind_type == ShaderCreateInfo::Resource::BindType::IMAGE) { + copy_input_name(input, res.image.name, name_buffer_, name_buffer_offset); + /* Until we make use of explicit uniform location. */ + if (true || !GLContext::explicit_location_support) { + input->location = glGetUniformLocation(program, res.image.name.c_str()); + glUniform1i(input->location, res.slot); + } + input->binding = res.slot; + enabled_ima_mask_ |= (1 << input->binding); + input++; + } + } + for (const ShaderCreateInfo::PushConst &uni : info.push_constants_) { + copy_input_name(input, uni.name, name_buffer_, name_buffer_offset); + /* Until we make use of explicit uniform location. */ + if (true || !GLContext::explicit_location_support) { + input->location = glGetUniformLocation(program, uni.name.c_str()); + } + input->binding = -1; + input++; + } + + /* SSBOs */ + for (const ShaderCreateInfo::Resource &res : all_resources) { + if (res.bind_type == ShaderCreateInfo::Resource::BindType::STORAGE_BUFFER) { + copy_input_name(input, res.storagebuf.name, name_buffer_, name_buffer_offset); + input->location = input->binding = res.slot; + enabled_ubo_mask_ |= (1 << input->binding); + input++; + } + } + + /* Builtin Uniforms */ + for (int32_t u_int = 0; u_int < GPU_NUM_UNIFORMS; u_int++) { + GPUUniformBuiltin u = static_cast(u_int); + const ShaderInput *uni = this->uniform_get(builtin_uniform_name(u)); + builtins_[u] = (uni != nullptr) ? uni->location : -1; + } + + /* Builtin Uniforms Blocks */ + for (int32_t u_int = 0; u_int < GPU_NUM_UNIFORM_BLOCKS; u_int++) { + GPUUniformBlockBuiltin u = static_cast(u_int); + const ShaderInput *block = this->ubo_get(builtin_uniform_block_name(u)); + builtin_blocks_[u] = (block != nullptr) ? block->binding : -1; + } + + this->sort_inputs(); + + // this->debug_print(); +} + GLShaderInterface::~GLShaderInterface() { for (auto *ref : refs_) { diff --git a/source/blender/gpu/opengl/gl_shader_interface.hh b/source/blender/gpu/opengl/gl_shader_interface.hh index 89a5b631047..94b6dd58316 100644 --- a/source/blender/gpu/opengl/gl_shader_interface.hh +++ b/source/blender/gpu/opengl/gl_shader_interface.hh @@ -34,6 +34,7 @@ #include "glew-mx.h" +#include "gpu_shader_create_info.hh" #include "gpu_shader_interface.hh" namespace blender::gpu { @@ -49,6 +50,7 @@ class GLShaderInterface : public ShaderInterface { Vector refs_; public: + GLShaderInterface(GLuint program, const shader::ShaderCreateInfo &info); GLShaderInterface(GLuint program); ~GLShaderInterface(); -- cgit v1.2.3