MayaFlux 0.5.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
MayaFlux::Portal::Graphics::PrimitiveMill Class Reference

Mills spans of mixed primitive topology into one TRIANGLE_LIST vertex buffer on the GPU. More...

#include <PrimitiveMill.hpp>

+ Collaboration diagram for MayaFlux::Portal::Graphics::PrimitiveMill:

Public Member Functions

uint32_t mill (const std::shared_ptr< Buffers::VKBuffer > &source, std::span< const DrawRun > runs, const MillView &view)
 Mill runs out of source into the owned buffer.
 
uint32_t milled_count () const
 Vertices written by the last mill().
 
PrimitiveMilloperator= (const PrimitiveMill &)=delete
 
PrimitiveMilloperator= (PrimitiveMill &&)=delete
 
std::shared_ptr< Buffers::VKBufferoutput () const
 The milled triangles: the ring slot the last mill() wrote.
 
 PrimitiveMill (const PrimitiveMill &)=delete
 
 PrimitiveMill (MillSpec spec={}, uint32_t output_ring=2)
 
 PrimitiveMill (PrimitiveMill &&)=delete
 
void release ()
 Destroy the kernel, pipeline, descriptor sets and buffers.
 
void set_spec (const MillSpec &spec)
 Replace the spec.
 
const MillSpecspec () const
 
 ~PrimitiveMill ()
 

Static Public Member Functions

static uint32_t milled_vertex_count (std::span< const DrawRun > runs)
 Vertices runs would mill to.
 

Private Member Functions

bool ensure_buffers (const std::shared_ptr< Buffers::VKBuffer > &source, const Kakshya::VertexLayout &layout, uint32_t total, size_t run_count)
 Grows the destination ring, run and prefix buffers to fit.
 
bool ensure_kernel ()
 Compiles the kernel and allocates its descriptor sets, once.
 
void resolve_pending ()
 Wait on and reclaim the previous dispatch, if one is outstanding.
 
void write_descriptors (const std::shared_ptr< Buffers::VKBuffer > &source)
 Points the descriptor set at the current buffer set, on any change of source or ring slot.
 

Private Attributes

size_t m_bound_slot { 0 }
 Ring slot the descriptor set currently points at, for invalidation.
 
std::weak_ptr< Buffers::VKBufferm_bound_source
 Source the descriptor set currently points at, for invalidation.
 
bool m_descriptors_written { false }
 
uint32_t m_milled_count { 0 }
 
uint32_t m_output_capacity { 0 }
 
uint32_t m_output_ring { 2 }
 
size_t m_output_slot { 0 }
 
std::vector< std::shared_ptr< Buffers::VKBuffer > > m_outputs
 Milled buffers rotated between dispatches, all at m_output_capacity.
 
FenceID m_pending_fence { INVALID_FENCE }
 Outstanding dispatch, resolved at the start of the next mill().
 
ComputePipelineID m_pipeline { INVALID_COMPUTE_PIPELINE }
 
std::vector< uint32_t > m_prefix
 
std::shared_ptr< Buffers::VKBufferm_prefix_buf
 
size_t m_push_constant_size { 0 }
 
std::shared_ptr< Buffers::VKBufferm_run_buf
 
std::vector< DescriptorSetIDm_sets
 
ShaderID m_shader { INVALID_SHADER }
 
MillSpec m_spec
 

Detailed Description

Mills spans of mixed primitive topology into one TRIANGLE_LIST vertex buffer on the GPU.

One job. Given a source vertex buffer, its layout, and a list of DrawRun spans, it produces a single triangle buffer carrying that same vertex layout, so every span can be drawn by one non-indexed draw at one topology. Points become quads, line segments become ribbons, triangle spans reduce to lists. Positions are rewritten and texture coordinates optionally synthesised; every other attribute is copied bit-exact from the source vertex its corner belongs to, so a vertex shader written against the source layout consumes the result unchanged.

Owns its kernel, pipeline, descriptor sets and destination buffers, and dispatches through ComputePress directly. It is a dispatch driver in the manner of Yantra's GPU executor, not a BufferProcessor: no processing token, no attach, no chain membership, no per-cycle driver. Milling is demand driven by whoever is about to draw, so a chain position would fix when it runs relative to the geometry it consumes.

The output is a transient draw source, not authored geometry. It is regenerated whenever the spans or the viewpoint change, its vertices have no correspondence back to the source, and it is not an export or readback surface. The intended caller is a render processor resolving its geometry immediately before recording.

Known gaps

Ribbon quality is not yet good enough for drawing work. Joins are mitred, so consecutive segments share their corners, but the result still shows visible unevenness along a curve. The remaining causes are not isolated: candidates are the miter limit falling back to the plain segment normal at moderate angles, width being resolved per vertex rather than along arc length, and the absence of any round join or cap.

Width is fixed in world units. A geometry shader expanding after projection holds a constant pixel width at any camera distance; this cannot, so a ribbon thins on screen as the camera pulls back. Matching a screen-space width would require expanding after the vertex shader, which a compute prepass cannot do.

mill_on_host has diverged and is no longer an oracle for the kernel. It implements the unjoined form only: no miter, no width averaging across shared positions. Treat it as a reference for span indexing and expansion counts, not for ribbon geometry, until it is brought back into step.

A producer emitting a polyline as duplicated vertex pairs costs twice the milled vertices it needs, since every second segment is a zero-length seam that collapses. Detected and skipped, but still budgeted for.

Definition at line 134 of file PrimitiveMill.hpp.


The documentation for this class was generated from the following files: