We are changing all object creation to use descriptors but there is no
creation argument to pass for queue, so instead Device::CreateQueue
takes no argument.
The flow of commands is a bit more involved than for MapReadAsync and
goes like this:
- C->S MapAsync isWrite = true
- S: Call MapWriteAsync
- S: MapWriteAsync callback fired
- S->C: MapWriteAsyncCallback (no data compared to the read case)
- C: Call the MapWriteAsync callback with a zeroed out buffer
- C: Application calls unmap.
- C->S: UpdateMappedData with the content of the mapped pointer
- S: Copy the data in the mapped pointer
- C->S: Regular unmap command
- S: Call unmap
Makes nxt_end2end_tests -w pass all tests.
Also duplicates the MapRead wire tests for the write cases
This will help with follow-up changes that add support for a more
complete grammer of types, including structures containing pointers
to objects or other structures.
Instead of having the wire::Client and wire::Server directly act on
buffer memory, a couple interfaces are introduced so that WireCmd can do
things like get the object<->id mapping and temporary allocations.
While the serialization and deserialization of most commands was moved
into WireCmd, the commands that don't directly correspond to NXT methods
have their logic moved inside Client and Server and will be made to
expose the new interface in a follow-up commit.
This will be useful to provide additional coverage of the wire in
addition to the very focused WireTests unittests. All tests pass except
the MapWriteAsync ones that aren't implemented in the wire yet. They can
be skipped with --gtest_filter=-*MapWrite*
These types are meant to be used for computations that might but are not
expected to fail in backend/, such that the error case can be much
slower than the success case.
The NXT_TRY and NXT_TRY_RESULT macros are added to help write more
concise code that uses Error and ResultOrError.
The sampler builder will be removed as the first builder being converted
to a descriptor. Use CommandBufferBuilder instead as it is not expected
to change soon.
This as an API change to get closer to the direction in which WebGPU is
headed. The API change in next.json caused a ton of files to be changed
in the same commit to keep things compiling.
API: the Framebuffer and RenderPass objects are now merged in a single
RenderPassInfo that contains the attachments, loadOps and clear values
for a BeginRenderPass command. The concept of subpass is removed.
The RenderPass creation argument to RenderPipelines is replaced by
explicitly setting the format of attachments for RenderPipeline.
Validation: SetPipeline checks are changed to check that the attachments
info set on a RenderPipeline matches the attachments of the render pass.
Backends: Most changes are simplifications of the backends that no
longer require and indirection to query the current subpass out of the
render pass in BeginSubpass, and don't need to get the attachment info
from a RenderPass when creating RenderPipelines. In the Vulkan backend,
a VkRenderPass cache is added to reuse VkRenderPasses between
RenderPassInfos and RenderPipelines.
Tests and examples: they are updated with the simplified API. Tests
specific to the Framebuffer and RenderPass objects were removed and
validation tests for RenderPassInfo were added.
Tested by running CppHelloTriangle on all backends, end2end tests on all
platforms and all examples on the GL backend.
HashCombine will be used in more than just BindGroupLayout caching so we
extract it to a separate header. Add a better mixing constant for 64bit
systems.
Delete the TextureBuilder created in SwapChainBase::GetNextTexture().
Delete the InputStateBuilder and DepthStencilStateBuilder created in
RenderPipelineBuilder::GetResultImpl().
PipelineLayout was re-entering in NXT to create the default empty BGLs,
but forgot to remove the initial external refcount for them.
Fixing this showed an issue where it was impossible to externally
reference a RefCounted that had only internal references, fix this as
well and add a test.
When a BGL was first created in the cache, it started with an external
refcount of 1 and we then referenced again in
BindGroupLayoutBuilder::GetResultImpl, causing a leak.
Fix this by referencing in the cache lookup only if the BGL already
exists.
Don't assert on color formats which can be cleared with a
floating-point clear value.
So far, these are { unorm } x { r, rg, rgba, bgra }.
Fix linter error when no files to check.
The indexOffset of the draw was not being used. It must be
included in the indexBufferOffset.
Renamed indexBufferOffset -> indexBufferBaseOffset.
Add a DrawElements test which exercises zero and non-zero index offsets.
Backend support implemented in GL, Metal and D3D12.
Support for unorm values in the GL backend requires a
utility function to indicate if the format's components
are normalized.
Note that unorm_r8 is only supported on more recent MacOS SDKs (10.13),
so it's omitted for now.
When calling unmap on a mapped buffer for which the callback hasn't
fired yet, the callback should be called with UNKNOWN. The code marked
the callback as called only after calling it, causing problems with
re-entrancy where the callback would be called twice.
This could also get triggered by destroying the buffer inside the
callback.
Fix this in backend::Buffer and the WireClient and add test for both.
Previously we would remove the reference to pipelines in the destructor
of the d3d12::*Pipeline objects which could cause the D3D12 pipeline
state to be destroyed while still used by in-flight commands. Add a
global queue of ComPtrs to keep alive in the d3d12::Device to fix this.
We want all of NXT to have the origin in the top left. OpenGL's origin
is the bottom left instead. We are doing a blit already to decouple
the NXT render targets from the OpenGL default framebuffer. Take
advantage of this and invert the blit to make the OpenGL's backend
origin be top left.
PRESENT is an exclusive flag in NXT and can't be combined with other flags. The existing implementation treats the D3D12_RESOURCE_STATE_PRESENT as flag which is confusing due to being 0.
The Swapchain::Configure was changed to not require an initial usage
anymore. Previously the code was doing a transition to this usage
causing the code to now transition to <uninitialized data> usage.
Fix this by deleting code. Also make TextureD3D12 responsible for the
transition to PRESENT.
Making all textures represented by pointers is a problem for Vulkan
where VkImage is a 64bit type and wouldn't fit in a pointer on 32bit
builds. Make texture contain on of each useful type so that each backend
can choose which one it wants to receive.
This file changes the non-dispatchable Vulkan handle types. We want to
use some of these handles in utils/VulkanSwapChain.cpp so it needs to
have access to it. The file could include
backend/vulkan/vulkan_platform.h but it seems a bit cleaner to move the
header in common/ instead with a warning if the Vulkan backend isn't
enabled.
For the Vulkan backend it will make sense to have the SwapChain be
implemented inside the backend as it will need to interact with a lot of
things there. It will need SwapChainImpl and cannot see utils/ so
SwapChainImpl has to be moved in common/
Also makes SwapChainImpl a function called CreateSwapChainImplementation
as the inheritance was only used to share a static method.
In Vulkan images are created in no particular layout and must be
transitioned before they can be used. This didn't appear before because
the test were creating the textures with not initial usage and then
transitioned them. This isn't the case with InputStateTest, which is
what uncovered this issue.
There was a lot of missing around with viewports and flip the Y
coordinate in vertex shaders before. Turns out things are simpler than
we thought: *all* APIs have gl_Position(-1, -1) map to texel (0, 0). It
is just the present coordinate system that changes.
Remove some of the hacks we had to work around non-existent viewport
issues and fix tests.
Sometimes NXT provides default objects for parts of the pipelines, for
example a default pipeline layout. This objects were create with code
like: device->CreateFooBuilder()->GetResult(); and stored in a Ref<>.
This caused the object to have on external reference and two internal
references and not get destroyed when the Ref<> goes out. Call Release
on these objects to remove the external reference and fix the leak.
Was found via the Vulkan validation layers that were complaining that a
VkPipelineLayout was leaked.
This as this is the first command handled by the Vulkan backend, this
commit also introduces the b:✌️:CommandBUffer class and implements
b:✌️:Queue::Submit.
Also enables the BufferSetSubData tests that are now passing on Vulkan
even though the buffer transitions are unimplemented.
This introduce a new FencedDeleter service as part of the Device
objects that tracks when resources are no longer used and deletes them.
BufferVk takes advantage of this to defer the deletion of its handle
that was previously incorrectly delete directly in ~BufferVk.
On 32 bit Vulkan typedefs these handles to uint64_t which breaks
function overload resolution. Replace the
VK_DEFINE_NON_DISPATCHABLE_HANDLE and VK_NULL_HANDLE defines to be
opaque C++ types with the same capabilities.