diff options
Diffstat (limited to 'source/blender/gpu/opengl/gl_shader.cc')
-rw-r--r-- | source/blender/gpu/opengl/gl_shader.cc | 440 |
1 files changed, 3 insertions, 437 deletions
diff --git a/source/blender/gpu/opengl/gl_shader.cc b/source/blender/gpu/opengl/gl_shader.cc index fe5ffe5a2ad..8367b0de02b 100644 --- a/source/blender/gpu/opengl/gl_shader.cc +++ b/source/blender/gpu/opengl/gl_shader.cc @@ -38,7 +38,6 @@ using namespace blender; using namespace blender::gpu; -using namespace blender::gpu::shader; /* -------------------------------------------------------------------- */ /** \name Creation / Destruction @@ -72,429 +71,6 @@ 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 * \{ */ @@ -508,12 +84,7 @@ static char *glsl_patch_default_get() size_t slen = 0; /* Version need to go first. */ - if (GLEW_VERSION_4_3) { - STR_CONCAT(patch, slen, "#version 430\n"); - } - else { - STR_CONCAT(patch, slen, "#version 330\n"); - } + 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! */ @@ -635,7 +206,7 @@ void GLShader::compute_shader_from_glsl(MutableSpan<const char *> sources) compute_shader_ = this->create_shader_stage(GL_COMPUTE_SHADER, sources); } -bool GLShader::finalize(const shader::ShaderCreateInfo *info) +bool GLShader::finalize() { if (compilation_failed_) { return false; @@ -654,12 +225,7 @@ bool GLShader::finalize(const shader::ShaderCreateInfo *info) return false; } - if (info != nullptr) { - interface = new GLShaderInterface(shader_program_, *info); - } - else { - interface = new GLShaderInterface(shader_program_); - } + interface = new GLShaderInterface(shader_program_); return true; } |