Skip to content

perf(gpui): batch-upload wgpu instances under resource budgets - #8

Merged
freefcw merged 3 commits into
develop/0.9from
cursor/wgpu-batch-upload-budget-bef0
Aug 29, 2026
Merged

perf(gpui): batch-upload wgpu instances under resource budgets#8
freefcw merged 3 commits into
develop/0.9from
cursor/wgpu-batch-upload-budget-bef0

Conversation

@freefcw

@freefcw freefcw commented Aug 29, 2026

Copy link
Copy Markdown
Owner

Port Zed be8c6f9 wgpu frame-start batch upload onto this fork’s existing GpuResourceBudget / AppResourceProfile watermarks. Dedicated renderer-path change, not a wholesale wgpu rewrite.

Rebased onto develop/0.9 at 1e1d854 (merged #7: demand-driven Wayland loop, font prewarm, hide/retry, shellcheck --source-path=scripts -x). This PR does not touch wgpu_context.rs; #3’s WGPU_BACKEND env honor remains on develop.

What landed

Zed bulk-uploads the whole scene’s instance arrays once at frame start, then draws from shared bind groups. That is more aggressive than the previous per-batch queue.write_buffer + retry-grow loop.

Locally that upload is now budget-aware:

Profile Initial Max growth
Desktop 2 MiB 256 MiB (Zed ceiling)
Utility 1 MiB 64 MiB
Minimal 512 KiB 16 MiB
Custom caller-set caller-set (max raised to initial if lower)

Growth still doubles from the profile allocation (not a hardcoded 2 MiB), is also limited by max_buffer_sizemax_storage_buffer_binding_size, and fails the frame instead of ballooning past the watermark.

The renderer now:

  1. Estimates the exact aligned instance bytes for the scene (including path vertices/sprites)
  2. Grows once to fit, under the profile/device cap
  3. Uploads each primitive array once and reuses one bind group per type
  4. Keeps device-lost recovery, atlas init, and Application::new() unchanged

Linux windows pass the full GpuResourceBudget into WgpuRenderer::new so atlas size, initial buffer, and max watermark travel together (including after GPU recovery). Wayland FrameLoop / PresentationState / hide() unmapped guards from #7 are unchanged.

Follow-ups on this branch (do not rewrite the Zed-Origin commit)

  • 89d2477 — do not present when batch upload fails; release-safe batch range check
  • 6f9ffc4GpuResourceBudget::new / Default so two-field construction still works; 0.9 changelog notes the struct-literal break

The previous shellcheck -x -P SCRIPTDIR follow-up was dropped: #7 already follows sourced scripts with shellcheck --source-path=scripts -x.

Sourcery’s per-draw texture bind-group cache note is a nit matching Zed; not changed.

Intentionally not pasted

  • Metal / DirectX hunks (Linux renderer is wgpu; Blade stays gone)
  • window.rs largest_border_interior (already covered by local border-only quad tests)
  • Zed WebGL instance-texture transport and subpixel-sprite pipelines (not present here)

Application::new() is unchanged. Zed-Origin: be8c6f9fb356dcd40a7ff06149568753e64ee171

Open in Web Open in Cursor 

Sourcery 摘要

通过在每帧内按批次处理实例数据,并遵循配置文件和设备的资源限制,使 Linux WGPU 场景上传具备预算感知能力。

新功能:

  • 每帧批量上传所有 WGPU 场景实例数据,并在图元渲染中复用共享绑定。
  • 为 GPU 资源配置文件新增可配置的实例缓冲区增长上限,支持桌面、实用、最小和自定义预算。

错误修复:

  • 防止实例缓冲区超过配置文件或设备的存储缓冲区限制;当场景无法容纳时,干净地终止帧处理。

增强功能:

  • 在创建 Linux 渲染器和 GPU 恢复期间保留资源预算,同时强制执行对齐要求和设备限制。
  • 在 WGPU 着色器和管线布局中,将精灵纹理绑定与实例数据绑定分离。

文档:

  • 记录实例缓冲区增长上限、设备限制行为,以及更新后的资源配置文件建议。

测试:

  • 增加对配置文件限制、增长行为、对齐、批次范围和渲染器预算传递的测试覆盖。
Original summary in English

Sourcery 总结

通过在配置文件和设备资源限制范围内批量处理实例数据,使 Linux WGPU 场景上传具备预算感知能力。

新功能:

  • 每帧批量上传 WGPU 场景实例数据,并在图元渲染中复用共享绑定。
  • 为 GPU 资源配置文件添加可配置的实例缓冲区增长上限,支持桌面、实用、最小和自定义预算。

错误修复:

  • 通过干净地失败处理超大帧,防止实例缓冲区超出配置文件或设备的存储缓冲区限制。

增强功能:

  • 在 Linux 渲染器创建和 GPU 恢复过程中保留完整的 GPU 资源预算,同时将精灵纹理绑定与实例数据绑定分离。

文档:

  • 记录实例缓冲区增长上限、设备限制行为以及更新后的资源配置文件建议。

测试:

  • 扩展对配置文件限制、增长行为、对齐、批处理范围和预算传递的测试覆盖。
Original summary in English

Sourcery 总结

通过在配置文件和设备资源限制范围内对每帧实例数据进行批处理,使 Linux WGPU 场景上传具备预算感知能力。

新功能:

  • 每帧批量上传所有 Linux WGPU 场景实例,并在各个图元绘制之间复用共享的实例绑定。
  • 为 GPU 资源配置文件添加可配置的实例缓冲区上限,并为桌面、实用、最小化和自定义应用预设预算。

错误修复:

  • 当所需容量无法满足时,通过干净地结束帧,防止超大场景超出配置文件或设备存储缓冲区限制。
  • 避免在渲染失败后呈现未记录的交换链图像。

增强功能:

  • 在创建 Linux 渲染器和执行 GPU 恢复的过程中保留完整的 GPU 资源预算,同时将精灵纹理绑定与实例数据绑定分离。

文档:

  • 记录实例缓冲区增长上限、设备限制行为以及更新后的资源配置文件建议。

测试:

  • 扩展对配置文件限制、增长行为、对齐、批次范围和预算传递的测试覆盖。
Original summary in English

Sourcery 摘要

通过在配置文件和设备资源限制范围内批量处理每帧实例数据,使 Linux WGPU 场景上传具备预算感知能力。

新功能:

  • 每帧批量上传 WGPU 场景实例数据,并在多个图元绘制之间复用共享的实例绑定。
  • 为 GPU 资源配置文件添加可配置的实例缓冲区增长上限,支持桌面、实用、最小和自定义预算。

错误修复:

  • 当场景无法容纳时,以干净的方式失败,避免帧超出配置文件或设备的存储缓冲区限制。
  • 当帧记录失败时,避免呈现未记录的交换链图像。

增强功能:

  • 在创建 Linux 渲染器和执行 GPU 恢复时,传递完整的 GPU 资源预算。
  • 在 WGPU 管线中,将精灵纹理绑定与实例数据绑定分离。

文档:

  • 记录实例缓冲区增长上限、设备限制裁剪、配置文件建议以及更新后的自定义预算构造方式。

测试:

  • 扩展对配置文件限制、增长行为、对齐、批次范围和预算传递的覆盖。

杂项:

  • 将所需的实例缓冲区最大值添加到 GpuResourceBudget,并为更新后的调用方提供构造函数/默认值。
Original summary in English

Sourcery 总结

通过根据配置文件和设备限制,对每帧实例数据进行批处理,使 Linux WGPU 场景上传具备预算感知能力。

新功能:

  • 每帧批量上传 Linux WGPU 场景实例数据,并在各图元绘制之间复用共享的实例绑定。
  • 为 GPU 资源配置文件添加可配置的实例缓冲区增长上限,支持桌面、实用、最小和自定义预算。

错误修复:

  • 当场景过大、超出配置文件或设备的存储缓冲区限制时,通过干净地终止帧处理,避免超出限制。
  • 当帧记录失败时,避免呈现交换链图像。

增强功能:

  • 在创建 Linux 渲染器和执行 GPU 恢复的过程中保留完整的 GPU 资源预算,同时将精灵纹理绑定与实例绑定分离。

构建:

  • 在 feature-matrix 工作流中启用源脚本解析,改进 Shell 脚本检查。

文档:

  • 记录实例缓冲区增长上限、设备限制裁剪、配置文件建议以及兼容的自定义预算构建方式。

测试:

  • 扩展对配置文件限制、缓冲区增长、对齐、批处理范围和渲染器预算传递的测试覆盖。

日常维护:

  • 更新发布归档验证逻辑,忽略未使用的清单路径字段。
Original summary in English

Sourcery 摘要

通过在配置文件和设备资源限制范围内对每帧实例数据进行批处理,使 Linux WGPU 场景上传具备预算感知能力。

新功能:

  • 每帧批量上传 Linux WGPU 场景实例数据,并在渲染期间复用共享的图元绑定。
  • 添加针对配置文件的实例缓冲区增长上限,并支持自定义预算。

错误修复:

  • 防止超大场景超过配置文件或设备的存储缓冲区限制,并在发生此情况时安全地结束帧处理。
  • 避免在帧记录失败时显示未记录的交换链图像。

增强功能:

  • 在创建 Linux 渲染器和 GPU 恢复期间保留完整的 GPU 资源预算,同时在 WGPU 管线中分离纹理绑定和实例绑定。

构建:

  • 更新 Shell 脚本检查,以便在功能矩阵工作流期间解析被 source 的文件。

文档:

  • 记录实例缓冲区增长上限、设备限制行为、配置文件建议以及兼容的自定义预算构造方式。

测试:

  • 扩展对预算规范化、增长行为、对齐、批次范围以及渲染器预算传递的测试覆盖。

杂项:

  • 为扩展后的 GPU 资源预算提供默认构造函数和便捷构造函数。
Original summary in English

Sourcery 摘要

通过根据配置文件和设备资源限制,对每帧实例数据进行批处理,使 Linux WGPU 场景上传具备预算感知能力。

新功能:

  • 每帧批量上传 Linux WGPU 场景实例,并在各图元绘制之间复用共享绑定。
  • 添加特定于配置文件的实例缓冲区增长上限,并支持自定义 GPU 资源预算。

错误修复:

  • 防止超大场景超过配置文件或设备的存储缓冲区限制,并在帧记录失败时避免呈现交换链图像。

增强功能:

  • 在创建 Linux 渲染器和 GPU 恢复过程中传递完整的 GPU 资源预算,同时将纹理绑定与实例绑定分离。

文档:

  • 记录实例缓冲区增长上限、设备限制行为、配置文件建议以及兼容的自定义预算构造方式。

测试:

  • 扩展对预算规范化、增长、对齐、批次范围以及渲染器预算传递的覆盖。
Original summary in English

Summary by Sourcery

Make Linux WGPU scene uploads budget-aware by batching per-frame instance data within profile and device resource limits.

New Features:

  • Batch-upload Linux WGPU scene instances once per frame and reuse shared bindings across primitive draws.
  • Add profile-specific instance-buffer growth ceilings with support for custom GPU resource budgets.

Bug Fixes:

  • Prevent oversized scenes from exceeding profile or device storage-buffer limits, and avoid presenting a swapchain image when frame recording fails.

Enhancements:

  • Carry the complete GPU resource budget through Linux renderer creation and GPU recovery while separating texture bindings from instance bindings.

Documentation:

  • Document instance-buffer growth ceilings, device-limit behavior, profile recommendations, and compatible custom budget construction.

Tests:

  • Expand coverage for budget normalization, growth, alignment, batch ranges, and renderer budget propagation.

@sourcery-ai

sourcery-ai Bot commented Aug 29, 2026

Copy link
Copy Markdown

审查者指南

Linux WGPU 渲染现在会在每帧批量上传场景的实例数据一次,并复用共享绑定组;同时,基于配置文件和设备感知的水位线限制了缓冲区增长,并在创建渲染器和恢复过程中保留完整的 GPU 预算;着色器布局以及相关文档和测试也已相应更新。

支持预算感知的 WGPU 帧上传时序图

sequenceDiagram
    participant Scene
    participant Renderer as WgpuRenderer
    participant Budget as GpuResourceBudget
    participant Queue as WGPUQueue
    participant Pass as RenderPass

    Scene->>Renderer: record_frame(scene, frame_view)
    Renderer->>Renderer: frame_instance_bytes(scene)
    Renderer->>Budget: next_instance_buffer_capacity(current, required, max_buffer_size)
    alt scene exceeds profile/device cap
        Budget-->>Renderer: None
        Renderer-->>Scene: frame fails
    else scene fits budget
        Budget-->>Renderer: capacity
        Renderer->>Queue: write_buffer(instance_buffer, offsets, primitive arrays)
        Renderer->>Renderer: write_instances(scene)
        loop scene batches
            Renderer->>Pass: draw_instances(bind_group, instance_range)
        end
        Queue-->>Renderer: submit(encoder)
    end
Loading

文件级变更

变更 详细信息 文件
将按批次上传实例数据以及基于重试的缓冲区增长,替换为每帧一次、支持预算感知的场景上传。
  • 在渲染前计算所有图元数组和路径栅格化数据所需的对齐存储空间。
  • 根据配置文件支持的倍增策略、配置文件/设备限制以及渲染器上限,一次性增长实例缓冲区。
  • 每个数组只上传一次,创建可复用的实例绑定组,并通过共享缓冲区中的范围绘制各个批次。
  • 当场景超出允许的容量时,返回带有上下文错误信息的失败帧。
crates/gpui-wgpu/src/wgpu_renderer.rs
为 GPU 资源配置文件添加明确的实例缓冲区增长水位线和容量辅助函数。
  • 为桌面、实用、最小和自定义预算添加按配置文件区分的初始值/最大值。
  • 根据设备限制规范化初始容量和最大容量,并强制执行最小值。
  • 添加增长和对齐分配辅助函数,并通过测试覆盖截断、倍增和拒绝场景。
crates/gpui/src/resource_profile.rs
crates/gpui/src/window.rs
在 Linux 渲染器创建和 GPU 恢复过程中传递完整的 GPU 资源预算。
  • 将图集、初始实例容量和最大水位线一同传入渲染器。
  • 在设备丢失恢复过程中保留该预算,并重新应用设备限制规范化。
crates/gpui-linux/src/linux/wayland/window.rs
crates/gpui-linux/src/linux/x11/window.rs
crates/gpui-wgpu/src/wgpu_renderer.rs
在 WGPU 管线布局中分离纹理绑定和实例绑定。
  • 将精灵纹理和采样器声明移动到组 2。
  • 为路径和精灵管线使用专用的纹理绑定组布局,同时将实例数据保留在组 1。
crates/gpui-wgpu/src/shaders.wgsl
crates/gpui-wgpu/src/wgpu_renderer.rs
记录并测试新的资源预算行为。
  • 记录批量上传增长上限、设备限制截断以及配置文件建议。
  • 增加对批次范围、对齐、配置文件水位线、增长行为和预算传递的测试覆盖。
docs/resource-profiles.md
docs/sync/upstream-audit.json
crates/gpui-wgpu/src/wgpu_renderer.rs
crates/gpui/src/resource_profile.rs
crates/gpui/src/window.rs

提示和命令

与 Sourcery 交互

  • 触发新的审查: 在拉取请求中评论 @sourcery-ai review
  • 继续讨论: 直接回复 Sourcery 的审查评论。
  • 根据审查评论生成 GitHub issue: 回复审查评论,请 Sourcery 根据该评论创建 issue。你也可以使用 @sourcery-ai issue 回复审查评论,以便根据该评论创建 issue。
  • 生成拉取请求标题: 在拉取请求标题的任意位置写入 @sourcery-ai,即可随时生成标题。你也可以在拉取请求中评论 @sourcery-ai title,以便随时(重新)生成标题。
  • 生成拉取请求摘要: 在拉取请求正文的任意位置写入 @sourcery-ai summary,即可在指定位置随时生成 PR 摘要。你也可以在拉取请求中评论 @sourcery-ai summary,以便随时(重新)生成摘要。
  • 生成审查者指南: 在拉取请求中评论 @sourcery-ai guide,即可随时(重新)生成审查者指南。
  • 解决所有 Sourcery 评论: 在拉取请求中评论 @sourcery-ai resolve,即可解决所有 Sourcery 评论。如果你已经处理完所有评论且不想再看到它们,此功能会很有用。
  • 驳回所有 Sourcery 审查: 在拉取请求中评论 @sourcery-ai dismiss,即可驳回所有现有的 Sourcery 审查。如果你希望从新的审查开始,这一功能尤其有用——别忘了评论 @sourcery-ai review 以触发新的审查!

自定义使用体验

访问你的控制面板以:

  • 启用或禁用审查功能,例如 Sourcery 生成的拉取请求摘要、审查者指南等。
  • 更改审查语言。
  • 添加、删除或编辑自定义审查指令。
  • 调整其他审查设置。

获取帮助

Original review guide in English

Reviewer's Guide

Linux WGPU rendering now bulk-uploads a scene’s instance data once per frame and reuses shared bind groups, while profile- and device-aware watermarks bound buffer growth and preserve the full GPU budget through renderer creation and recovery; shader layouts and documentation/tests were updated accordingly.

Sequence diagram for budget-aware WGPU frame upload

sequenceDiagram
    participant Scene
    participant Renderer as WgpuRenderer
    participant Budget as GpuResourceBudget
    participant Queue as WGPUQueue
    participant Pass as RenderPass

    Scene->>Renderer: record_frame(scene, frame_view)
    Renderer->>Renderer: frame_instance_bytes(scene)
    Renderer->>Budget: next_instance_buffer_capacity(current, required, max_buffer_size)
    alt scene exceeds profile/device cap
        Budget-->>Renderer: None
        Renderer-->>Scene: frame fails
    else scene fits budget
        Budget-->>Renderer: capacity
        Renderer->>Queue: write_buffer(instance_buffer, offsets, primitive arrays)
        Renderer->>Renderer: write_instances(scene)
        loop scene batches
            Renderer->>Pass: draw_instances(bind_group, instance_range)
        end
        Queue-->>Renderer: submit(encoder)
    end
Loading

File-Level Changes

Change Details Files
Replace per-batch instance uploads and retry-based buffer growth with one budget-aware scene upload per frame.
  • Compute aligned storage requirements for all primitive arrays and path rasterization data before rendering.
  • Grow the instance buffer once using profile-backed doubling, profile/device limits, and the renderer ceiling.
  • Upload each array once, create reusable instance bind groups, and draw batches through ranges into shared buffers.
  • Return a failed frame with contextual errors when the scene exceeds the permitted capacity.
crates/gpui-wgpu/src/wgpu_renderer.rs
Extend GPU resource profiles with explicit instance-buffer growth watermarks and capacity helpers.
  • Add per-profile initial/max values for desktop, utility, minimal, and custom budgets.
  • Normalize initial and maximum capacities against device limits and enforce minimums.
  • Add growth and aligned-allocation helpers with tests for clamping, doubling, and rejection.
crates/gpui/src/resource_profile.rs
crates/gpui/src/window.rs
Propagate the complete GPU resource budget through Linux renderer creation and GPU recovery.
  • Pass atlas, initial instance capacity, and maximum watermark together into the renderer.
  • Retain the budget across device-lost recovery and reapply device-limit normalization.
crates/gpui-linux/src/linux/wayland/window.rs
crates/gpui-linux/src/linux/x11/window.rs
crates/gpui-wgpu/src/wgpu_renderer.rs
Separate texture bindings from instance bindings in the WGPU pipeline layouts.
  • Move sprite texture and sampler declarations to group 2.
  • Use a dedicated texture bind-group layout for path and sprite pipelines while keeping instance data in group 1.
crates/gpui-wgpu/src/shaders.wgsl
crates/gpui-wgpu/src/wgpu_renderer.rs
Document and test the new resource-budget behavior.
  • Document batch-upload growth ceilings, device-limit clamping, and profile recommendations.
  • Add coverage for batch ranges, alignment, profile watermarks, growth behavior, and budget propagation.
docs/resource-profiles.md
docs/sync/upstream-audit.json
crates/gpui-wgpu/src/wgpu_renderer.rs
crates/gpui/src/resource_profile.rs
crates/gpui/src/window.rs

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@cursor
cursor Bot marked this pull request as ready for review August 29, 2026 10:18

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

你好——我发现了 2 个问题

面向 AI Agent 的提示
请处理这次代码审查中的评论:

## 单条评论

### 评论 1
<location path="crates/gpui/src/resource_profile.rs" line_range="245-254" />
<code_context>
     /// Default: 2 MiB for desktop applications.
     pub instance_buffer_initial_size: usize,
+
+    /// Maximum renderer instance buffer capacity in bytes, where supported.
+    ///
+    /// Batch upload sizes the GPU buffer to fit the whole scene at frame start.
+    /// This is the growth ceiling after device limits are applied. Desktop
+    /// matches Zed's 256 MiB native cap; Utility and Minimal stay lower so a
+    /// tray or dialog profile cannot balloon to a full-editor working set.
+    ///
+    /// Values below [`Self::instance_buffer_initial_size`] are raised to that
+    /// initial budget.
+    pub instance_buffer_max_size: usize,
 }

</code_context>
<issue_to_address>
**issue (bug_risk):**`GpuResourceBudget` 添加必需的公共字段,会导致现有下游结构体字面量无法编译,因为现在每个字面量都必须提供 `instance_buffer_max_size`。对于直接构造自定义 GPU 预算的调用方而言,这是一个破坏源码兼容性的 API 回归。

**触发条件:** 当应用或下游 crate 使用 `GpuResourceBudget { ... }`,而不是通过更新后的辅助方法来构造它时。

**建议修复:** 提供不破坏兼容性的构造函数/更新路径,或通过带默认值的配置表示形式来保持兼容性;至少应将其记录为有意进行的破坏性 API 变更,并更新所有受支持的下游字面量。
</issue_to_address>

### 评论 2
<location path="crates/gpui-wgpu/src/wgpu_renderer.rs" line_range="1478-1500" />
<code_context>
+    fn create_texture_bind_group(
</code_context>
<issue_to_address>
**nitpick (performance):** 每次 sprite 绘制调用中都会创建一个新的纹理绑定组,因此包含许多图集纹理批次的场景会为每个批次分配并保留一个绑定组,直到命令提交,而不是复用使用相同纹理 ID 的批次的绑定组。这会增加每帧 CPU/GPU 资源的频繁分配与释放,并使针对 sprite 的共享绑定组批处理优化失去作用。

**触发条件:** 当一帧包含许多单色或多色 sprite 批次时,尤其是多个批次使用同一个图集纹理时。

**建议修复:** 在帧的持续期间按 `AtlasTextureId` 缓存纹理绑定组,或将它们与图集纹理元数据一起保留。
</issue_to_address>

Sourcery 对开源项目免费——如果你喜欢我们的审查结果,请考虑分享它们 ✨
请帮助我变得更有用!请在每条评论上点击 👍 或 👎,我会利用这些反馈来改进审查结果。
Original comment in English

Hey - I've found 2 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="crates/gpui/src/resource_profile.rs" line_range="245-254" />
<code_context>
     /// Default: 2 MiB for desktop applications.
     pub instance_buffer_initial_size: usize,
+
+    /// Maximum renderer instance buffer capacity in bytes, where supported.
+    ///
+    /// Batch upload sizes the GPU buffer to fit the whole scene at frame start.
+    /// This is the growth ceiling after device limits are applied. Desktop
+    /// matches Zed's 256 MiB native cap; Utility and Minimal stay lower so a
+    /// tray or dialog profile cannot balloon to a full-editor working set.
+    ///
+    /// Values below [`Self::instance_buffer_initial_size`] are raised to that
+    /// initial budget.
+    pub instance_buffer_max_size: usize,
 }

</code_context>
<issue_to_address>
**issue (bug_risk):** Adding the required public field to `GpuResourceBudget` makes existing downstream struct literals fail to compile because every literal must now provide `instance_buffer_max_size`. This is a source-compatible API regression for callers that construct custom GPU budgets directly.

**Triggers:** When an application or downstream crate uses `GpuResourceBudget { ... }` rather than constructing it through an updated helper.

**Suggested fix:** Provide a non-breaking constructor/update path or preserve compatibility with a defaulted configuration representation; at minimum, document this as a deliberate breaking API change and update all supported downstream literals.
</issue_to_address>

### Comment 2
<location path="crates/gpui-wgpu/src/wgpu_renderer.rs" line_range="1478-1500" />
<code_context>
+    fn create_texture_bind_group(
</code_context>
<issue_to_address>
**nitpick (performance):** A new texture bind group is created inside every sprite draw call, so scenes with many atlas texture batches allocate and retain one bind group per batch until command submission rather than reusing bind groups for repeated texture IDs. This increases per-frame CPU/GPU resource churn and defeats the stated shared-bind-group batching optimization for sprites.

**Triggers:** When a frame contains many monochrome or polychrome sprite batches, especially repeated batches using the same atlas texture.

**Suggested fix:** Cache texture bind groups by `AtlasTextureId` for the duration of the frame or retain them alongside atlas texture metadata.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread crates/gpui/src/resource_profile.rs
Comment on lines +1478 to 1500
fn create_texture_bind_group(
&self,
sprites: &[PolychromeSprite],
texture_id: AtlasTextureId,
instance_offset: &mut u64,
pass: &mut wgpu::RenderPass<'_>,
) -> bool {
let tex_info = self.atlas.get_texture_info(texture_id);
let data = unsafe { Self::instance_bytes(sprites) };
self.draw_instances_with_texture(
data,
sprites.len() as u32,
&tex_info.view,
&self.resources().pipelines.poly_sprites,
instance_offset,
pass,
)
label: &str,
texture_view: &wgpu::TextureView,
) -> wgpu::BindGroup {
let resources = self.resources();
resources
.device
.create_bind_group(&wgpu::BindGroupDescriptor {
label: Some(label),
layout: &resources.bind_group_layouts.texture,
entries: &[
wgpu::BindGroupEntry {
binding: 0,
resource: wgpu::BindingResource::TextureView(texture_view),
},
wgpu::BindGroupEntry {
binding: 1,
resource: wgpu::BindingResource::Sampler(&resources.atlas_sampler),
},
],
})
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick (performance): 每次 sprite 绘制调用中都会创建一个新的纹理绑定组,因此包含许多图集纹理批次的场景会为每个批次分配并保留一个绑定组,直到命令提交,而不是复用使用相同纹理 ID 的批次的绑定组。这会增加每帧 CPU/GPU 资源的频繁分配与释放,并使针对 sprite 的共享绑定组批处理优化失去作用。

触发条件: 当一帧包含许多单色或多色 sprite 批次时,尤其是多个批次使用同一个图集纹理时。

建议修复: 在帧的持续期间按 AtlasTextureId 缓存纹理绑定组,或将它们与图集纹理元数据一起保留。

Original comment in English

nitpick (performance): A new texture bind group is created inside every sprite draw call, so scenes with many atlas texture batches allocate and retain one bind group per batch until command submission rather than reusing bind groups for repeated texture IDs. This increases per-frame CPU/GPU resource churn and defeats the stated shared-bind-group batching optimization for sprites.

Triggers: When a frame contains many monochrome or polychrome sprite batches, especially repeated batches using the same atlas texture.

Suggested fix: Cache texture bind groups by AtlasTextureId for the duration of the frame or retain them alongside atlas texture metadata.

@cursor
cursor Bot force-pushed the cursor/wgpu-batch-upload-budget-bef0 branch from a8f4bc0 to cbd8510 Compare August 29, 2026 12:07
Port Zed's frame-start instance-buffer upload onto the Linux wgpu
renderer without overwriting local recovery or profile wiring. Size and
grow the buffer from GpuResourceBudget watermarks so Minimal/Utility
cannot follow Zed's 256 MiB desktop ceiling.

Zed-Origin: be8c6f9fb356dcd40a7ff06149568753e64ee171

Co-authored-by: freefcw <freefcw@gmail.com>
Do not present an unrecorded swapchain image when instance upload
exceeds the profile/device cap. Replace offset_from with a release-safe
subslice check so a non-scene batch cannot invoke UB.

Co-authored-by: freefcw <freefcw@gmail.com>
Add GpuResourceBudget::new and Default so 0.9 callers can set atlas and
initial instance-buffer sizes without inventing a max. Document the
struct-literal break in the 0.9 changelog.

Co-authored-by: freefcw <freefcw@gmail.com>
@cursor
cursor Bot force-pushed the cursor/wgpu-batch-upload-budget-bef0 branch from cbd8510 to 6f9ffc4 Compare August 29, 2026 16:02
@freefcw
freefcw merged commit 5d0f51b into develop/0.9 Aug 29, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant