diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2022-08-26 15:19:28 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2022-08-26 15:48:34 +0300 |
commit | d5b1085aa7ad15caf3dbfcc14290faf6447a770a (patch) | |
tree | 69f2a2b5f497aae6a71b324b7320698d495b5b74 | |
parent | 7efa5647fa05a22bd067893132c2bfc58b4430d0 (diff) |
Add Pass::material_set()
-rw-r--r-- | source/blender/draw/intern/draw_manager.cc | 18 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager.hh | 36 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_pass.hh | 55 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_resource.hh | 1 | ||||
-rw-r--r-- | source/blender/draw/tests/draw_pass_test.cc | 1 |
5 files changed, 106 insertions, 5 deletions
diff --git a/source/blender/draw/intern/draw_manager.cc b/source/blender/draw/intern/draw_manager.cc index 38a37c3f01e..a1b1673ef6e 100644 --- a/source/blender/draw/intern/draw_manager.cc +++ b/source/blender/draw/intern/draw_manager.cc @@ -10,12 +10,30 @@ #include "draw_manager.h" #include "draw_manager.hh" +#include "draw_pass.hh" #include "draw_shader.h" namespace blender::draw { +Manager::~Manager() +{ + for (GPUTexture *texture : acquired_textures) { + /* Decrease refcount and free if 0. */ + GPU_texture_free(texture); + } +} + void Manager::begin_sync() { + /* TODO: This means the reference is kept until further redraw or manager teardown. Instead, they + * should be released after each draw loop. But for now, mimics old DRW behavior. */ + for (GPUTexture *texture : acquired_textures) { + /* Decrease refcount and free if 0. */ + GPU_texture_free(texture); + } + + acquired_textures.clear(); + #ifdef DEBUG /* Detect non-init data. */ memset(matrix_buf.data(), 0xF0, resource_len_ * sizeof(*matrix_buf.data())); diff --git a/source/blender/draw/intern/draw_manager.hh b/source/blender/draw/intern/draw_manager.hh index a0aa73e242b..98de25290e0 100644 --- a/source/blender/draw/intern/draw_manager.hh +++ b/source/blender/draw/intern/draw_manager.hh @@ -10,7 +10,6 @@ #include "BLI_sys_types.h" -#include "draw_pass.hh" #include "draw_resource.hh" #include "draw_view.hh" @@ -18,6 +17,20 @@ namespace blender::draw { +/* Forward declarations. */ + +namespace detail { +template<typename T> class Pass; +} // namespace detail + +namespace command { +class DrawCommandBuf; +class DrawMultiBuf; +} // namespace command + +using PassSimple = detail::Pass<command::DrawCommandBuf>; +using PassMain = detail::Pass<command::DrawMultiBuf>; + class Manager { using ObjectMatricesBuf = StorageArrayBuffer<ObjectMatrices, 128>; using ObjectBoundsBuf = StorageArrayBuffer<ObjectBounds, 128>; @@ -48,6 +61,10 @@ class Manager { ObjectBoundsBuf bounds_buf; ObjectInfosBuf infos_buf; + /** List of textures coming from Image data-blocks. They need to be refcounted in order to avoid + * beeing freed in another thread. */ + Vector<GPUTexture *> acquired_textures; + private: uint resource_len_ = 0; Object *object = nullptr; @@ -55,9 +72,12 @@ class Manager { Object *object_active = nullptr; public: + Manager(){}; + ~Manager(); + /** - * Create a new resource handle for the given object. Can be called multiple time with the same - * object **successively** without duplicating the data. + * Create a new resource handle for the given object. Can be called multiple time with the + * same object **successively** without duplicating the data. */ ResourceHandle resource_handle(const ObjectRef ref); /** @@ -99,6 +119,16 @@ class Manager { */ DataDebugOutput data_debug(); + /** + * Will acquire the texture using ref counting and release it after drawing. To be used for + * texture coming from blender Image. + */ + void acquire_texture(GPUTexture *texture) + { + GPU_texture_ref(texture); + acquired_textures.append(texture); + } + /** TODO(fclem): The following should become private at some point. */ void begin_sync(); void end_sync(); diff --git a/source/blender/draw/intern/draw_pass.hh b/source/blender/draw/intern/draw_pass.hh index eef5f59f11a..03d6e739929 100644 --- a/source/blender/draw/intern/draw_pass.hh +++ b/source/blender/draw/intern/draw_pass.hh @@ -32,15 +32,21 @@ * ResourceBind ref) it will have to be re-recorded if any of these reference becomes invalid. */ +#include "BKE_image.h" #include "BLI_vector.hh" #include "DRW_gpu_wrapper.hh" #include "GPU_debug.h" +#include "GPU_material.h" #include "draw_command.hh" #include "draw_handle.hh" +#include "draw_manager.hh" +#include "draw_pass.hh" #include "draw_shader_shared.h" #include "draw_state.h" +#include "intern/gpu_codegen.h" + namespace blender::draw { using namespace blender::draw; @@ -132,6 +138,13 @@ class PassBase { void shader_set(GPUShader *shader); /** + * Bind a material shader along with its associated resources. Any following bind() or + * push_constant() call will use its interface. + * IMPORTANT: Assumes material is compiled and can be used (no compilation error). + */ + void material_set(Manager &manager, GPUMaterial *material); + + /** * Record a draw call. * NOTE: Setting the count or first to -1 will use the values from the batch. * NOTE: An instance or vertex count of 0 will discard the draw call. It will not be recorded. @@ -301,7 +314,7 @@ template<typename DrawCommandBufType> class Pass : public detail::PassBase<DrawC /** * Normal pass type. No visibility or draw-call optimisation. */ -using PassSimple = detail::Pass<DrawCommandBuf>; +// using PassSimple = detail::Pass<DrawCommandBuf>; /** * Main pass type. @@ -310,7 +323,7 @@ using PassSimple = detail::Pass<DrawCommandBuf>; * IMPORTANT: To be used only for passes containing lots of draw calls since it has a potentially * high overhead due to batching and culling optimizations. */ -using PassMain = detail::Pass<DrawMultiBuf>; +// using PassMain = detail::Pass<DrawMultiBuf>; /** \} */ @@ -617,6 +630,44 @@ template<class T> inline void PassBase<T>::shader_set(GPUShader *shader) create_command(Type::ShaderBind).shader_bind = {shader}; } +template<class T> inline void PassBase<T>::material_set(Manager &manager, GPUMaterial *material) +{ + GPUPass *gpupass = GPU_material_get_pass(material); + shader_set(GPU_pass_shader_get(gpupass)); + + /* Bind all textures needed by the material. */ + ListBase textures = GPU_material_textures(material); + for (GPUMaterialTexture *tex : ListBaseWrapper<GPUMaterialTexture>(textures)) { + if (tex->ima) { + /* Image */ + ImageUser *iuser = tex->iuser_available ? &tex->iuser : nullptr; + if (tex->tiled_mapping_name[0]) { + GPUTexture *tiles = BKE_image_get_gpu_tiles(tex->ima, iuser, nullptr); + manager.acquire_texture(tiles); + bind(tex->sampler_name, tiles, (eGPUSamplerState)tex->sampler_state); + + GPUTexture *tile_map = BKE_image_get_gpu_tilemap(tex->ima, iuser, nullptr); + manager.acquire_texture(tile_map); + bind(tex->tiled_mapping_name, tile_map, (eGPUSamplerState)tex->sampler_state); + } + else { + GPUTexture *texture = BKE_image_get_gpu_texture(tex->ima, iuser, nullptr); + manager.acquire_texture(texture); + bind(tex->sampler_name, texture, (eGPUSamplerState)tex->sampler_state); + } + } + else if (tex->colorband) { + /* Color Ramp */ + bind(tex->sampler_name, *tex->colorband); + } + } + + GPUUniformBuf *ubo = GPU_material_uniform_buffer_get(material); + if (ubo != nullptr) { + bind(GPU_UBO_BLOCK_NAME, ubo); + } +} + /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/draw/intern/draw_resource.hh b/source/blender/draw/intern/draw_resource.hh index 8e942d584bc..97cb7c55392 100644 --- a/source/blender/draw/intern/draw_resource.hh +++ b/source/blender/draw/intern/draw_resource.hh @@ -17,6 +17,7 @@ #include "BKE_volume.h" #include "BLI_hash.h" #include "DNA_curve_types.h" +#include "DNA_layer_types.h" #include "DNA_meta_types.h" #include "DNA_object_types.h" diff --git a/source/blender/draw/tests/draw_pass_test.cc b/source/blender/draw/tests/draw_pass_test.cc index 2d72796e5e9..ca32c4f1f29 100644 --- a/source/blender/draw/tests/draw_pass_test.cc +++ b/source/blender/draw/tests/draw_pass_test.cc @@ -3,6 +3,7 @@ #include "testing/testing.h" #include "draw_manager.hh" +#include "draw_pass.hh" #include "draw_shader.h" #include "draw_testing.hh" |