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:
authorClément Foucault <foucault.clem@gmail.com>2022-08-26 15:19:28 +0300
committerClément Foucault <foucault.clem@gmail.com>2022-08-26 15:48:34 +0300
commitd5b1085aa7ad15caf3dbfcc14290faf6447a770a (patch)
tree69f2a2b5f497aae6a71b324b7320698d495b5b74
parent7efa5647fa05a22bd067893132c2bfc58b4430d0 (diff)
Add Pass::material_set()
-rw-r--r--source/blender/draw/intern/draw_manager.cc18
-rw-r--r--source/blender/draw/intern/draw_manager.hh36
-rw-r--r--source/blender/draw/intern/draw_pass.hh55
-rw-r--r--source/blender/draw/intern/draw_resource.hh1
-rw-r--r--source/blender/draw/tests/draw_pass_test.cc1
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"