Replaces the bindless `binding_array<texture_2d<f32>>` the renderer bound every texture through. That array needs `VK_EXT_descriptor_indexing`, which a real share of Android GPUs lack, so the old shape did not run there at all. The two things being bound want opposite treatment, so they are now split: - **Glyph atlas pages become layers of one `texture_2d_array`.** A glyph primitive carries a `layer` instead of a view/sampler index pair. A layer index is an ordinary sampling operand, so this needs nothing beyond plain Vulkan 1.0 / GLES. Growing the atlas recreates the array with headroom and `copy_texture_to_texture`s the old layers across, no readback. - **A standalone image gets its own texture and its own bind group,** and draws in its own call. It no longer needs a per-instance entry in `PrimitiveData`: the bind group has already picked the texture. `Primitives` keeps images in a list of their own as a result, with `PrimitiveChange::is_image` naming which list a renumbering belongs to -- the two have independent index spaces, so `(layer, inst_idx)` alone would collide between them. Two notes on judgement calls, since this slice was rebuilt on top of `main` rather than transplanted: - The source version renamed `GlyphEntry::is_colored` to `is_color` and added a second `IS_COLOR` flag constant beside the existing `GlyphEntry::IS_COLORED`. Both dropped: #10's naming and its `flags()` are kept, and UVs stay `Vec2` rather than going back to `[f32; 2]`. - `ImageGpu` no longer holds the `Texture` behind its view, which removes an `#[allow(dead_code)]`. A `TextureView` keeps its own reference to the texture, checked by rendering rather than assumed -- see below. ### Verification ``` cargo fmt --all --check cargo clippy --workspace --all-targets --locked -- -D warnings cargo test --workspace --locked ``` All clean; the 4 text-edit tests pass. The only clippy output is the pre-existing future-incompatibility notice about `naga`/`wgpu`/`winit`. Because this is a rendering change, it was also run for real rather than only compiled. The `tabs` example was rendered on this machine's GPU -- Venus onto an RX 7900 XT, confirmed from the loaded ICD (`libvulkan_virtio.so` on `/dev/dri/renderD128`) rather than assumed, since a failed Vulkan init here silently falls back to llvmpipe and would make the screenshots meaningless. Screenshots before and after the change are **byte-identical** (same md5) in two scenes: the default tab, which exercises text (the atlas path) and rects, and the image tab with a standalone image pushed at startup, which exercises the per-image bind group. The image-tab scene needed a temporary local edit to the example to push the image without a click; that edit is not part of this branch. The same comparison, re-run after dropping the `Texture` field, is still byte-identical -- which is the check that the view alone keeps it alive. --------- Co-authored-by: iris <2+iris@noreply.localhost> Reviewed-on: iris/iris#11 Reviewed-by: iris <2+iris@noreply.localhost> Co-authored-by: AIris <4+iris-ai@noreply.localhost>
47 lines
1.0 KiB
Rust
47 lines
1.0 KiB
Rust
use crate::{UiRegion, util::Id};
|
|
use wgpu::*;
|
|
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable, Default)]
|
|
pub struct WindowUniform {
|
|
pub width: f32,
|
|
pub height: f32,
|
|
}
|
|
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
|
|
pub struct PrimitiveInstance {
|
|
pub region: UiRegion,
|
|
pub mask_idx: MaskIdx,
|
|
}
|
|
|
|
impl PrimitiveInstance {
|
|
const ATTRIBS: [VertexAttribute; 5] = vertex_attr_array![
|
|
0 => Float32x2,
|
|
1 => Float32x2,
|
|
2 => Float32x2,
|
|
3 => Float32x2,
|
|
4 => Uint32,
|
|
];
|
|
|
|
pub fn desc() -> VertexBufferLayout<'static> {
|
|
VertexBufferLayout {
|
|
array_stride: std::mem::size_of::<Self>() as BufferAddress,
|
|
step_mode: VertexStepMode::Instance,
|
|
attributes: &Self::ATTRIBS,
|
|
}
|
|
}
|
|
}
|
|
|
|
pub type MaskIdx = Id<u32>;
|
|
|
|
impl MaskIdx {
|
|
pub const NONE: Self = Self::preset(u32::MAX);
|
|
}
|
|
|
|
#[repr(C)]
|
|
#[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
|
|
pub struct Mask {
|
|
pub region: UiRegion,
|
|
}
|