Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/gpu/opengl')
-rw-r--r--source/blender/gpu/opengl/gl_backend.cc2
-rw-r--r--source/blender/gpu/opengl/gl_context.hh1
-rw-r--r--source/blender/gpu/opengl/gl_shader.cc440
-rw-r--r--source/blender/gpu/opengl/gl_shader.hh12
-rw-r--r--source/blender/gpu/opengl/gl_shader_interface.cc133
-rw-r--r--source/blender/gpu/opengl/gl_shader_interface.hh2
6 files changed, 586 insertions, 4 deletions
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
@@ -71,6 +72,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<StageInterfaceInfo *> &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<const char *> 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<const char *> sources) override;
void fragment_shader_from_glsl(MutableSpan<const char *> sources) override;
void compute_shader_from_glsl(MutableSpan<const char *> 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<const char *> 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<ShaderCreateInfo::Resource> 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<GPUUniformBuiltin>(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<GPUUniformBlockBuiltin>(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<GLVaoCache *> refs_;
public:
+ GLShaderInterface(GLuint program, const shader::ShaderCreateInfo &info);
GLShaderInterface(GLuint program);
~GLShaderInterface();