Fix #114742: Draw: Buffers never shrink #114857
|
@ -69,7 +69,7 @@ class Instance {
|
|||
|
||||
void begin_sync()
|
||||
{
|
||||
resources.material_buf.clear();
|
||||
resources.material_buf.clear_and_trim();
|
||||
|
||||
opaque_ps.sync(scene_state, resources);
|
||||
transparent_ps.sync(scene_state, resources);
|
||||
|
|
|
@ -373,6 +373,20 @@ class StorageArrayBuffer : public detail::StorageCommon<T, len, device_only> {
|
|||
return this->data_[index];
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure the allocated size is not much larger than the currently required size,
|
||||
* using the same heuristic as `get_or_resize`.
|
||||
*/
|
||||
void trim_to_next_power_of_2(int64_t required_size)
|
||||
{
|
||||
/* Don't go below the size used at creation. */
|
||||
required_size = std::max(required_size, len);
|
||||
size_t target_size = power_of_2_max_u(required_size);
|
||||
if (this->len_ > target_size) {
|
||||
this->resize(target_size);
|
||||
}
|
||||
}
|
||||
|
||||
int64_t size() const
|
||||
{
|
||||
return this->len_;
|
||||
|
@ -414,6 +428,16 @@ class StorageVectorBuffer : public StorageArrayBuffer<T, len, false> {
|
|||
item_len_ = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set item count to zero
|
||||
* and trim the buffer if current size is much larger than the current item count.
|
||||
*/
|
||||
void clear_and_trim()
|
||||
{
|
||||
this->trim_to_next_power_of_2(item_len_);
|
||||
clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert a new element at the end of the vector.
|
||||
* This might cause a reallocation with the capacity is exceeded.
|
||||
|
|
|
@ -701,7 +701,7 @@ void DrawMultiBuf::bind(RecordingState &state,
|
|||
prototype_buf_.push_update();
|
||||
/* Allocate enough for the expansion pass. */
|
||||
resource_id_buf_.get_or_resize(resource_id_count_ * (use_custom_ids ? 2 : 1));
|
||||
/* Two command per group. */
|
||||
/* Two commands per group (inverted and non-inverted scale). */
|
||||
command_buf_.get_or_resize(group_count_ * 2);
|
||||
|
||||
if (prototype_count_ > 0) {
|
||||
|
|
|
@ -443,7 +443,10 @@ class DrawCommandBuf {
|
|||
uint resource_id_count_ = 0;
|
||||
|
||||
public:
|
||||
void clear(){};
|
||||
void clear()
|
||||
{
|
||||
resource_id_buf_.trim_to_next_power_of_2(resource_id_count_);
|
||||
};
|
||||
|
||||
void append_draw(Vector<Header, 0> &headers,
|
||||
Vector<Undetermined, 0> &commands,
|
||||
|
@ -554,6 +557,11 @@ class DrawMultiBuf {
|
|||
public:
|
||||
void clear()
|
||||
{
|
||||
group_buf_.trim_to_next_power_of_2(group_count_);
|
||||
/* Two commands per group (inverted and non-inverted scale). */
|
||||
command_buf_.trim_to_next_power_of_2(group_count_ * 2);
|
||||
prototype_buf_.trim_to_next_power_of_2(prototype_count_);
|
||||
resource_id_buf_.trim_to_next_power_of_2(resource_id_count_);
|
||||
header_id_counter_ = 0;
|
||||
group_count_ = 0;
|
||||
prototype_count_ = 0;
|
||||
|
|
|
@ -32,6 +32,11 @@ void Manager::begin_sync()
|
|||
bounds_buf.swap();
|
||||
infos_buf.swap();
|
||||
|
||||
matrix_buf.current().trim_to_next_power_of_2(resource_len_);
|
||||
bounds_buf.current().trim_to_next_power_of_2(resource_len_);
|
||||
infos_buf.current().trim_to_next_power_of_2(resource_len_);
|
||||
attributes_buf.trim_to_next_power_of_2(attribute_len_);
|
||||
|
||||
/* TODO: This means the reference is kept until further redraw or manager tear-down. Instead,
|
||||
* they should be released after each draw loop. But for now, mimics old DRW behavior. */
|
||||
for (GPUTexture *texture : acquired_textures) {
|
||||
|
|
Loading…
Reference in New Issue