* Fix call to removed encoded_scene method in pgpu-render
* Add new ImageFormat::Surface variant to select a pixel format that matches the platform specific surface format. This makes gradients consistent across platforms.
Use compute pass for tests in tests subdir. This is also shaking out some issues that weren't apparent from just collatz.
In particular, we need more autorelease pools to prevent things from leaking. As of this commit, the "clear" test runs correctly but the others haven't yet been converted to the compute_pass format.
Current status: the piet-gpu-hal module (including the collatz example)
have the new API (with queries set on compute pass) implemented. The
other uses have not yet been updated.
On Metal, only M1 is tested. The "command" counter style is partly
implemented, but not fully wired up.
The current plan is to more or less follow the wgpu/wgpu-hal approach. In the mux/backend layer (which corresponds fairly strongly to wgpu-hal), there isn't explicit construction of a compute encoder, but there are new methods for beginning and ending a compute pass. At the hub layer (which corresponds to wgpu) there will be a ComputeEncoder object.
That said, there will be some differences. The WebGPU "end" method on a compute encoder is implemented in wgpu as Drop, and that is not ideal. Also, the wgpu-hal approach to timer queries (still based on write_timestamp) is not up to the task of Metal timer queries, where the query offsets have to be specified at compute encoder creation. That's why there are different projects :)
WIP: current state is that stage-style queries work on Apple Silicon, but non-Metal backends are broken, and piet-gpu is not yet updated to use new API.
This exposes interfaces to render glyphs into a texture atlas. The main changes are:
* Methods to plumb raw Metal GPU resources (device, texture, etc) into piet-gpu-hal objects.
* A new glyph_render API specialized to rendering glyphs. This is basically the same as just painting to a canvas, but will allow better caching (and has more direct access to fonts, bypassing the Piet font type which is underdeveloped).
* Ability to render to A8 target in addition to RGBA.
WIP, there are some rough edges, not least of which is that the image format changes are only on mac and cause compile errors elsewhere.
This patch includes a number of changes to encourage reading and writing
buffers through mapping rather than copying data as before.
This includes a new `BufWrite` abstraction which is designed for filling
buffers. It behaves much like a Vec<u8>, but with fixed capacity.
Reduce allocation of descriptor heaps. This change also enables clearing
of buffers, as the handles are needed at command dispatch time.
Also updates the tests to use clear_buffers on DX12. Looking forward to
being able to get rid of the compute shader workaround on Metal.
This is a followup on #125, and progress toward #95
Integrate DXC for translating HLSL for use in DX12. This will work
around FXC limitations and unlock the use of more advanced HLSL features
such as subgroups.
This hardcodes the use of DXIL, but it could be adapted (with a bit of
effort) to choose between DXIL and HLSL at runtime.
This gets it working on mac. Also delete old implementation.
There's also an update to winit 0.25 in here, because it was easier to
roll forward than fix inconsistent Cargo.lock. At some point, we should
systematically update all deps.
Use an array of bindtypes rather than the previous situation, which was
a choice of buffer counts, or a heavier builder pattern.
The main thing this unlocks is distinguishing between readonly and
read/write buffers, which is important for DX12.
This is WIP, the Metal part hasn't been done, and the old stuff not
deleted.
Part of #125
Move types into the toplevel and hide implementation details. Remove
deref of hub CmdBuf to mux. Restrict public visibility of internals.
Most items have some docs, though improvements are still possible. In
particular, there should be detailed safety info.
Add workgroup size to dispatch call (needed by metal). Change all fence
references to mutable for consistency.
Move backend traits to a separate file (move them out of the toplevel
namespace in preparation for the hub types going there, to make the
public API nicer).
Add a method and macro for automatically choosing shader code, and
change collatz example to generate all 3 kinds on build.
Change the interface for fences to accept mutable references. This will
actualy help the Metal backend more than dx12 (avoiding interior
mutability) but more accurately captures intent and matches gfx-hal.
Make the hub abstraction connect to the mux, rather than directly to the
Vulkan back-end.
As of this commit, both command line and winit examples work (on
Vulkan). In theory it should be possible to get them working on Dx12 as
well by translating the shader code, but there's a lot that can go
wrong.
This commit also contains a bunch of changes to mux to make conditional
compilation of match arms work, and new methods to support swapchain.
Adds a new "mux" module which can have multiple backends. As of this
commit, it's not wired up at all, but the functionality should be
reasonably complete.
Minor tweaks to the backend trait to accommodate this, mostly changing
Fence and Semaphore to references so they don't need to be Copy.
Part of the work toward #95
Add a method to create a buffer with initial content, which requires
staging buffers under the hood.
This patch also changes the lower-level (Vulkan) interface to be closer
to the raw Vulkan call.
These function, but can use some work.
First, the buffer situation is worse than it should be. It should be
possible to create a single readback buffer rather then copy from
gpu-local to host-coherent.
Second, the command buffer `finish_timestamps` call doesn't correlate to
anything in Vulkan, so needs plumbing up through the hub in one form or
other when that happens. I'm inclined to make it ergonomic by doing a
bit of resource tracking that will trigger the appropriate call (and
subsequent host barrier) in the `finish` method on the command buffer.
Create compute pipelines from shader source and descriptor sets. This
gets it to the point where it can run the collatz example.
Still WIP and with rough edges, of course.
Test whether the GPU supports subgroups (including size control) and
memory model.
This patch does all the ceremony needed for runtime query, including
testing the Vulkan version and only probing the extensions when
available. Thus, it should work fine on older devices (not yet tested).
The reporting of capabilities follows Vulkan concepts, but is not
particularly Vulkan-specific.
FillImage is like Fill, except that it takes its color from one or
more image atlases.
kernel4 uses a single image for non-Vulkan hosts, and the dynamic sized array
of image descriptors on Vulkan.
A previous version of this commit used textures. I think images are a better
choice for piet-gpu, for several reasons:
- Texture sampling, in particular textureGrad, is slow on lower spec devices
such as Google Pixel. Texture sampling is particularly slow and difficult to
implement for CPU fallbacks.
- Texture sampling need more parameters, in particular the full u,v
transformation matrix, leading to a large increase in the command size. Since
all commands use the same size, that memory penalty is paid by all scenes, not
just scenes with textures.
- It is unlikely that piet-gpu will support every kind of fill for every
client, because each kind must be added to kernel4.
With FillImage, a client will prepare the image(s) in separate shader stages,
sampling and applying transformations and special effects as needed. Textures
that align with the output pixel grid can be used directly, without
pre-processing.
Note that the pre-processing step can run concurrently with the piet-gpu pipeline;
Only the last stage, kernel4, needs the images.
Pre-processing most likely uses fixed function vertex/fragment programs,
which on some GPUs may run in parallel with piet-gpu's compute programs.
While here, fix a few validation errors:
- Explicitly enable EXT_descriptor_indexing, KHR_maintenance3,
KHR_get_physical_device_properties2.
- Specify a vkDescriptorSetVariableDescriptorCountAllocateInfo for
vkAllocateDescriptorSets. Otherwise, variable image2D arrays won't work (but
sampler2D arrays do, at least on my setup).
Updates #38
Signed-off-by: Elias Naur <mail@eliasnaur.com>
Provide images to fine rasterization kernel as readonly textures with a
sampler, rather than storage images. That lets us use the GPU's hardware
for sampling, which should be considerably more efficient.
There are a bunch of parameters that are hardcoded, but it does seem to
work.
This patch passes a dynamically sized array of textures to the fine
rasterizer.
A bunch of the low level Vulkan stuff is done, but only enough of the
shaders and encoders to do minimal testing. We'll want to switch from
storage images to sampled images, track the actual array of textures
during encoding, use that to build the descriptor set (which will need
to be more dynamic), and of course run image elements through the
pipeline.
Progress towards #38
We keep a small window of the clip stack in registers in the fine
rasterization kernel, and when that window is exceeded, spill to global
memory, so the clip stack can be unbounded.
The hub does a little better lifetime tracking of resources (so
Rust-side references can be dropped), and in the future will be used for
dynamic selection of backend.
The migration is still a bit half-baked, as there are a bunch of
Vulkan-specific types in the signatures, but it shouldn't be too much
work to sort that out. Perhaps it can wait until there is a second
backend though.
The main motivation for this is to create image objects with lifetime
tracking, one of the things required for #38.