[Bf-blender-cvs] [9bc678969aa] master: pyGPU: Port 'StageInterfaceInfo' and 'ShaderCreateInfo' types

Germano Cavalcante noreply at git.blender.org
Tue Apr 12 23:51:11 CEST 2022


Commit: 9bc678969aaef5e2343d9362648e9a633d1b6e5e
Author: Germano Cavalcante
Date:   Tue Apr 12 18:28:27 2022 -0300
Branches: master
https://developer.blender.org/rB9bc678969aaef5e2343d9362648e9a633d1b6e5e

pyGPU: Port 'StageInterfaceInfo' and 'ShaderCreateInfo' types

In order to allow GLSL Cross Compilation across platforms, expose in
Python the `GPUShaderCreateInfo` strategy as detailed in
https://wiki.blender.org/wiki/EEVEE_%26_Viewport/GPU_Module/GLSL_Cross_Compilation

The new features can be listed as follows:
```
>>> gpu.types.GPUShaderCreateInfo.
                                  define(
                                  fragment_out(
                                  fragment_source(
                                  push_constant(
                                  sampler(
                                  typedef_source(
                                  uniform_buf(
                                  vertex_in(
                                  vertex_out(
                                  vertex_source(

>>> gpu.types.GPUStageInterfaceInfo.
                                    flat(
                                    name
                                    no_perspective(
                                    smooth(

>>> gpu.shader.create_from_info(
```

Reviewed By: fclem, campbellbarton

Differential Revision: https://developer.blender.org/D14497

===================================================================

M	source/blender/gpu/GPU_shader.h
M	source/blender/gpu/intern/gpu_shader.cc
M	source/blender/gpu/intern/gpu_shader_create_info.cc
M	source/blender/gpu/intern/gpu_shader_create_info.hh
M	source/blender/python/generic/py_capi_utils.h
M	source/blender/python/gpu/CMakeLists.txt
M	source/blender/python/gpu/gpu_py_shader.c
M	source/blender/python/gpu/gpu_py_shader.h
A	source/blender/python/gpu/gpu_py_shader_create_info.cc
M	source/blender/python/gpu/gpu_py_types.c

===================================================================

diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h
index c0c25022836..eed7685bf01 100644
--- a/source/blender/gpu/GPU_shader.h
+++ b/source/blender/gpu/GPU_shader.h
@@ -56,6 +56,7 @@ GPUShader *GPU_shader_create_from_info(const GPUShaderCreateInfo *_info);
 GPUShader *GPU_shader_create_from_info_name(const char *info_name);
 
 const GPUShaderCreateInfo *GPU_shader_create_info_get(const char *info_name);
+bool GPU_shader_create_info_check_error(const GPUShaderCreateInfo *_info, char r_error[128]);
 
 struct GPU_ShaderCreateFromArray_Params {
   const char **vert, **geom, **frag, **defs;
diff --git a/source/blender/gpu/intern/gpu_shader.cc b/source/blender/gpu/intern/gpu_shader.cc
index b434cfbbb0e..227525bd5d3 100644
--- a/source/blender/gpu/intern/gpu_shader.cc
+++ b/source/blender/gpu/intern/gpu_shader.cc
@@ -249,6 +249,19 @@ const GPUShaderCreateInfo *GPU_shader_create_info_get(const char *info_name)
   return gpu_shader_create_info_get(info_name);
 }
 
+bool GPU_shader_create_info_check_error(const GPUShaderCreateInfo *_info, char r_error[128])
+{
+  using namespace blender::gpu::shader;
+  const ShaderCreateInfo &info = *reinterpret_cast<const ShaderCreateInfo *>(_info);
+  std::string error = info.check_error();
+  if (error.length() == 0) {
+    return true;
+  }
+
+  BLI_strncpy(r_error, error.c_str(), 128);
+  return false;
+}
+
 GPUShader *GPU_shader_create_from_info_name(const char *info_name)
 {
   using namespace blender::gpu::shader;
@@ -270,28 +283,10 @@ GPUShader *GPU_shader_create_from_info(const GPUShaderCreateInfo *_info)
 
   GPU_debug_group_begin(GPU_DEBUG_SHADER_COMPILATION_GROUP);
 
-  /* 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());
+  std::string error = info.check_error();
+  if (error.length()) {
+    printf(error.c_str());
+    BLI_assert(true);
   }
 
   Shader *shader = GPUBackend::get()->shader_alloc(info.name_.c_str());
diff --git a/source/blender/gpu/intern/gpu_shader_create_info.cc b/source/blender/gpu/intern/gpu_shader_create_info.cc
index 0dd82d4ea44..6e82201b424 100644
--- a/source/blender/gpu/intern/gpu_shader_create_info.cc
+++ b/source/blender/gpu/intern/gpu_shader_create_info.cc
@@ -136,6 +136,34 @@ void ShaderCreateInfo::finalize()
   }
 }
 
+std::string ShaderCreateInfo::check_error() const
+{
+  std::string error;
+
+  /* At least a vertex shader and a fragment shader are required, or only a compute shader. */
+  if (this->compute_source_.is_empty()) {
+    if (this->vertex_source_.is_empty()) {
+      error += "Missing vertex shader in " + this->name_ + ".\n";
+    }
+    if (this->fragment_source_.is_empty()) {
+      error += "Missing fragment shader in " + this->name_ + ".\n";
+    }
+  }
+  else {
+    if (!this->vertex_source_.is_empty()) {
+      error += "Compute shader has vertex_source_ shader attached in" + this->name_ + ".\n";
+    }
+    if (!this->geometry_source_.is_empty()) {
+      error += "Compute shader has geometry_source_ shader attached in" + this->name_ + ".\n";
+    }
+    if (!this->fragment_source_.is_empty()) {
+      error += "Compute shader has fragment_source_ shader attached in" + this->name_ + ".\n";
+    }
+  }
+
+  return error;
+}
+
 void ShaderCreateInfo::validate(const ShaderCreateInfo &other_info)
 {
   if (!auto_resource_location_) {
diff --git a/source/blender/gpu/intern/gpu_shader_create_info.hh b/source/blender/gpu/intern/gpu_shader_create_info.hh
index 51008993353..dfd73219d1b 100644
--- a/source/blender/gpu/intern/gpu_shader_create_info.hh
+++ b/source/blender/gpu/intern/gpu_shader_create_info.hh
@@ -787,6 +787,8 @@ struct ShaderCreateInfo {
   /* WARNING: Recursive. */
   void finalize();
 
+  std::string check_error() const;
+
   /** Error detection that some backend compilers do not complain about. */
   void validate(const ShaderCreateInfo &other_info);
 
diff --git a/source/blender/python/generic/py_capi_utils.h b/source/blender/python/generic/py_capi_utils.h
index 0f94b264159..ecb6db2b82c 100644
--- a/source/blender/python/generic/py_capi_utils.h
+++ b/source/blender/python/generic/py_capi_utils.h
@@ -8,6 +8,10 @@
 #ifndef __PY_CAPI_UTILS_H__
 #define __PY_CAPI_UTILS_H__
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include "BLI_sys_types.h"
 #include "BLI_utildefines_variadic.h"
 
@@ -273,3 +277,7 @@ bool PyC_StructFmt_type_is_byte(char format);
 bool PyC_StructFmt_type_is_bool(char format);
 
 #endif /* __PY_CAPI_UTILS_H__ */
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/python/gpu/CMakeLists.txt b/source/blender/python/gpu/CMakeLists.txt
index 644bbd18173..e726cb7883d 100644
--- a/source/blender/python/gpu/CMakeLists.txt
+++ b/source/blender/python/gpu/CMakeLists.txt
@@ -29,6 +29,7 @@ set(SRC
   gpu_py_offscreen.c
   gpu_py_platform.c
   gpu_py_select.c
+  gpu_py_shader_create_info.cc
   gpu_py_shader.c
   gpu_py_state.c
   gpu_py_texture.c
diff --git a/source/blender/python/gpu/gpu_py_shader.c b/source/blender/python/gpu/gpu_py_shader.c
index c74b3e173d1..cdcf22df7a1 100644
--- a/source/blender/python/gpu/gpu_py_shader.c
+++ b/source/blender/python/gpu/gpu_py_shader.c
@@ -831,6 +831,38 @@ static PyObject *pygpu_shader_code_from_builtin(BPyGPUShader *UNUSED(self), PyOb
   return r_dict;
 }
 
+PyDoc_STRVAR(pygpu_shader_create_from_info_doc,
+             ".. function:: create_from_info(shader_info)\n"
+             "\n"
+             "   Create shader from a GPUShaderCreateInfo.\n"
+             "\n"
+             "   :param shader_info: GPUShaderCreateInfo\n"
+             "   :type shader_info: :class:`bpy.types.GPUShaderCreateInfo`\n"
+             "   :return: Shader object corresponding to the given name.\n"
+             "   :rtype: :class:`bpy.types.GPUShader`\n");
+static PyObject *pygpu_shader_create_from_info(BPyGPUShader *UNUSED(self),
+                                               BPyGPUShaderCreateInfo *o)
+{
+  if (!BPyGPUShaderCreateInfo_Check(o)) {
+    PyErr_Format(PyExc_TypeError, "Expected a GPUShaderCreateInfo, got %s", Py_TYPE(o)->tp_name);
+    return NULL;
+  }
+
+  char error[128];
+  if (!GPU_shader_create_info_check_error(o->info, error)) {
+    PyErr_SetString(PyExc_Exception, error);
+    return NULL;
+  }
+
+  GPUShader *shader = GPU_shader_create_from_info(o->info);
+  if (!shader) {
+    PyErr_SetString(PyExc_Exception, "Shader Compile Error, see console for more details");
+    return NULL;
+  }
+
+  return BPyGPUShader_CreatePyObject(shader, false);
+}
+
 static struct PyMethodDef pygpu_shader_module__tp_methods[] = {
     {"unbind", (PyCFunction)pygpu_shader_unbind, METH_NOARGS, pygpu_shader_unbind_doc},
     {"from_builtin",
@@ -841,6 +873,10 @@ static struct PyMethodDef pygpu_shader_module__tp_methods[] = {
      (PyCFunction)pygpu_shader_code_from_builtin,
      METH_O,
      pygpu_shader_code_from_builtin_doc},
+    {"create_from_info",
+     (PyCFunction)pygpu_shader_create_from_info,
+     METH_O,
+     pygpu_shader_create_from_info_doc},
     {NULL, NULL, 0, NULL},
 };
 
diff --git a/source/blender/python/gpu/gpu_py_shader.h b/source/blender/python/gpu/gpu_py_shader.h
index eb4810efeac..b5944c4b3a0 100644
--- a/source/blender/python/gpu/gpu_py_shader.h
+++ b/source/blender/python/gpu/gpu_py_shader.h
@@ -6,6 +6,12 @@
 
 #pragma once
 
+/* Make sure that there is always a reference count for PyObjects of type String as the strings are
+ * passed by reference in the #GPUStageInterfaceInfo and #GPUShaderCreateInfo APIs. */
+#define USE_GPU_PY_REFERENCES
+
+/* gpu_py_shader.c */
+
 extern PyTypeObject BPyGPUShader_Type;
 
 #define BPyGPUShader_Check(v) (Py_TYPE(v) == &BPyGPUShader_Type)
@@ -18,3 +24,44 @@ typedef struct BPyGPUShader {
 
 PyObject *BPyGPUShader_CreatePyObject(struct GPUShader *shader, bool is_builtin);
 PyObject *bpygpu_shader_init(void);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* gpu_py_shader_create_info.cc */
+
+extern PyTypeObject BPyGPUShaderCreateInfo_Type;
+extern PyTypeObject BPyGPUStageInterfaceInfo_Type;
+
+#define BPyGPUShaderCreateInfo_Check(v) (Py_TYPE(v) == &BPyGPUShaderCreateInfo_Type)
+#define BPyGPUStageInterfaceInfo_Check(v) (Py_TYPE(v) == &BPyGPUStageInterfaceInfo_Type)
+
+typedef struct BPyGPUStageInterfaceInfo {
+  PyObject_VAR_HEAD
+  struct GPUStageInterfaceInfo *interface;
+#ifdef USE_GPU_PY_REFERENCES
+  /* Just to keep a user to prevent freeing buf's we're using. */
+  PyObject *references;
+#endif
+} BPyGPUStageInterfaceInfo;
+
+typedef struct BPyGPUShaderCreateInfo {
+  PyObject_VAR_HEAD
+  struct GPUShaderCreateInfo *info;
+#ifdef USE_GPU_PY_REFERENCES
+  /* Just to keep a user to prevent freeing buf's we're using. */
+  PyObject *vertex_source;
+  PyObject *fragment_source;
+  PyObject *typedef_source;
+  PyObject *references;
+#endif
+  size_t constants_total_size;
+} BPyGPUShaderCreateInfo;
+
+PyObject *BPyGPUStageInterfaceInfo_CreatePyObject(struct GPUStageInterfaceInfo *interface);
+PyObject *BPyGPUShaderCreateInfo_CreatePyObject(struct GPUShaderCreateInfo *info);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/python/gpu/gpu_py_shader_create_info.cc b/source/blender/python/gpu/gpu_py_shader_create_info.cc
new file mode 100644
index 00000000000..caf71ad5980
--- /dev/null
+++ b/source/blender/python/gpu

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list