From b60e61396b7b4bc54f4e628118586ab168775671 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 9 Jul 2021 09:51:22 +0200 Subject: Rename to ShaderBlocks --- source/blender/gpu/CMakeLists.txt | 2 +- source/blender/gpu/GPU_shader.h | 2 +- source/blender/gpu/GPU_shader_block_types.h | 46 ++++ source/blender/gpu/GPU_uniform_buffer_types.h | 46 ---- source/blender/gpu/intern/gpu_shader_block.cc | 270 ++++++++++++++++++++ source/blender/gpu/intern/gpu_shader_block.hh | 100 ++++++++ source/blender/gpu/intern/gpu_shader_private.hh | 9 +- .../gpu/intern/gpu_uniform_buffer_private.hh | 66 +---- .../gpu/intern/gpu_uniform_buffer_structs.cc | 272 --------------------- source/blender/gpu/opengl/gl_shader.cc | 5 +- source/blender/gpu/opengl/gl_shader_interface.cc | 6 +- source/blender/gpu/opengl/gl_shader_interface.hh | 4 +- .../gpu/tests/gpu_uniform_buffer_struct_test.cc | 18 +- 13 files changed, 440 insertions(+), 406 deletions(-) create mode 100644 source/blender/gpu/GPU_shader_block_types.h delete mode 100644 source/blender/gpu/GPU_uniform_buffer_types.h create mode 100644 source/blender/gpu/intern/gpu_shader_block.cc create mode 100644 source/blender/gpu/intern/gpu_shader_block.hh delete mode 100644 source/blender/gpu/intern/gpu_uniform_buffer_structs.cc diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index ab85a80b57c..267cda4f38a 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -81,13 +81,13 @@ set(SRC intern/gpu_select_pick.c intern/gpu_select_sample_query.cc intern/gpu_shader.cc + intern/gpu_shader_block.cc intern/gpu_shader_builtin.c intern/gpu_shader_log.cc intern/gpu_shader_interface.cc intern/gpu_state.cc intern/gpu_texture.cc intern/gpu_uniform_buffer.cc - intern/gpu_uniform_buffer_structs.cc intern/gpu_vertex_buffer.cc intern/gpu_vertex_format.cc intern/gpu_viewport.c diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h index b1fefcdeb36..600ab5c1808 100644 --- a/source/blender/gpu/GPU_shader.h +++ b/source/blender/gpu/GPU_shader.h @@ -23,7 +23,7 @@ #pragma once -#include "GPU_uniform_buffer_types.h" +#include "GPU_shader_block_types.h" #ifdef __cplusplus extern "C" { diff --git a/source/blender/gpu/GPU_shader_block_types.h b/source/blender/gpu/GPU_shader_block_types.h new file mode 100644 index 00000000000..fb372582311 --- /dev/null +++ b/source/blender/gpu/GPU_shader_block_types.h @@ -0,0 +1,46 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2021 Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup gpu + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum GPUShaderBlockType { + GPU_SHADER_BLOCK_CUSTOM = 0, + GPU_SHADER_BLOCK_3D_COLOR, + GPU_NUM_SHADER_BLOCK_TYPES, /* Special value, denotes number of structs. */ +} GPUShaderBlockType; + +typedef struct GPUShaderBlock3dColor { + float ModelMatrix[4][4]; + float ModelViewProjectionMatrix[4][4]; + float color[4]; + float WorldClipPlanes[6][4]; + int SrgbTransform; +} GPUShaderBlock3dColor; + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/gpu/GPU_uniform_buffer_types.h b/source/blender/gpu/GPU_uniform_buffer_types.h deleted file mode 100644 index fb372582311..00000000000 --- a/source/blender/gpu/GPU_uniform_buffer_types.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2021 Blender Foundation. - * All rights reserved. - */ - -/** \file - * \ingroup gpu - */ - -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum GPUShaderBlockType { - GPU_SHADER_BLOCK_CUSTOM = 0, - GPU_SHADER_BLOCK_3D_COLOR, - GPU_NUM_SHADER_BLOCK_TYPES, /* Special value, denotes number of structs. */ -} GPUShaderBlockType; - -typedef struct GPUShaderBlock3dColor { - float ModelMatrix[4][4]; - float ModelViewProjectionMatrix[4][4]; - float color[4]; - float WorldClipPlanes[6][4]; - int SrgbTransform; -} GPUShaderBlock3dColor; - -#ifdef __cplusplus -} -#endif diff --git a/source/blender/gpu/intern/gpu_shader_block.cc b/source/blender/gpu/intern/gpu_shader_block.cc new file mode 100644 index 00000000000..a10bf4a332c --- /dev/null +++ b/source/blender/gpu/intern/gpu_shader_block.cc @@ -0,0 +1,270 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2021 Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup gpu + */ + +#include "gpu_uniform_buffer_private.hh" + +#include "MEM_guardedalloc.h" + +#include "GPU_shader.h" +#include "gpu_shader_block.hh" +#include "gpu_shader_interface.hh" + +namespace blender::gpu { + +/* -------------------------------------------------------------------- */ +/** \name Attribute bindings + * \{ */ +const int BUILTIN_BINDING_LOCATION_OFFSET = 1000; + +static constexpr int to_binding_location(const GPUUniformBuiltin builtin_uniform) +{ + return BUILTIN_BINDING_LOCATION_OFFSET + builtin_uniform; +} + +static GPUUniformBuiltin to_builtin_uniform(int location) +{ + return static_cast(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 ShaderBlockType::AttributeBinding determine_binding_struct_1( + const GPUUniformBuiltin builtin_uniform) +{ + ShaderBlockType::AttributeBinding result = {-1, 0}; + + switch (builtin_uniform) { + case GPU_UNIFORM_MODEL: + result.binding = to_binding_location(builtin_uniform); + result.offset = offsetof(GPUShaderBlock3dColor, ModelMatrix); + break; + case GPU_UNIFORM_MVP: + result.binding = to_binding_location(builtin_uniform); + result.offset = offsetof(GPUShaderBlock3dColor, ModelViewProjectionMatrix); + break; + case GPU_UNIFORM_COLOR: + result.binding = to_binding_location(builtin_uniform); + result.offset = offsetof(GPUShaderBlock3dColor, color); + break; + case GPU_UNIFORM_CLIPPLANES: + result.binding = to_binding_location(builtin_uniform); + result.offset = offsetof(GPUShaderBlock3dColor, WorldClipPlanes); + break; + case GPU_UNIFORM_SRGB_TRANSFORM: + result.binding = to_binding_location(builtin_uniform); + result.offset = offsetof(GPUShaderBlock3dColor, SrgbTransform); + break; + + default: + break; + }; + + return result; +} + +static constexpr ShaderBlockType::AttributeBinding determine_binding( + const GPUShaderBlockType struct_type, const GPUUniformBuiltin builtin_uniform) +{ + + switch (struct_type) { + case GPU_SHADER_BLOCK_CUSTOM: + case GPU_NUM_SHADER_BLOCK_TYPES: + return {}; + + case GPU_SHADER_BLOCK_3D_COLOR: + return determine_binding_struct_1(builtin_uniform); + }; + return {}; +} + +static constexpr std::array +builtin_uniforms_for_struct_type(const GPUShaderBlockType 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, + GPU_NUM_SHADER_BLOCK_TYPES> + ATTRIBUTE_BINDINGS = { + builtin_uniforms_for_struct_type(GPU_SHADER_BLOCK_CUSTOM), + builtin_uniforms_for_struct_type(GPU_SHADER_BLOCK_3D_COLOR), +}; + +static constexpr size_t data_size_for(const GPUShaderBlockType struct_type) +{ + + switch (struct_type) { + case GPU_SHADER_BLOCK_CUSTOM: + case GPU_NUM_SHADER_BLOCK_TYPES: + return 0; + + case GPU_SHADER_BLOCK_3D_COLOR: + return sizeof(GPUShaderBlock3dColor); + }; + return 0; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Struct type + * \{ */ + +constexpr ShaderBlockType::ShaderBlockType(const GPUShaderBlockType type) + : type(type), m_attribute_bindings(ATTRIBUTE_BINDINGS[type]), m_data_size(data_size_for(type)) +{ +} + +bool ShaderBlockType::AttributeBinding::has_binding() const +{ + return binding != -1; +} + +bool ShaderBlockType::has_all_builtin_uniforms(const ShaderInterface &interface) const +{ + for (int i = 0; i < GPU_NUM_UNIFORMS; i++) { + const GPUUniformBuiltin builtin_uniform = static_cast(i); + const AttributeBinding &binding = attribute_binding(builtin_uniform); + const bool builtin_is_used = interface.builtins_[i] != -1; + const bool has_attribute = binding.has_binding(); + if (builtin_is_used && !has_attribute) { + return false; + } + } + return true; +} + +static constexpr std::array STRUCT_TYPE_INFOS = { + ShaderBlockType(GPU_SHADER_BLOCK_CUSTOM), + ShaderBlockType(GPU_SHADER_BLOCK_3D_COLOR), +}; + +const ShaderBlockType &ShaderBlockType::get(const GPUShaderBlockType type) +{ + return STRUCT_TYPE_INFOS[type]; +} + +std::optional find_smallest_uniform_builtin_struct( + const ShaderInterface &interface) +{ + if (!interface.has_builtin_uniforms()) { + return std::nullopt; + } + + if (ShaderBlockType::get(GPU_SHADER_BLOCK_3D_COLOR).has_all_builtin_uniforms(interface)) { + return std::make_optional(GPU_SHADER_BLOCK_3D_COLOR); + } + + return std::nullopt; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Struct type + * \{ */ + +ShaderBlockBuffer::ShaderBlockBuffer(const GPUShaderBlockType type) + : m_type_info(ShaderBlockType::get(type)) +{ + m_data = MEM_mallocN(m_type_info.data_size(), __func__); +} + +ShaderBlockBuffer::~ShaderBlockBuffer() +{ + MEM_freeN(m_data); + m_data = nullptr; +} + +bool ShaderBlockBuffer::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 ShaderBlockType::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 ShaderBlockBuffer::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 ShaderBlockType::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 diff --git a/source/blender/gpu/intern/gpu_shader_block.hh b/source/blender/gpu/intern/gpu_shader_block.hh new file mode 100644 index 00000000000..95e8524a334 --- /dev/null +++ b/source/blender/gpu/intern/gpu_shader_block.hh @@ -0,0 +1,100 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright 2020, Blender Foundation. + */ + +/** \file + * \ingroup gpu + */ + +#pragma once + +#include "BLI_sys_types.h" + +#include + +#include "GPU_shader_block_types.h" +#include "gpu_shader_interface.hh" + +#include + +namespace blender::gpu { + +class ShaderBlockType { + public: + constexpr ShaderBlockType(const GPUShaderBlockType type); + static const ShaderBlockType &get(const GPUShaderBlockType type); + + bool has_all_builtin_uniforms(const ShaderInterface &interface) const; + + GPUShaderBlockType type; + struct AttributeBinding { + int binding = -1; + size_t offset = 0; + + bool has_binding() const; + }; + + const AttributeBinding &attribute_binding(const GPUUniformBuiltin builtin_uniform) const + { + return m_attribute_bindings[builtin_uniform]; + } + + size_t data_size() const + { + return m_data_size; + } + + private: + const std::array &m_attribute_bindings; + const size_t m_data_size; +}; + +class ShaderBlockBuffer { + public: + struct Flags { + bool is_dirty : 1; + }; + + ShaderBlockBuffer(const GPUShaderBlockType type); + ShaderBlockBuffer(const ShaderBlockBuffer &other) = default; + ShaderBlockBuffer(ShaderBlockBuffer &&other) = default; + + ~ShaderBlockBuffer(); + + void *data() const + { + return m_data; + }; + + const ShaderBlockType &type_info() const + { + return m_type_info; + } + + 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: + Flags m_flags; + const ShaderBlockType &m_type_info; + void *m_data; +}; + +std::optional find_smallest_uniform_builtin_struct( + const ShaderInterface &interface); + +} // namespace blender::gpu diff --git a/source/blender/gpu/intern/gpu_shader_private.hh b/source/blender/gpu/intern/gpu_shader_private.hh index 4d9f39f758e..4f138e8a5fb 100644 --- a/source/blender/gpu/intern/gpu_shader_private.hh +++ b/source/blender/gpu/intern/gpu_shader_private.hh @@ -24,7 +24,8 @@ #include "BLI_string_ref.hh" #include "GPU_shader.h" -#include "GPU_uniform_buffer_types.h" +#include "GPU_shader_block_types.h" +#include "gpu_shader_block.hh" #include "gpu_shader_interface.hh" #include "gpu_uniform_buffer_private.hh" #include "gpu_vertex_buffer_private.hh" @@ -49,7 +50,7 @@ class Shader { /** For debugging purpose. */ char name[64]; - std::optional shader_struct; + std::optional shader_struct; public: Shader(const char *name); @@ -82,10 +83,10 @@ class Shader { return name; }; - UniformBuiltinStruct *m_shader_struct = nullptr; + ShaderBlockBuffer *m_shader_struct = nullptr; void set_shader_struct(GPUShaderBlockType struct_type) { - m_shader_struct = new UniformBuiltinStruct(struct_type); + m_shader_struct = new ShaderBlockBuffer(struct_type); } protected: diff --git a/source/blender/gpu/intern/gpu_uniform_buffer_private.hh b/source/blender/gpu/intern/gpu_uniform_buffer_private.hh index e2f1f29eb5d..bfce63f7504 100644 --- a/source/blender/gpu/intern/gpu_uniform_buffer_private.hh +++ b/source/blender/gpu/intern/gpu_uniform_buffer_private.hh @@ -27,7 +27,7 @@ #include #include "GPU_shader.h" -#include "GPU_uniform_buffer_types.h" +#include "GPU_shader_block_types.h" #include @@ -88,70 +88,6 @@ static inline const UniformBuf *unwrap(const GPUUniformBuf *vert) return reinterpret_cast(vert); } -class UniformBuiltinStructType { - public: - constexpr UniformBuiltinStructType(const GPUShaderBlockType type); - static const UniformBuiltinStructType &get(const GPUShaderBlockType type); - - bool has_all_builtin_uniforms(const ShaderInterface &interface) const; - - GPUShaderBlockType type; - struct AttributeBinding { - int binding = -1; - size_t offset = 0; - - bool has_binding() const; - }; - - const AttributeBinding &attribute_binding(const GPUUniformBuiltin builtin_uniform) const - { - return m_attribute_bindings[builtin_uniform]; - } - - size_t data_size() const - { - return m_data_size; - } - - private: - const std::array &m_attribute_bindings; - const size_t m_data_size; -}; - -class UniformBuiltinStruct { - public: - struct Flags { - bool is_dirty : 1; - }; - - UniformBuiltinStruct(const GPUShaderBlockType type); - UniformBuiltinStruct(const UniformBuiltinStruct &other) = default; - UniformBuiltinStruct(UniformBuiltinStruct &&other) = default; - - ~UniformBuiltinStruct(); - - void *data() const - { - return m_data; - }; - - const UniformBuiltinStructType &type_info() const - { - return m_type_info; - } - - 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: - Flags m_flags; - const UniformBuiltinStructType &m_type_info; - void *m_data; -}; - -std::optional find_smallest_uniform_builtin_struct( - const ShaderInterface &interface); - #undef DEBUG_NAME_LEN } // namespace gpu diff --git a/source/blender/gpu/intern/gpu_uniform_buffer_structs.cc b/source/blender/gpu/intern/gpu_uniform_buffer_structs.cc deleted file mode 100644 index 0f14a4ae8b0..00000000000 --- a/source/blender/gpu/intern/gpu_uniform_buffer_structs.cc +++ /dev/null @@ -1,272 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2021 Blender Foundation. - * All rights reserved. - */ - -/** \file - * \ingroup gpu - */ - -#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" - -namespace blender::gpu { - -/* -------------------------------------------------------------------- */ -/** \name Attribute bindings - * \{ */ -const int BUILTIN_BINDING_LOCATION_OFFSET = 1000; - -static constexpr int to_binding_location(const GPUUniformBuiltin builtin_uniform) -{ - return BUILTIN_BINDING_LOCATION_OFFSET + builtin_uniform; -} - -static GPUUniformBuiltin to_builtin_uniform(int location) -{ - return static_cast(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 = {-1, 0}; - - switch (builtin_uniform) { - case GPU_UNIFORM_MODEL: - result.binding = to_binding_location(builtin_uniform); - result.offset = offsetof(GPUShaderBlock3dColor, ModelMatrix); - break; - case GPU_UNIFORM_MVP: - result.binding = to_binding_location(builtin_uniform); - result.offset = offsetof(GPUShaderBlock3dColor, ModelViewProjectionMatrix); - break; - case GPU_UNIFORM_COLOR: - result.binding = to_binding_location(builtin_uniform); - result.offset = offsetof(GPUShaderBlock3dColor, color); - break; - case GPU_UNIFORM_CLIPPLANES: - result.binding = to_binding_location(builtin_uniform); - result.offset = offsetof(GPUShaderBlock3dColor, WorldClipPlanes); - break; - case GPU_UNIFORM_SRGB_TRANSFORM: - result.binding = to_binding_location(builtin_uniform); - result.offset = offsetof(GPUShaderBlock3dColor, SrgbTransform); - break; - - default: - break; - }; - - return result; -} - -static constexpr UniformBuiltinStructType::AttributeBinding determine_binding( - const GPUShaderBlockType struct_type, const GPUUniformBuiltin builtin_uniform) -{ - - switch (struct_type) { - case GPU_SHADER_BLOCK_CUSTOM: - case GPU_NUM_SHADER_BLOCK_TYPES: - return {}; - - case GPU_SHADER_BLOCK_3D_COLOR: - return determine_binding_struct_1(builtin_uniform); - }; - return {}; -} - -static constexpr std::array -builtin_uniforms_for_struct_type(const GPUShaderBlockType 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, - GPU_NUM_SHADER_BLOCK_TYPES> - ATTRIBUTE_BINDINGS = { - builtin_uniforms_for_struct_type(GPU_SHADER_BLOCK_CUSTOM), - builtin_uniforms_for_struct_type(GPU_SHADER_BLOCK_3D_COLOR), -}; - -static constexpr size_t data_size_for(const GPUShaderBlockType struct_type) -{ - - switch (struct_type) { - case GPU_SHADER_BLOCK_CUSTOM: - case GPU_NUM_SHADER_BLOCK_TYPES: - return 0; - - case GPU_SHADER_BLOCK_3D_COLOR: - return sizeof(GPUShaderBlock3dColor); - }; - return 0; -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Struct type - * \{ */ - -constexpr UniformBuiltinStructType::UniformBuiltinStructType(const GPUShaderBlockType 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(i); - const AttributeBinding &binding = attribute_binding(builtin_uniform); - const bool builtin_is_used = interface.builtins_[i] != -1; - const bool has_attribute = binding.has_binding(); - if (builtin_is_used && !has_attribute) { - return false; - } - } - return true; -} - -static constexpr std::array - STRUCT_TYPE_INFOS = { - UniformBuiltinStructType(GPU_SHADER_BLOCK_CUSTOM), - UniformBuiltinStructType(GPU_SHADER_BLOCK_3D_COLOR), -}; - -const UniformBuiltinStructType &UniformBuiltinStructType::get(const GPUShaderBlockType type) -{ - return STRUCT_TYPE_INFOS[type]; -} - -std::optional find_smallest_uniform_builtin_struct( - const ShaderInterface &interface) -{ - if (!interface.has_builtin_uniforms()) { - return std::nullopt; - } - - if (UniformBuiltinStructType::get(GPU_SHADER_BLOCK_3D_COLOR) - .has_all_builtin_uniforms(interface)) { - return std::make_optional(GPU_SHADER_BLOCK_3D_COLOR); - } - - return std::nullopt; -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Struct type - * \{ */ - -UniformBuiltinStruct::UniformBuiltinStruct(const GPUShaderBlockType 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 diff --git a/source/blender/gpu/opengl/gl_shader.cc b/source/blender/gpu/opengl/gl_shader.cc index 63ba0ab0a34..3d3b5f7649a 100644 --- a/source/blender/gpu/opengl/gl_shader.cc +++ b/source/blender/gpu/opengl/gl_shader.cc @@ -225,9 +225,8 @@ bool GLShader::finalize() this->print_log(sources, log, "Linking", true, &parser); return false; } - const UniformBuiltinStructType *type_info = m_shader_struct != nullptr ? - &m_shader_struct->type_info() : - nullptr; + const ShaderBlockType *type_info = m_shader_struct != nullptr ? &m_shader_struct->type_info() : + nullptr; interface = new GLShaderInterface(type_info, shader_program_); return true; diff --git a/source/blender/gpu/opengl/gl_shader_interface.cc b/source/blender/gpu/opengl/gl_shader_interface.cc index c5c8e2397d1..23435a2e0ee 100644 --- a/source/blender/gpu/opengl/gl_shader_interface.cc +++ b/source/blender/gpu/opengl/gl_shader_interface.cc @@ -145,7 +145,7 @@ static inline int ssbo_binding(int32_t program, uint32_t ssbo_index) /** \name Creation / Destruction * \{ */ -GLShaderInterface::GLShaderInterface(const UniformBuiltinStructType *type_info, GLuint program) +GLShaderInterface::GLShaderInterface(const ShaderBlockType *type_info, GLuint program) { /* Necessary to make #glUniform works. */ glUseProgram(program); @@ -191,7 +191,7 @@ GLShaderInterface::GLShaderInterface(const UniformBuiltinStructType *type_info, if (type_info) { for (int i = 0; i < GPU_NUM_UNIFORMS; i++) { const GPUUniformBuiltin builtin_uniform = static_cast(i); - const UniformBuiltinStructType::AttributeBinding &binding = type_info->attribute_binding( + const ShaderBlockType::AttributeBinding &binding = type_info->attribute_binding( builtin_uniform); if (binding.has_binding()) { uniform_len++; @@ -298,7 +298,7 @@ GLShaderInterface::GLShaderInterface(const UniformBuiltinStructType *type_info, if (type_info) { for (int i = 0; i < GPU_NUM_UNIFORMS; i++) { const GPUUniformBuiltin builtin_uniform = static_cast(i); - const UniformBuiltinStructType::AttributeBinding &binding = type_info->attribute_binding( + const ShaderBlockType::AttributeBinding &binding = type_info->attribute_binding( builtin_uniform); if (binding.has_binding()) { ShaderInput *input = &inputs_[attr_len_ + ubo_len_ + uniform_len_++]; diff --git a/source/blender/gpu/opengl/gl_shader_interface.hh b/source/blender/gpu/opengl/gl_shader_interface.hh index 5125c885cc5..059c6681b1d 100644 --- a/source/blender/gpu/opengl/gl_shader_interface.hh +++ b/source/blender/gpu/opengl/gl_shader_interface.hh @@ -34,8 +34,8 @@ #include "glew-mx.h" +#include "gpu_shader_block.hh" #include "gpu_shader_interface.hh" -#include "gpu_uniform_buffer_private.hh" namespace blender::gpu { @@ -50,7 +50,7 @@ class GLShaderInterface : public ShaderInterface { Vector refs_; public: - GLShaderInterface(const UniformBuiltinStructType *type_info, GLuint program); + GLShaderInterface(const ShaderBlockType *type_info, GLuint program); ~GLShaderInterface(); void ref_add(GLVaoCache *ref); diff --git a/source/blender/gpu/tests/gpu_uniform_buffer_struct_test.cc b/source/blender/gpu/tests/gpu_uniform_buffer_struct_test.cc index 5e6a0ad2567..6bc5a0e2aed 100644 --- a/source/blender/gpu/tests/gpu_uniform_buffer_struct_test.cc +++ b/source/blender/gpu/tests/gpu_uniform_buffer_struct_test.cc @@ -3,8 +3,8 @@ #include "GPU_capabilities.h" #include "GPU_compute.h" #include "GPU_shader.h" -#include "GPU_uniform_buffer_types.h" -#include "gpu_uniform_buffer_private.hh" +#include "GPU_shader_block_types.h" +#include "gpu_shader_block.hh" #include "BLI_math.h" @@ -12,15 +12,15 @@ namespace blender::gpu::tests { TEST(GPUUniformStruct, struct1) { - UniformBuiltinStruct uniform_struct(GPU_SHADER_BLOCK_3D_COLOR); - const UniformBuiltinStructType &type_info = uniform_struct.type_info(); + ShaderBlockBuffer uniform_struct(GPU_SHADER_BLOCK_3D_COLOR); + const ShaderBlockType &type_info = uniform_struct.type_info(); const GPUShaderBlock3dColor *struct_data = static_cast( uniform_struct.data()); EXPECT_EQ(type_info.data_size(), sizeof(*struct_data)); /* ModelMatrix attribute. */ { - const UniformBuiltinStructType::AttributeBinding &binding = type_info.attribute_binding( + const ShaderBlockType::AttributeBinding &binding = type_info.attribute_binding( GPU_UNIFORM_MODEL); float m4[4][4]; unit_m4(m4); @@ -36,7 +36,7 @@ TEST(GPUUniformStruct, struct1) /* ModelViewProjectionMatrix attribute. */ { - const UniformBuiltinStructType::AttributeBinding &binding = type_info.attribute_binding( + const ShaderBlockType::AttributeBinding &binding = type_info.attribute_binding( GPU_UNIFORM_MVP); float m4[4][4]; unit_m4(m4); @@ -52,7 +52,7 @@ TEST(GPUUniformStruct, struct1) /* Color attribute. */ { - const UniformBuiltinStructType::AttributeBinding &binding = type_info.attribute_binding( + const ShaderBlockType::AttributeBinding &binding = type_info.attribute_binding( GPU_UNIFORM_COLOR); float color[4] = {1.0f, 0.0f, 1.0f, 1.0f}; const bool result = uniform_struct.uniform_float(binding.binding, 4, 1, color); @@ -64,7 +64,7 @@ TEST(GPUUniformStruct, struct1) /* WorldClipPlanes attribute. */ { - const UniformBuiltinStructType::AttributeBinding &binding = type_info.attribute_binding( + const ShaderBlockType::AttributeBinding &binding = type_info.attribute_binding( GPU_UNIFORM_CLIPPLANES); float clip_planes[6][4] = { @@ -88,7 +88,7 @@ TEST(GPUUniformStruct, struct1) /* SrgbTransform attribute. */ { - const UniformBuiltinStructType::AttributeBinding &binding = type_info.attribute_binding( + const ShaderBlockType::AttributeBinding &binding = type_info.attribute_binding( GPU_UNIFORM_SRGB_TRANSFORM); int srgb_transform = true; const bool result = uniform_struct.uniform_int(binding.binding, 1, 1, &srgb_transform); -- cgit v1.2.3