Summary:
- Buffer length can be zero (indicates single value instead of array)
- Internally, arrays aren't coerced to array-of-single-struct
- Removes support for "flat table" data (array-of-structs w/o wrapping
each struct in a nested table)
- Use consistent syntax for reading table data into buffers:
- Numbers are numbers
- Vectors are numbers, tables, or vectors
- Structs are tables with any combination of integer/string keys
- Fields are assigned from integer keys in order, then any remaining
fields use the string keys
- Arrays are tables of elements, formatted as above
- Try to improve error messages for Buffer:setData errors
LÖVR uses d32f by default, but that's not guaranteed to be supported.
However, GPUs must support either d32f or d24, so we can fall back to
d24 reliably.
Adding an offset to VertexIndex/BaseVertex breaks those builtins for
shader code. Instead, go back to binding the vertex buffer at an
appropriate offset.
This means we rebind the vertex buffer and makes it harder to batch
draws. In the future we'd like to go back to binding all vertex buffers
at zero and incorporating per-draw vertex offsets, but we'll need to
adjust the VertexIndex macro to subtract that offset.
Shader == NULL wasn't clearing the dirty uniform flag, so if the
uniforms were dirty when you set a default shader we would try to
allocate and bind a zero-size uniform buffer.
Instead, let's avoid making a new uniform buffer if the shader doesn't
have any uniforms!
- You can nest texture views (make a view of a view).
- You can do transfers on views (copies, clears, blits, etc.).
- You can give labels to views.
- API changes
- Rename Texture:newView to lovr.graphics.newTextureView.
- Constructor takes a table of options (order was too confusing).
- Remove Texture:isView/getParent, since views can be used for everything now.
- Better matches what LÖVE ended up doing.
- Fix bug where :getType on a view returned parent type.
Previously, when switching shaders, resource bindings would be preserved
for resources with matching slots/types. This doesn't make sense in a
world where binding numbers are internal. Instead, match up resources
by name/type.
Additionally, rewire all the uniforms by name/size so uniforms with the
same name get preserved (name/type would be too hard for e.g. structs).
This seems like it would be horribly slow and may need to be optimized,
optional, or removed.
I didn't test any of this lol, but I will I promise.
The vertex-only shader requires too much juggling of shader stage flags
and pipeline layout compatibility when e.g. binding push constants and
descriptor sets.
This is a little slower, but means indirect draws can use Transform and Color.
There are other solutions for this. For example LÖVR could reserve
BaseInstance and use a compute shader to rewrite indirect buffers.
For now we choose to be correct and a little slower.
- Undeprecate ShaderType (it's good actually, kinda like a pipeline bind
point and more specific than having lovr trying to make sense of a
random set of stages).
- Use a default uniform block instead of push constants. The Constants
macro now maps to a uniform block declaration.
- It is no longer possible to create a shader by giving a single
DefaultShader string (you can still give a per-stage DefaultShader
though).
- lovr.graphics.compileShader now takes all stages instead of a single
stage. In general we need all stages when compiling GLSL because
default uniforms require linking across stages.
- When destroyed, Pass should only recycle its buffer if it actually has one.
- When resetting, chain all of the buffers at once instead of one-by-one (N^2)
This shaves 20 bytes off of each model vertex, or around 40% savings.
The vertex size is also a power of two which results in extreme amounts
of style points.