diff options
author | Jeroen Bakker <jeroen@blender.org> | 2021-07-06 18:24:45 +0300 |
---|---|---|
committer | Jeroen Bakker <jeroen@blender.org> | 2021-07-06 18:24:45 +0300 |
commit | dd31aebf119f451f8738ec0b3f3d31125661bbec (patch) | |
tree | aa1ff34324183bd0b911adfd33e5a4b518e547b7 /source | |
parent | 7af40ccf5f22795da4122ac20c966a352cae4eaf (diff) |
GPU: Detect mathing struct based on shader interface.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/draw/intern/draw_manager_shader.c | 1 | ||||
-rw-r--r-- | source/blender/gpu/GPU_shader.h | 16 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_shader.cc | 25 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_shader_interface.cc | 63 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_shader_interface.hh | 7 |
5 files changed, 112 insertions, 0 deletions
diff --git a/source/blender/draw/intern/draw_manager_shader.c b/source/blender/draw/intern/draw_manager_shader.c index 83d0030f89b..4d7d32164bc 100644 --- a/source/blender/draw/intern/draw_manager_shader.c +++ b/source/blender/draw/intern/draw_manager_shader.c @@ -401,6 +401,7 @@ GPUShader *DRW_shader_create_with_transform_feedback(const char *vert, prim_type, varying_names, varying_count, + GPU_UNIFORM_STRUCT_NONE, __func__); } diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h index f834ee5b234..5bc47be0459 100644 --- a/source/blender/gpu/GPU_shader.h +++ b/source/blender/gpu/GPU_shader.h @@ -40,6 +40,12 @@ typedef enum eGPUShaderTFBType { GPU_SHADER_TFB_TRIANGLES = 3, } eGPUShaderTFBType; +typedef enum GPUUniformBuiltinStructType { + GPU_UNIFORM_STRUCT_NONE = 0, + GPU_UNIFORM_STRUCT_1, + GPU_NUM_UNIFORM_STRUCTS, /* Special value, denotes number of structs. */ +} GPUUniformBuiltinStructType; + GPUShader *GPU_shader_create(const char *vertcode, const char *fragcode, const char *geomcode, @@ -64,6 +70,7 @@ GPUShader *GPU_shader_create_ex(const char *vertcode, const eGPUShaderTFBType tf_type, const char **tf_names, const int tf_count, + const GPUUniformBuiltinStructType uniform_struct_type, const char *shname); struct GPU_ShaderCreateFromArray_Params { @@ -118,10 +125,19 @@ typedef enum { GPU_NUM_UNIFORMS, /* Special value, denotes number of builtin uniforms. */ } GPUUniformBuiltin; +typedef struct GPUUniformBuiltinStruct1 { + float ModelMatrix[4][4]; + float ModelViewProjectionMatrix[4][4]; + float color[4]; + float WorldClipPlanes[6][4]; + int SrgbTransform; +} GPUUniformBuiltinStruct1; + typedef enum { GPU_UNIFORM_BLOCK_VIEW = 0, /* viewBlock */ GPU_UNIFORM_BLOCK_MODEL, /* modelBlock */ GPU_UNIFORM_BLOCK_INFO, /* infoBlock */ + GPU_UNIFORM_BLOCK_SHADER, /* shaderBlock */ GPU_NUM_UNIFORM_BLOCKS, /* Special value, denotes number of builtin uniforms block. */ } GPUUniformBlockBuiltin; diff --git a/source/blender/gpu/intern/gpu_shader.cc b/source/blender/gpu/intern/gpu_shader.cc index c754a649924..310b506b2e5 100644 --- a/source/blender/gpu/intern/gpu_shader.cc +++ b/source/blender/gpu/intern/gpu_shader.cc @@ -23,6 +23,8 @@ #include "MEM_guardedalloc.h" +#include "BKE_global.h" + #include "BLI_string_utils.h" #include "GPU_capabilities.h" @@ -33,6 +35,10 @@ #include "gpu_context_private.hh" #include "gpu_shader_private.hh" +#include "CLG_log.h" + +static CLG_LogRef LOG = {"gpu.shader"}; + extern "C" char datatoc_gpu_shader_colorspace_lib_glsl[]; using namespace blender; @@ -94,6 +100,7 @@ GPUShader *GPU_shader_create_ex(const char *vertcode, const eGPUShaderTFBType tf_type, const char **tf_names, const int tf_count, + const GPUUniformBuiltinStructType uniform_struct_type, const char *shname) { /* At least a vertex shader and a fragment shader are required, or only a compute shader. */ @@ -175,6 +182,21 @@ GPUShader *GPU_shader_create_ex(const char *vertcode, return nullptr; }; + if (G.debug & G_DEBUG_GPU) { + std::optional<GPUUniformBuiltinStructType> best_struct_type = + shader->interface->best_builtin_uniform_struct(); + if (best_struct_type) { + if (/*uniform_struct_type != GPU_UNIFORM_STRUCT_NONE &&*/ + uniform_struct_type != *best_struct_type) { + CLOG_WARN(&LOG, + "Found better matching uniform struct for '%s'; current %d, suggested %d", + shname, + static_cast<int>(uniform_struct_type), + static_cast<int>(*best_struct_type)); + } + } + } + return wrap(shader); } @@ -205,6 +227,7 @@ GPUShader *GPU_shader_create(const char *vertcode, GPU_SHADER_TFB_NONE, nullptr, 0, + GPU_UNIFORM_STRUCT_NONE, shname); } @@ -222,6 +245,7 @@ GPUShader *GPU_shader_create_compute(const char *computecode, GPU_SHADER_TFB_NONE, nullptr, 0, + GPU_UNIFORM_STRUCT_NONE, shname); } @@ -249,6 +273,7 @@ GPUShader *GPU_shader_create_from_python(const char *vertcode, GPU_SHADER_TFB_NONE, nullptr, 0, + GPU_UNIFORM_STRUCT_NONE, "pyGPUShader"); MEM_SAFE_FREE(libcodecat); diff --git a/source/blender/gpu/intern/gpu_shader_interface.cc b/source/blender/gpu/intern/gpu_shader_interface.cc index ae94112b17b..a4d077eef61 100644 --- a/source/blender/gpu/intern/gpu_shader_interface.cc +++ b/source/blender/gpu/intern/gpu_shader_interface.cc @@ -129,4 +129,67 @@ void ShaderInterface::debug_print() printf("\n"); } +/* TODO(jbakker): move to new compile unit (GPU_uniform_structs.cc). */ + +static bool can_hold_element(const GPUUniformBuiltinStructType struct_type, + const GPUUniformBuiltin builtin_uniform) +{ + switch (struct_type) { + case GPU_UNIFORM_STRUCT_NONE: + return false; + break; + + case GPU_UNIFORM_STRUCT_1: + return ELEM(builtin_uniform, + GPU_UNIFORM_MODEL, + GPU_UNIFORM_MVP, + GPU_UNIFORM_COLOR, + GPU_UNIFORM_CLIPPLANES, + GPU_UNIFORM_SRGB_TRANSFORM); + break; + + case GPU_NUM_UNIFORM_STRUCTS: + return false; + break; + } + return false; +} + +static bool can_hold_data(const ShaderInterface &interface, + const GPUUniformBuiltinStructType struct_type) +{ + for (int i = 0; i < GPU_NUM_UNIFORMS; i++) { + const GPUUniformBuiltin builtin_uniform = static_cast<const GPUUniformBuiltin>(i); + const bool builtin_is_used = interface.builtins_[i] != -1; + if (builtin_is_used && !can_hold_element(struct_type, builtin_uniform)) { + return false; + } + } + return true; +} + +bool ShaderInterface::has_builtin_uniforms() const +{ + for (int i = 0; i < GPU_NUM_UNIFORMS; i++) { + if (builtins_[i] != -1) { + return true; + } + } + return false; +} + +std::optional<const GPUUniformBuiltinStructType> ShaderInterface::best_builtin_uniform_struct() + const +{ + if (!this->has_builtin_uniforms()) { + return std::nullopt; + } + + if (can_hold_data(*this, GPU_UNIFORM_STRUCT_1)) { + return std::make_optional(GPU_UNIFORM_STRUCT_1); + } + + return std::nullopt; +} + } // namespace blender::gpu diff --git a/source/blender/gpu/intern/gpu_shader_interface.hh b/source/blender/gpu/intern/gpu_shader_interface.hh index ebed7b15170..00afc4dde98 100644 --- a/source/blender/gpu/intern/gpu_shader_interface.hh +++ b/source/blender/gpu/intern/gpu_shader_interface.hh @@ -35,6 +35,8 @@ #include "GPU_shader.h" +#include <optional> + namespace blender::gpu { typedef struct ShaderInput { @@ -124,6 +126,8 @@ class ShaderInterface { return builtin_blocks_[builtin]; } + std::optional<const GPUUniformBuiltinStructType> best_builtin_uniform_struct() const; + protected: static inline const char *builtin_uniform_name(GPUUniformBuiltin u); static inline const char *builtin_uniform_block_name(GPUUniformBlockBuiltin u); @@ -141,6 +145,7 @@ class ShaderInterface { inline const ShaderInput *input_lookup(const ShaderInput *const inputs, const uint inputs_len, const int binding) const; + bool has_builtin_uniforms() const; }; inline const char *ShaderInterface::builtin_uniform_name(GPUUniformBuiltin u) @@ -202,6 +207,8 @@ inline const char *ShaderInterface::builtin_uniform_block_name(GPUUniformBlockBu return "modelBlock"; case GPU_UNIFORM_BLOCK_INFO: return "infoBlock"; + case GPU_UNIFORM_BLOCK_SHADER: + return "shaderBlock"; default: return NULL; } |