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/intern/gpu_shader.cc')
-rw-r--r--source/blender/gpu/intern/gpu_shader.cc192
1 files changed, 192 insertions, 0 deletions
diff --git a/source/blender/gpu/intern/gpu_shader.cc b/source/blender/gpu/intern/gpu_shader.cc
index 3f5a639d2a0..3b41e804fd4 100644
--- a/source/blender/gpu/intern/gpu_shader.cc
+++ b/source/blender/gpu/intern/gpu_shader.cc
@@ -31,10 +31,32 @@
#include "gpu_backend.hh"
#include "gpu_context_private.hh"
+#include "gpu_shader_create_info.hh"
+#include "gpu_shader_create_info_private.hh"
+#include "gpu_shader_dependency_private.h"
#include "gpu_shader_private.hh"
+#include <string>
+
extern "C" char datatoc_gpu_shader_colorspace_lib_glsl[];
+namespace blender::gpu {
+
+std::string Shader::defines_declare(const shader::ShaderCreateInfo &info) const
+{
+ std::string defines;
+ for (const auto &def : info.defines_) {
+ defines += "#define ";
+ defines += def[0];
+ defines += " ";
+ defines += def[1];
+ defines += "\n";
+ }
+ return defines;
+}
+
+} // namespace blender::gpu
+
using namespace blender;
using namespace blender::gpu;
@@ -59,6 +81,8 @@ static void standard_defines(Vector<const char *> &sources)
BLI_assert(sources.size() == 0);
/* Version needs to be first. Exact values will be added by implementation. */
sources.append("version");
+ /* Define to identify code usage in shading language. */
+ sources.append("#define GPU_SHADER\n");
/* some useful defines to detect GPU type */
if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY)) {
sources.append("#define GPU_ATI\n");
@@ -225,6 +249,174 @@ GPUShader *GPU_shader_create_compute(const char *computecode,
shname);
}
+GPUShader *GPU_shader_create_from_info(const GPUShaderCreateInfo *_info)
+{
+ using namespace blender::gpu::shader;
+ const ShaderCreateInfo &info = *reinterpret_cast<const ShaderCreateInfo *>(_info);
+
+ const_cast<ShaderCreateInfo &>(info).finalize();
+
+ /* At least a vertex shader and a fragment shader are required, or only a compute shader. */
+ if (info.compute_source_.is_empty()) {
+ if (info.vertex_source_.is_empty()) {
+ printf("Missing vertex shader in %s.\n", info.name_.c_str());
+ }
+ if (info.fragment_source_.is_empty()) {
+ printf("Missing fragment shader in %s.\n", info.name_.c_str());
+ }
+ BLI_assert(!info.vertex_source_.is_empty() && !info.fragment_source_.is_empty());
+ }
+ else {
+ if (!info.vertex_source_.is_empty()) {
+ printf("Compute shader has vertex_source_ shader attached in %s.\n", info.name_.c_str());
+ }
+ if (!info.geometry_source_.is_empty()) {
+ printf("Compute shader has geometry_source_ shader attached in %s.\n", info.name_.c_str());
+ }
+ if (!info.fragment_source_.is_empty()) {
+ printf("Compute shader has fragment_source_ shader attached in %s.\n", info.name_.c_str());
+ }
+ BLI_assert(info.vertex_source_.is_empty() && info.geometry_source_.is_empty() &&
+ info.fragment_source_.is_empty());
+ }
+
+ Shader *shader = GPUBackend::get()->shader_alloc(info.name_.c_str());
+
+ std::string defines = shader->defines_declare(info);
+ std::string resources = shader->resources_declare(info);
+ char *shader_shared_utils = nullptr;
+
+ defines += "#define USE_GPU_SHADER_CREATE_INFO\n";
+
+ Vector<char *> typedefs;
+ for (auto filename : info.typedef_sources_) {
+ typedefs.append(gpu_shader_dependency_get_source(filename.c_str()));
+ }
+ if (!typedefs.is_empty()) {
+ shader_shared_utils = gpu_shader_dependency_get_source("gpu_shader_shared_utils.h");
+ }
+
+ if (!info.vertex_source_.is_empty()) {
+ uint32_t builtins = 0;
+ std::string interface = shader->vertex_interface_declare(info);
+ char *code = gpu_shader_dependency_get_resolved_source(info.vertex_source_.c_str(), &builtins);
+
+ Vector<const char *> sources;
+ standard_defines(sources);
+ sources.append("#define GPU_VERTEX_SHADER\n");
+ if (!info.geometry_source_.is_empty()) {
+ sources.append("#define USE_GEOMETRY_SHADER\n");
+ }
+ sources.append(defines.c_str());
+ if (!typedefs.is_empty()) {
+ sources.append(shader_shared_utils);
+ }
+ for (auto *types : typedefs) {
+ sources.append(types);
+ }
+ sources.append(resources.c_str());
+ sources.append(interface.c_str());
+ sources.append(code);
+
+ shader->vertex_shader_from_glsl(sources);
+
+ free(code);
+ }
+
+ if (!info.fragment_source_.is_empty()) {
+ uint32_t builtins = 0;
+ std::string interface = shader->fragment_interface_declare(info);
+ char *code = gpu_shader_dependency_get_resolved_source(info.fragment_source_.c_str(),
+ &builtins);
+
+ Vector<const char *> sources;
+ standard_defines(sources);
+ sources.append("#define GPU_FRAGMENT_SHADER\n");
+ if (!info.geometry_source_.is_empty()) {
+ sources.append("#define USE_GEOMETRY_SHADER\n");
+ }
+ sources.append(defines.c_str());
+ if (!typedefs.is_empty()) {
+ sources.append(shader_shared_utils);
+ }
+ for (auto *types : typedefs) {
+ sources.append(types);
+ }
+ sources.append(resources.c_str());
+ sources.append(interface.c_str());
+ sources.append(code);
+
+ shader->fragment_shader_from_glsl(sources);
+
+ free(code);
+ }
+
+ if (!info.geometry_source_.is_empty()) {
+ uint32_t builtins = 0;
+ std::string interface = shader->geometry_interface_declare(info);
+ std::string layout = shader->geometry_layout_declare(info);
+ char *code = gpu_shader_dependency_get_resolved_source(info.geometry_source_.c_str(),
+ &builtins);
+
+ Vector<const char *> sources;
+ standard_defines(sources);
+ sources.append("#define GPU_GEOMETRY_SHADER\n");
+ sources.append(defines.c_str());
+ if (!typedefs.is_empty()) {
+ sources.append(shader_shared_utils);
+ }
+ for (auto *types : typedefs) {
+ sources.append(types);
+ }
+ sources.append(resources.c_str());
+ sources.append(layout.c_str());
+ sources.append(interface.c_str());
+ sources.append(code);
+
+ shader->geometry_shader_from_glsl(sources);
+
+ free(code);
+ }
+
+ if (!info.compute_source_.is_empty()) {
+ uint32_t builtins = 0;
+ char *code = gpu_shader_dependency_get_resolved_source(info.compute_source_.c_str(),
+ &builtins);
+
+ Vector<const char *> sources;
+ standard_defines(sources);
+ sources.append("#define GPU_COMPUTE_SHADER\n");
+ sources.append(defines.c_str());
+ if (!typedefs.is_empty()) {
+ sources.append(shader_shared_utils);
+ }
+ for (auto *types : typedefs) {
+ sources.append(types);
+ }
+ sources.append(resources.c_str());
+ sources.append(code);
+
+ shader->compute_shader_from_glsl(sources);
+
+ free(code);
+ }
+
+ for (auto *types : typedefs) {
+ free(types);
+ }
+
+ if (shader_shared_utils) {
+ free(shader_shared_utils);
+ }
+
+ if (!shader->finalize(&info)) {
+ delete shader;
+ return nullptr;
+ }
+
+ return wrap(shader);
+}
+
GPUShader *GPU_shader_create_from_python(const char *vertcode,
const char *fragcode,
const char *geomcode,