Commit Graph

140 Commits

Author SHA1 Message Date
Hans Goudey
a9e6417e19 Cleanup: Remove unnecessary mutex for draw attribute requests
As noted in [0], locking or atomics are not required for merging
requests for a single mesh, because there is no multithreaded iteration
over objects that will process the same mesh in multiple threads. This
locking was  added preemptively over the years and has made code
needlessly complicated, even while the final design for parallel object
iteration isn't completely clear. This PR removes the locks to simplify
some changes necessary for mesh attribute storage refactors.

[0]: b6764e77ef

Pull Request: https://projects.blender.org/blender/blender/pulls/141405
2025-07-03 19:14:26 +02:00
Hans Goudey
4b4ed8bccc Mesh: Split paint overlay flag data from normals buffers
For paint modes the selection and visibility were encoded in in the W
component of the normals. Separating the normals  into a separate vertex
buffer, though it increases memory usage a bit in those paint modes,
means the status doesn't need to be computed outside of paint modes,
and the whole system becomes less convoluted and easier to optimize.
The particular optimization I have in mind is better caching of vertex
buffers, which gets much more complicated when the normals VBO contains
data like selection and visibility and depends on the paint mode.

Internally, a there are now three mesh draw batches that are specific to
the paint overlay. The GPU subdivision normals buffer is now just three
components rather than 4 components.

Pull Request: https://projects.blender.org/blender/blender/pulls/140156
2025-06-13 16:08:46 +02:00
Campbell Barton
9fff67ba1b Cleanup: rename UV flags for clarity
Use the `UV_FLAG_*` prefix for UV flags.
2025-06-12 13:25:22 +10:00
Hans Goudey
b6764e77ef Mesh: Extend GPU batch limit from 32 to 64
Some refactors (!140156) require adding a few more batches,
but we're already at the limit for how many we can add. This
commit makes the batch flag into a 64 bit integer. It might be
worth refactoring this more to use some system besides a flag,
but for now this simple change is best.

The atomic combination of requests wasn't actually required
and isn't supported for 64 bit integers, so it's just removed here.

Pull Request: https://projects.blender.org/blender/blender/pulls/140164
2025-06-11 18:17:49 +02:00
Hans Goudey
8f1f509368 Cleanup: GPU: Use smaller backing types for a few enums
This makes a few structs a little bit smaller.

Pull Request: https://projects.blender.org/blender/blender/pulls/140157
2025-06-11 18:17:28 +02:00
Clément Foucault
e57359726f GPU: VertexFormat: Use new data types
This prevents the use of unaligned data types in
vertex formats. These formats are not supported on many
platform.

This simplify the `GPUVertexFormat` class a lot as
we do not need packing shenanigans anymore and just
compute the vertex stride.

The old enums are kept for progressive porting of the
backends and user code.

This will break compatibility with python addons.

TODO:
- [x] Deprecation warning for PyGPU (4.5)
  - [x] Deprecate matrix attributes
- [x] Error handling for PyGPU (5.0)
- [x] Backends
  - [x] Metal
  - [x] OpenGL
  - [x] Vulkan

Pull Request: https://projects.blender.org/blender/blender/pulls/138846
2025-06-10 17:20:45 +02:00
Jacques Lucke
37388aaabf Merge branch 'blender-v4.5-release' 2025-06-09 08:31:09 +02:00
Jacques Lucke
fd2be0026a Fix #137236: performance regression with nonsensical face material indices
From what I know, we don't really have a good way to detect whether a material
index is non-sensical in the right places. That's because the same material
index on a mesh may not make sense on one object but can still make sense on
another. This is the issue we fixed in the first place when the regression was
introduced.

What we can do though is to check which exact material indices a mesh is
actually using (not just the maximum). This allows us to skip a lot of work for
unused material indices. This doesn't help when a mesh has thousands of unique
non-sensical material indices, but it should be an improvement in the majority
of cases.

This patch adds a cache of used material indices to `Mesh`. The drawing code
requests that cache if the maximum material index is above some threshold (16
currently). We don't want to compute it all the time, because it requires
iterating over the mesh (at least once, then it is cached). So it's only worth
the extra cost of the there is at least one large material index. The threshold
also ensure that the large majority of scenes is not affected by this patch
performance wise.

Pull Request: https://projects.blender.org/blender/blender/pulls/139781
2025-06-09 08:10:48 +02:00
Hans Goudey
59c65a7994 Mesh: Separate GPU subdivision normals and positions
Currently for the result of GPU subdivision, normals are stored in two
places. First, interleaved with the positions, and second, in a separate
"lnor" vertex buffer. This extra duplication costs 12 bytes of GPU
memory usage per subdivided face corner, which is quite a lot. It also
causes problems because it's inconsistent with the format used for
regular non-subdivided meshes, causing various hacks and issues
throughout the code.

This PR moves the normals into just the "lnor" vertex buffer. This
starts some code simplifications, but ends up still more complicated
than I'd like because some edit selection flags are still stored in the
fourth component of the normal vector. Tacking that makes this PR too
big, but it would be a good next step.

Pull Request: https://projects.blender.org/blender/blender/pulls/137158
2025-06-06 18:04:59 +02:00
Hans Goudey
77b14f2dcb Cleanup: Grammar: Fallback vs. fall back
The former is a noun or adjective, the latter is a verb.
2025-06-02 17:13:56 -04:00
Hans Goudey
a7e3a81c84 Cleanup: Use functional style case for eCustomDataType 2025-05-28 22:05:03 -04:00
Brecht Van Lommel
40642343b6 Fix #138978: Modifier cage option not working when GPU subdivision is off
Need an equivalent of DRW_object_get_data_for_drawing for the cage mesh,
to ensure proper comparison between meshes.

Pull Request: https://projects.blender.org/blender/blender/pulls/138987
2025-05-19 11:50:00 +02:00
Hans Goudey
7a125d5ebc Cleanup: Draw: Simplify trivial attribute requests clearing 2025-05-16 12:30:48 -04:00
Jeroen Bakker
729f6290b8 Fix: Draw: Asserts due to recent changes
cbcf421db7 could raise asserts as it
didn't use the `!is_empty()` function to test if the name is set.

Pull Request: https://projects.blender.org/blender/blender/pulls/138970
2025-05-16 11:20:53 +02:00
Hans Goudey
cbcf421db7 Cleanup: Draw: Use StringRef for attribute names
Avoid the need to measure string length potentially many times.
2025-05-15 14:53:51 -04:00
Hans Goudey
760cf70d63 Draw: Use VectorSet for generic attribute requests
Replace `DRW_Attributes` with a VectorSet of std::string. The max number of
attributes is still the same. The inline buffer size is 4, and std::string's inline
buffer is smaller than the previous char array size of 64, but it seems
reasonable to save those optimizations for shorter attribute names and
fewer attributes. In return we significantly decrease the size of the batch
caches, simplify the code, and remove the attribute name length limit.

I observed roughly an 8% increase in the 30k cube objects file, a change from
12 to 13 FPS. I'm guessing this is mostly because `VectorSet<std::string>` is
smaller than `DRW_Attributes`.

Pull Request: https://projects.blender.org/blender/blender/pulls/138946
2025-05-15 20:43:31 +02:00
Hans Goudey
eaa3dd0cd3 Refactor: Remove data type from draw attribute request struct
Similar to 93be6baa9c.

It doesn't make sense to store the type as part of the request
since we upload any generic attribute, and the vertex buffer
type is just chosen depending on the attribute's type in the
geometry anyway.

The code in `mesh_cd_calc_used_gpu_layers` is unfortunately
still way too complicated to remove the custom data layer lookup,
but this gets us one step closer.

Pull Request: https://projects.blender.org/blender/blender/pulls/138791
2025-05-13 13:35:30 +02:00
Hans Goudey
f2327a956b Cleanup: Remove disabled code
This only makes this function even more difficult to understand.
2025-05-12 16:38:14 -04:00
Hans Goudey
93be6baa9c Refactor: Remove domain from draw attribute request struct
Similar to b21cb20eeb.
This time the domain is removed. The idea is that the domain doesn't
change anything about how the attribute is stored on the vertex buffers
so it doesn't make sense as part of the request. If we continue that
logic to also remove the data type, we can avoid searching through the
geometry when creating the requests, instead handling invalid requests
when creating the buffers.

The complexity of the change comes from the fact that the request's
domain was used to determine whether the Curves drawing code needed to
interpolate the attribute to the evaluated points. This is now stored
separately in the curves cache. The change in the sculpt code is also
non-trivial since we delay more of the logic until after we have
looked up the attribute from the geometry.

Pull Request: https://projects.blender.org/blender/blender/pulls/138619
2025-05-12 21:16:15 +02:00
Hans Goudey
b21cb20eeb Refactor: Remove layer index from draw attribute request struct
The goal is to separate the draw attribute request from the
CustomData implementation. For the layer index this was
already started a while ago; it's only used in a couple places
and lookups are mostly name based anyway.

Conceptually the attribute request is just a request that the
extraction system create a buffer for a certain attribute name.
Information about where the attribute is stored doesn't fit.

Pull Request: https://projects.blender.org/blender/blender/pulls/138570
2025-05-08 16:55:23 +02:00
Hans Goudey
36130d5584 Fix #136837: Mesh incorrectly renders smooth with GPU subdivision in some cases
Caused by 9b70851d91.
That commit inadvertently switched the order of these definitions. Because the
vertex buffers created by GPU subdivision still have a different format than regular
mesh drawing (the position buffer also includes vertex normals), the order of these
VBOs in the batch matters, since "lnor" attribute can override another.

Pull Request: https://projects.blender.org/blender/blender/pulls/137000
2025-04-05 15:21:48 +02:00
T0MIS0N
24d08e0bae Overlay: Allow drawing UVs in Image Editor in any mode
**Problem**
When using Texture Paint mode, the Image Editor will show a UV Wireframe
to display the active object's UVs. In every other mode, this wireframe
is absent. This is currently a big problem for Sculpt Mode since the
Experimental Texture Paint system is a part of that mode, meaning that
the user can't see their UVs while they paint in Sculpt Mode. This is
also troublesome for users that would like to quickly view an object's
UVs without using Texture Paint Mode.

**Solution**
Since it's useful to be able to view an object's UVs at all times, the
Image Editor should display UV Wireframes in all Object Modes regardless
of the Image Editor's mode. This is the best solution since it means
that future Blender features, that would benefit from having a preview
of an object's UV Wireframes, will automatically have that option since
UV Wireframes are supported in all modes. Also, if a user doesn't want
to see UV Wireframes for any reason, it can be disabled with an Overlay
option.

Additionally, when multiple objects are selected, each object should
have its UV Wireframe drawn in the Image Editor. The selected objects
that aren't active should have less opaque wireframes to indicate which
wireframe belongs to the active object. This is the best approach for
having multiple objects selected since it allows the user to quickly
view the UV layout for all selected objects to troubleshoot UV problems,
like texture mapping. This is especially helpful when using a material
for multiple different objects.

An alternative solution would be to only show the UV Wireframe for the
active object, but this would be undesirable because it would make
troubleshooting UV positions tedious when working with multiple objects
since the user would need to select objects individually.

Co-authored-by: T0MIS0N <50230774+T0MIS0N@users.noreply.github.com>
Co-authored-by: Sean Kim <SeanCTKim@protonmail.com>
Pull Request: https://projects.blender.org/blender/blender/pulls/135102
2025-04-04 21:30:05 +02:00
Clément Foucault
9181485931 Fix #136235: Edit UV: Crash when modifying mesh in shaded viewport
This happened because the viewport was drawn after
the UV editor when some update occur (e.g. canceling an
operator). The requested UV edit batch would require only
one specific UV channel. The viewport, in need of a different
UV channel, requested a VBO rebuild (freing the old UV VBO)
but did not correctly clear the UV batches that were referencing
the said VBO. This lead to use after free which would sometime
works because the same memory would be reused for a random new
batch.

Pull Request: https://projects.blender.org/blender/blender/pulls/136780
2025-03-31 18:45:59 +02:00
Hans Goudey
ebe7259c65 Fix #136670: Missing update after UV editor selection
Typo in 9b70851d91.
2025-03-28 16:01:21 -04:00
Hans Goudey
ec2cdce657 Fix #136625: Crash switching to Texture Paint workspace
Simple mistake in 9b70851d91.
The batch creation info wasn't moved to the vector, so nothing happened;
it was never created.
2025-03-28 14:47:44 -04:00
Hans Goudey
9b1a5a1c43 Refactor: Draw: Further changes to mesh buffer extraction
Followup to 9b70851d91.

Return buffers by value rather than creating an empty/uninitialized
buffer first, then initializing it in an extraction function. This generally
makes the code easier to follow. And avoiding these half-created buffers
is an essential step to adding some sort of more global cache.

Pull Request: https://projects.blender.org/blender/blender/pulls/136570
2025-03-27 16:52:55 +01:00
Hans Goudey
3bca04b172 Cleanup: Remove matrix copy from MeshRenderData 2025-03-26 09:49:54 -04:00
Hans Goudey
9b70851d91 Draw: Refactor mesh extraction to avoid creating uninitialized buffers
The initial goal of this PR is to avoid creating vertex and index
buffers as part of the "request" phase of the drawing loop. Conflating
requesting and creating index buffers might not sound so bad, but it
ends up significantly complicating the whole process. It is also
incompatible with a future buffer cache that would allow avoiding
re-uploading mesh buffers.

Specifically, this means removing the use of `DRW_vbo_request` and
`DRW_ibo_request` from the mesh batch extraction process. Instead, a
list of buffer types is gathered based on the requested batches. Then
that list is filtered to find the batches that haven't been requested
yet. Overall I find the new process much easier to understand.

A few examples of simplifications this allows are avoiding allocating
`MeshRenderData` on the heap, and the removal of its `use_final_mesh`
member. That's just replaced by passing the necessary information
through the call stack.

Another notable difference is that for meshes, EEVEE's velocity module
now requests a batch that contains the buffer rather than just requesting
the buffer itself. This is just simpler to get working since it doesn't require
a separate code path.

The task graph argument for extraction is unused after this change. It wasn't
used effectively anyway; a simpler method of multithreading extractions is
used in this PR. I didn't remove it completely because it will probably be
repurposed in the next step of this project.

The next step in this project is to replace `MeshBufferList` with a
global cache that's keyed based on the mesh data that compromises each
batch, when possible (i.e. for non edit-mode meshes). This changes above
should be applied to other object types too.

Pull Request: https://projects.blender.org/blender/blender/pulls/135699
2025-03-25 18:09:38 +01:00
Clément Foucault
94c7c84bcd Refactor: DRW: Simplify the DRWContext classes and methods
This refactor part of `draw_manager_c.cc` to make it more understandable
and less bug prone.

- Splits the context handing to `draw_gpu_context.cc`
- Rename `draw_manager_c.cc` to `draw_context.cc`
- Merge `DRWContextState` into `DRWContext`
- Merge lots of static functions into `DRWContext` to avoid global access
- Deduplicate code between entry point functions
- Move context init logic to `DRWContext` constructor
- Move resource init logic to `DRWContext::acquire_data`
- Move extraction `TaskGraph` out of `DRWContext`
- Reduce / centralize complexity of enabling draw engines
- Reduce the amount of `drw_get` calls
- Remove unused code

Pull Request: https://projects.blender.org/blender/blender/pulls/135821
2025-03-13 13:47:02 +01:00
Hans Goudey
cd0956d72f Cleanup: Simplify check for sculpt BVH normals update in mesh draw code 2025-03-03 18:22:56 -05:00
Philipp Oeser
e4b36d677e Merge branch 'blender-v4.4-release' 2025-02-21 12:40:35 +01:00
Philipp Oeser
5cfc7b7c65 Fix #134825: Assert in draw code when enabling "Paint Mask"
This happend for meshes without UVs.
The call to `texpaint_request_active_uv` in
`DRW_mesh_batch_cache_get_surface_edges` is from 9c010c44f4.

Looks like this is not needed (assumed to be copy paste error).

Pull Request: https://projects.blender.org/blender/blender/pulls/134856
2025-02-21 12:40:21 +01:00
Brecht Van Lommel
c7a33a62a2 Cleanup: Directly include DNA_userdef_types.h and BLI_listbase.h
Instead of relying on them being included indirectly.

Pull Request: https://projects.blender.org/blender/blender/pulls/134406
2025-02-12 23:01:08 +01:00
Clément Foucault
7bdafde54c Fix #133138: Overlay: Assert displaying subdiv surface modifier in edit-mode
The cause was that the shader was expecting both `pos` and `nor`
attribute but only one would be extracted.
This is because the mesh has cage display on but the batch cache
wouldn't extract the `vbo.vnor`.

This patch just make sure the vertex normal just follow the same
condition as the other edit normals batches.
2025-02-03 19:04:05 +01:00
Jacques Lucke
2fda20e1db Fix #132099: crash when using same geometry on objects with different material counts
The core issue was that the geometry batch cache (e.g. `MeshBatchCache` or
`PointCloudBatchCache`) was dependent on the object. This is problematic when
the the same geometry is used with multiple different objects because the cache
can't be consistent with all of them.

Fortunately, the only thing that was retrieved from the object was the number of
material slots, so if that can be avoided we should be fine. We can't just use
the number of material slots stored on the geometry because that may have no
material slots but still has material indices which are overridden on the object
level.

The solution is to take make the number of materials for a geometry only
dependent on the actual `material_index` attribute and not on the number of
available slots. More specifically, we find the maximal referenced material
index and handle that many materials. This number does not depend on how many
material slots there are on the object, but it still allows the object to
override materials slots that the mesh references.

A downside is that the maximum material index has to be computed which often
requires an iteration over the mesh. Fortunately, we can cache that quite easily
and the computation can be done in parallel. Also we are probably able to
eagerly update the material index in many cases when it's set instead of
computing it lazily. That is not implemented in this patch though.

The largest part of the patch is making the maximal material index easily
available on all the geometry types. Besides that, the material API is slightly
replaced and the drawing code now makes use of the updated API.

Pull Request: https://projects.blender.org/blender/blender/pulls/133498
2025-01-24 12:05:25 +01:00
Hans Goudey
e07cd2b982 Cleanup: Remove unused and transitive includes in draw module
Especially through DRW_render.hh, there were a lot of unnecessary
includes almost everywhere in the module. This typically makes
dependencies less explicit and slows down compile times, so switch
to including what files actual use.

Pull Request: https://projects.blender.org/blender/blender/pulls/133450
2025-01-22 19:37:38 +01:00
Hans Goudey
6871fe8415 Cleanup: Use Span for GPU batch array
Pull Request: https://projects.blender.org/blender/blender/pulls/132464
2024-12-30 18:55:23 +01:00
Hans Goudey
ee7f30a371 Fix #131989: Mesh paint mode selection does not work
Caused by 839108f623.

The edit mapping was invalid so we just created a dummy GPU
batch for the selection edit data. But it was invalid because we
weren't in edit mode. The fix just requires tweaking the checks
for this data that's also used outside of edit mode.
2024-12-17 17:16:20 -05:00
Jacques Lucke
b8228303bc Materials: take object and geometry material slot counts into account
Previously, the number of material slots on the geometry (e.g. mesh) was the
ground truth. However, this had limitations in the case when the object had more
material slots than the evaluated geometry. All extra slots on the object were
ignored.

This patch changes the definition so that the number of materials used for
rendering is the maximum of the number of material slots on the geometry and on
the object. This also implies that one always needs a reference to an object
when determining that number, but that was fairly straight forward to achieve in
current code.

This patch also cleans up the material count handling a fair amount by using the
`BKE_object_material_*_eval` API more consistently instead of manually accessing
`totcol`. Cycles uses the the same API indirectly through RNA.

Pull Request: https://projects.blender.org/blender/blender/pulls/131869
2024-12-16 18:08:06 +01:00
Jacques Lucke
c36567d156 Revert "Materials: take object and geometry material slot counts into account"
This reverts commit 47c255e2da.

There are unexpected problems with mesh rendering. Looks like some `max(1, ...)`
are missing.
2024-12-13 16:54:08 +01:00
Jacques Lucke
47c255e2da Materials: take object and geometry material slot counts into account
Previously, the number of material slots on the geometry (e.g. mesh) was the
ground truth. However, this had limitations in the case when the object had more
material slots than the evaluated geometry. All extra slots on the object were
ignored.

This patch changes the definition so that the number of materials used for
rendering is the maximum of the number of material slots on the geometry and on
the object. This also implies that one always needs a reference to an object
when determining that number, but that was fairly straight forward to achieve in
current code.

This patch also cleans up the material count handling a fair amount by using the
`BKE_object_material_*_eval` API more consistently instead of manually accessing
`totcol`. Cycles uses the the same API indirectly through RNA.

Pull Request: https://projects.blender.org/blender/blender/pulls/131761
2024-12-13 15:47:04 +01:00
Campbell Barton
0de8ae8046 Cleanup: spelling in comments 2024-11-25 13:24:46 +11:00
Clément Foucault
170277f703 DRW: Batch Cache: Avoid dummy batch creating invalid draw calls
The vertex length of the batch was 1 which lead to invalid
drawcall if trying to render triangles or lines.

Setting a length of 0 allows the GPU module to bypass the
drawcall.
2024-11-24 01:02:55 +01:00
Hans Goudey
b5f9db919b Fix: Viewer node overlay broken after recent draw extraction fix
The viewer node is not edit mode data, it should be extracted from
a final evaluated mesh (that's just the mechanism that geometry
nodes uses to get the data to the engines. The requests were probably
just added to the bottom by mistake.
2024-11-23 16:45:55 -05:00
Hans Goudey
a4c9b691a0 Attributes: Add 2D 16 bit integer type
Add a `short2` attribute type, intended to store the existing
`CD_CUSTOMLOOPNORMAL` custom data type in order to move the custom
normal storage to generic attributes. This type probably won't get much
use besides that, but generally we don't have reasons not to add these
generic types, besides binary size. In the future we should consolidate
usage of `convert_to_static_type` to avoid large binary size increases
(about 700KB here) for this sort of addition.

This is the first step of #130484.

Pull Request: https://projects.blender.org/blender/blender/pulls/130530
2024-11-21 17:02:05 +01:00
Hans Goudey
839108f623 Fix #113377: Pass edit mesh pointer through modifiers
Currently replacing the Mesh during evaluation with the object info node
can cause us to use invalid original indices when the source object is
in edit mode. This is really a more fundamental problem though: we have
no way to tell whether an evaluated mesh actually corresponds to the
object's original mesh.

This commit changes to explicitly propagating the edit mesh pointer
through copied and changed meshes during modifier and nodes evaluation,
instead of just blindly copying the edit mode pointer from the original
mesh to the evaluated mesh. A benefit of not writing to the evaluated
mesh means it can be shared, potentially offering a future performance
improvement for uses of the object info node.

When we detect an invalid correspondence between the evaluated/original
meshes, we skip extracting the cage mesh's data and skip extracting edit
mesh data from the evaluated object.

This commit also moves the source of "object is in edit mode" truth in
the draw module from whether the evaluated mesh has an edit mode pointer
to the object's mode flag. That's a simplification that's also helpful
to reduce the strong linking between BMesh and edit mode.

Pull Request: https://projects.blender.org/blender/blender/pulls/120999
2024-11-21 16:42:00 +01:00
Hans Goudey
ab2f0f8876 Cleanup: Remove redundant "is edit mode" check in drawing code
Because everything is logical-and here, these two variables are redundant.

Pull Request: https://projects.blender.org/blender/blender/pulls/129915
2024-11-06 18:36:54 +01:00
Hans Goudey
0be2535369 Cleanup: Remame PBVH headers to "paint BVH"
The PBVH struct is now called `bke::pbvh::Tree`. Expanding the acronym
in the file name just a little should help developers find things and make
the connection to the "paint" concept that loosely ties sculpt mode and
other painting modes together a little stronger.

This rename also lets us replace the weird `_api.hh` historical part of
the file name without reusing the old `BKE_pbvh.hh` file name, which
would have probably made understanding the git history a bit harder.

Pull Request: https://projects.blender.org/blender/blender/pulls/129684
2024-11-01 17:27:07 +01:00
Hans Goudey
d33e708343 Refactor: Sculpt: Use function to access PBVH
Part of #118145.
In the future we want to move the ownership of the BVH tree to the
original mesh rather than `SculptSession`, in order to persist it
across some more general non-topology changing operations like
node tools. The first step of that change is replacing all places
that used `SculptSession::pbvh` for access with a function.
2024-09-05 14:16:40 -04:00
Hans Goudey
bd19212fb8 Refactor: Sculpt: Avoid BVH tree geometry pointers in normals update
Part of #118145.
There is some complexity in this area because the normals need to be
updated on the original geometry only when there is no deformation
or multires modifier. The simplest way to encapsulate that usage of
the original geometry for now was adding a separate function that
contains the lookup with a comment justifying it.
2024-08-14 23:19:39 -04:00