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:
authorJeroen Bakker <jeroen@blender.org>2021-07-07 13:36:25 +0300
committerJeroen Bakker <jeroen@blender.org>2021-07-07 13:36:25 +0300
commit8f2bb1b1f055b55f41165b00de58109dab6df8f9 (patch)
treed41aea830bff7989b9fdfb9d1431a196f060e659
parent0271c736a9f6aec1c326501a8e73bf8c12329882 (diff)
Use compile time inlining for buitin structs.
-rw-r--r--source/blender/gpu/intern/gpu_shader.cc2
-rw-r--r--source/blender/gpu/intern/gpu_uniform_buffer_private.hh49
-rw-r--r--source/blender/gpu/intern/gpu_uniform_buffer_structs.cc224
3 files changed, 248 insertions, 27 deletions
diff --git a/source/blender/gpu/intern/gpu_shader.cc b/source/blender/gpu/intern/gpu_shader.cc
index 373162d35f7..b71f46fb3fc 100644
--- a/source/blender/gpu/intern/gpu_shader.cc
+++ b/source/blender/gpu/intern/gpu_shader.cc
@@ -211,7 +211,7 @@ void GPU_shader_free(GPUShader *shader)
/* -------------------------------------------------------------------- */
/** \name Creation utils
* \{ */
-
+
GPUShader *GPU_shader_create(const char *vertcode,
const char *fragcode,
const char *geomcode,
diff --git a/source/blender/gpu/intern/gpu_uniform_buffer_private.hh b/source/blender/gpu/intern/gpu_uniform_buffer_private.hh
index b514b312c11..06ec14780a8 100644
--- a/source/blender/gpu/intern/gpu_uniform_buffer_private.hh
+++ b/source/blender/gpu/intern/gpu_uniform_buffer_private.hh
@@ -29,6 +29,8 @@
#include "GPU_shader.h"
#include "GPU_uniform_buffer_types.h"
+#include <array>
+
struct GPUUniformBuf;
namespace blender {
@@ -88,14 +90,55 @@ static inline const UniformBuf *unwrap(const GPUUniformBuf *vert)
class UniformBuiltinStructType {
public:
- UniformBuiltinStructType(const GPUUniformBuiltinStructType type);
+ constexpr UniformBuiltinStructType(const GPUUniformBuiltinStructType type);
+ static const UniformBuiltinStructType &get(const GPUUniformBuiltinStructType type);
+
+ bool has_all_builtin_uniforms(const ShaderInterface &interface) const;
GPUUniformBuiltinStructType type;
+ struct AttributeBinding {
+ int binding = -1;
+ size_t offset = -1;
- bool has_all_builtin_uniforms(const ShaderInterface &interface) const;
+ bool has_binding() const;
+ };
+
+ const AttributeBinding &attribute_binding(const GPUUniformBuiltin builtin_uniform) const
+ {
+ return m_attribute_bindings[builtin_uniform];
+ }
+
+ const size_t data_size() const
+ {
+ return m_data_size;
+ }
+
+ private:
+ const std::array<const AttributeBinding, GPU_NUM_UNIFORMS> &m_attribute_bindings;
+ const size_t m_data_size;
+};
+
+class UniformBuiltinStruct {
+ public:
+ struct Flags {
+ bool is_dirty : 1;
+ };
+
+ UniformBuiltinStruct(const GPUUniformBuiltinStructType type);
+ ~UniformBuiltinStruct();
+
+ void *data() const
+ {
+ return m_data;
+ };
+
+ bool uniform_int(int location, int comp_len, int array_size, const int *data);
+ bool uniform_float(int location, int comp_len, int array_size, const float *data);
private:
- bool has_attribute(const GPUUniformBuiltin builtin_uniform) const;
+ Flags m_flags;
+ const UniformBuiltinStructType &m_type_info;
+ void *m_data;
};
std::optional<const GPUUniformBuiltinStructType> find_smallest_uniform_builtin_struct(
diff --git a/source/blender/gpu/intern/gpu_uniform_buffer_structs.cc b/source/blender/gpu/intern/gpu_uniform_buffer_structs.cc
index 897d1088e43..bdb16d2ec54 100644
--- a/source/blender/gpu/intern/gpu_uniform_buffer_structs.cc
+++ b/source/blender/gpu/intern/gpu_uniform_buffer_structs.cc
@@ -23,6 +23,8 @@
#include "gpu_uniform_buffer_private.hh"
+#include "MEM_guardedalloc.h"
+
#include "GPU_shader.h"
#include "GPU_uniform_buffer_types.h"
#include "gpu_shader_interface.hh"
@@ -30,49 +32,168 @@
namespace blender::gpu {
/* -------------------------------------------------------------------- */
-/** \name Struct type
+/** \name Attribute bindings
* \{ */
+const int BUILTIN_BINDING_LOCATION_OFFSET = 1000;
-UniformBuiltinStructType::UniformBuiltinStructType(const GPUUniformBuiltinStructType type)
- : type(type)
+static constexpr int to_binding_location(const GPUUniformBuiltin builtin_uniform)
{
+ return BUILTIN_BINDING_LOCATION_OFFSET + builtin_uniform;
}
-bool UniformBuiltinStructType::has_attribute(const GPUUniformBuiltin builtin_uniform) const
+static GPUUniformBuiltin to_builtin_uniform(int location)
{
- switch (type) {
- case GPU_UNIFORM_STRUCT_NONE:
- return false;
+ return static_cast<GPUUniformBuiltin>(location - BUILTIN_BINDING_LOCATION_OFFSET);
+}
+
+static bool is_valid_location(int location)
+{
+ int builtin_uniform = location - BUILTIN_BINDING_LOCATION_OFFSET;
+ if (builtin_uniform < 0 || builtin_uniform >= GPU_NUM_UNIFORMS) {
+ return false;
+ }
+ return true;
+}
+
+static constexpr UniformBuiltinStructType::AttributeBinding determine_binding_struct_1(
+ const GPUUniformBuiltin builtin_uniform)
+{
+ UniformBuiltinStructType::AttributeBinding result;
+ switch (builtin_uniform) {
+ case GPU_UNIFORM_MODEL:
+ result.binding = to_binding_location(builtin_uniform);
+ result.offset = offsetof(GPUUniformBuiltinStruct1, ModelMatrix);
+ break;
+ case GPU_UNIFORM_MVP:
+ result.binding = to_binding_location(builtin_uniform);
+ result.offset = offsetof(GPUUniformBuiltinStruct1, ModelViewProjectionMatrix);
+ break;
+ case GPU_UNIFORM_COLOR:
+ result.binding = to_binding_location(builtin_uniform);
+ result.offset = offsetof(GPUUniformBuiltinStruct1, color);
+ break;
+ case GPU_UNIFORM_CLIPPLANES:
+ result.binding = to_binding_location(builtin_uniform);
+ result.offset = offsetof(GPUUniformBuiltinStruct1, WorldClipPlanes);
+ break;
+ case GPU_UNIFORM_SRGB_TRANSFORM:
+ result.binding = to_binding_location(builtin_uniform);
+ result.offset = offsetof(GPUUniformBuiltinStruct1, SrgbTransform);
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);
+ default:
break;
+ };
+
+ return result;
+}
+
+static constexpr UniformBuiltinStructType::AttributeBinding determine_binding(
+ const GPUUniformBuiltinStructType struct_type, const GPUUniformBuiltin builtin_uniform)
+{
+ switch (struct_type) {
+ case GPU_UNIFORM_STRUCT_NONE:
case GPU_NUM_UNIFORM_STRUCTS:
- return false;
- break;
- }
- return false;
+ return {};
+
+ case GPU_UNIFORM_STRUCT_1:
+ return determine_binding_struct_1(builtin_uniform);
+ };
+ return {};
+}
+
+static constexpr std::array<const UniformBuiltinStructType::AttributeBinding, GPU_NUM_UNIFORMS>
+builtin_uniforms_for_struct_type(const GPUUniformBuiltinStructType struct_type)
+{
+ return {
+ determine_binding(struct_type, GPU_UNIFORM_MODEL),
+ determine_binding(struct_type, GPU_UNIFORM_VIEW),
+ determine_binding(struct_type, GPU_UNIFORM_MODELVIEW),
+ determine_binding(struct_type, GPU_UNIFORM_PROJECTION),
+ determine_binding(struct_type, GPU_UNIFORM_VIEWPROJECTION),
+ determine_binding(struct_type, GPU_UNIFORM_MVP),
+ determine_binding(struct_type, GPU_UNIFORM_MODEL_INV),
+ determine_binding(struct_type, GPU_UNIFORM_VIEW_INV),
+ determine_binding(struct_type, GPU_UNIFORM_MODELVIEW_INV),
+ determine_binding(struct_type, GPU_UNIFORM_PROJECTION_INV),
+ determine_binding(struct_type, GPU_UNIFORM_VIEWPROJECTION_INV),
+ determine_binding(struct_type, GPU_UNIFORM_NORMAL),
+ determine_binding(struct_type, GPU_UNIFORM_ORCO),
+ determine_binding(struct_type, GPU_UNIFORM_CLIPPLANES),
+ determine_binding(struct_type, GPU_UNIFORM_COLOR),
+ determine_binding(struct_type, GPU_UNIFORM_BASE_INSTANCE),
+ determine_binding(struct_type, GPU_UNIFORM_RESOURCE_CHUNK),
+ determine_binding(struct_type, GPU_UNIFORM_RESOURCE_ID),
+ determine_binding(struct_type, GPU_UNIFORM_SRGB_TRANSFORM),
+ };
+}
+
+static constexpr std::array<
+ const std::array<const UniformBuiltinStructType::AttributeBinding, GPU_NUM_UNIFORMS>,
+ GPU_NUM_UNIFORM_STRUCTS>
+ ATTRIBUTE_BINDINGS = {
+ builtin_uniforms_for_struct_type(GPU_UNIFORM_STRUCT_NONE),
+ builtin_uniforms_for_struct_type(GPU_UNIFORM_STRUCT_1),
+};
+
+static constexpr size_t data_size_for(const GPUUniformBuiltinStructType struct_type)
+{
+
+ switch (struct_type) {
+ case GPU_UNIFORM_STRUCT_NONE:
+ case GPU_NUM_UNIFORM_STRUCTS:
+ return 0;
+
+ case GPU_UNIFORM_STRUCT_1:
+ return sizeof(GPUUniformBuiltinStruct1);
+ };
+ return 0;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Struct type
+ * \{ */
+
+constexpr UniformBuiltinStructType::UniformBuiltinStructType(
+ const GPUUniformBuiltinStructType type)
+ : type(type), m_attribute_bindings(ATTRIBUTE_BINDINGS[type]), m_data_size(data_size_for(type))
+{
+}
+
+bool UniformBuiltinStructType::AttributeBinding::has_binding() const
+{
+ return binding != -1;
}
bool UniformBuiltinStructType::has_all_builtin_uniforms(const ShaderInterface &interface) const
{
for (int i = 0; i < GPU_NUM_UNIFORMS; i++) {
const GPUUniformBuiltin builtin_uniform = static_cast<const GPUUniformBuiltin>(i);
+ const AttributeBinding &binding = attribute_binding(builtin_uniform);
const bool builtin_is_used = interface.builtins_[i] != -1;
- if (builtin_is_used && !has_attribute(builtin_uniform)) {
+ const bool has_attribute = binding.has_binding();
+ if (builtin_is_used && !has_attribute) {
return false;
}
}
return true;
}
+static constexpr std::array<UniformBuiltinStructType, GPU_NUM_UNIFORM_STRUCTS> STRUCT_TYPE_INFOS =
+ {
+ UniformBuiltinStructType(GPU_UNIFORM_STRUCT_NONE),
+ UniformBuiltinStructType(GPU_UNIFORM_STRUCT_1),
+};
+
+const UniformBuiltinStructType &UniformBuiltinStructType::get(
+ const GPUUniformBuiltinStructType type)
+{
+ return STRUCT_TYPE_INFOS[type];
+}
+
std::optional<const GPUUniformBuiltinStructType> find_smallest_uniform_builtin_struct(
const ShaderInterface &interface)
{
@@ -80,10 +201,8 @@ std::optional<const GPUUniformBuiltinStructType> find_smallest_uniform_builtin_s
return std::nullopt;
}
- const UniformBuiltinStructType struct1(GPU_UNIFORM_STRUCT_1);
-
- if (struct1.has_all_builtin_uniforms(interface)) {
- return std::make_optional(struct1.type);
+ if (UniformBuiltinStructType::get(GPU_UNIFORM_STRUCT_1).has_all_builtin_uniforms(interface)) {
+ return std::make_optional(GPU_UNIFORM_STRUCT_1);
}
return std::nullopt;
@@ -91,4 +210,63 @@ std::optional<const GPUUniformBuiltinStructType> find_smallest_uniform_builtin_s
/** \} */
+/* -------------------------------------------------------------------- */
+/** \name Struct type
+ * \{ */
+
+UniformBuiltinStruct::UniformBuiltinStruct(const GPUUniformBuiltinStructType type)
+ : m_type_info(UniformBuiltinStructType::get(type))
+{
+ m_data = MEM_mallocN(m_type_info.data_size(), __func__);
+}
+
+UniformBuiltinStruct::~UniformBuiltinStruct()
+{
+ MEM_freeN(m_data);
+ m_data = nullptr;
+}
+
+bool UniformBuiltinStruct::uniform_int(int location, int comp_len, int array_size, const int *data)
+{
+ if (is_valid_location(location)) {
+ return false;
+ }
+ const GPUUniformBuiltin builtin_uniform = to_builtin_uniform(location);
+ const UniformBuiltinStructType::AttributeBinding &attribute = m_type_info.attribute_binding(
+ builtin_uniform);
+
+ if (!attribute.has_binding()) {
+ return false;
+ }
+ const size_t attribute_len = comp_len * array_size * sizeof(int);
+ memcpy(((uint8_t *)m_data) + attribute.offset, data, attribute_len);
+ m_flags.is_dirty = true;
+
+ return true;
+}
+
+bool UniformBuiltinStruct::uniform_float(int location,
+ int comp_len,
+ int array_size,
+ const float *data)
+{
+ if (is_valid_location(location)) {
+ return false;
+ }
+ const GPUUniformBuiltin builtin_uniform = to_builtin_uniform(location);
+ const UniformBuiltinStructType::AttributeBinding &attribute = m_type_info.attribute_binding(
+ builtin_uniform);
+
+ if (!attribute.has_binding()) {
+ return false;
+ }
+ const size_t attribute_len = comp_len * array_size * sizeof(float);
+ memcpy(((uint8_t *)m_data) + attribute.offset, data, attribute_len);
+ m_flags.is_dirty = true;
+
+ return true;
+}
+
+/** \} */
+
} // namespace blender::gpu