21 [[nodiscard]] Portal::Graphics::ShaderSpec require_spec(
22 const std::shared_ptr<Nodes::Network::GpuFieldOperator>& op)
25 error<std::invalid_argument>(
28 std::source_location::current(),
29 "VertexFieldProcessor: null field operator");
32 auto spec = op->build_spec();
33 if (!spec.has_value()) {
34 error<std::invalid_argument>(
37 std::source_location::current(),
38 "VertexFieldProcessor: operator produced no spec. Bind at least "
39 "one field, and supply a layout carrying a position attribute, "
40 "before constructing the processor.");
46 [[nodiscard]] glm::mat4 geometry_transform(
const std::shared_ptr<VKBuffer>&
buffer)
48 glm::mat4 transform { 1.0F };
49 if (
const auto render =
buffer->get_render_processor()) {
50 if (
const auto& source = render->get_geometry_transform_source()) {
52 }
else if (
const auto& fixed = render->get_geometry_transform()) {
57 const float determinant = glm::determinant(glm::mat3(transform));
58 return std::isfinite(determinant) && determinant != 0.0F ? transform : glm::mat4 { 1.0F };
64 std::shared_ptr<Nodes::Network::GpuFieldOperator> field_operator)
66 , m_operator(
std::move(field_operator))
67 , m_built_revision(m_operator->revision())
68 , m_needs_cluster_id(m_operator->needs_cluster_id())
103 auto vk_buf = std::dynamic_pointer_cast<VKBuffer>(
buffer);
106 "VertexFieldProcessor requires a VKBuffer");
117 m_epoch = std::chrono::steady_clock::now();
120 "VertexFieldProcessor attached: {} bytes, stride {} words, {} bound fields",
121 vk_buf->get_size_bytes(),
128 return std::chrono::duration<float>(
129 std::chrono::steady_clock::now() -
m_epoch)
134 const std::shared_ptr<VKBuffer>&
buffer)
const
137 if (stride_bytes == 0)
140 return static_cast<uint32_t
>(
buffer->get_size_bytes() / stride_bytes);
149 if (!spec.has_value()) {
151 "VertexFieldProcessor: operator no longer yields a spec after rebind. "
152 "Dispatch suppressed; the previous pipeline is not reused because it "
153 "no longer describes the bindings.");
175 "VertexFieldProcessor: rebuilt for revision {} ({} bound fields)",
183 const std::shared_ptr<VKBuffer>&
buffer)
198 "VertexFieldProcessor: range starts at {} but the buffer holds {} "
199 "records. Dispatch suppressed.",
218 "VertexFieldProcessor dispatch: [{}, {}) of {} records, stride {} words, t={:.3f}",
226 const glm::vec4& params =
m_operator->get_params();
235 const std::shared_ptr<VKBuffer>& )
238 const uint32_t local_x = std::max(1U, dispatch.workgroup_x);
241 return { std::max(1U, groups), 1U, 1U };
252 "VertexFieldProcessor: operator has a cluster-scoped binding but the "
253 "attached buffer is not a NetworkGeometryBuffer, so hash_cluster_id "
254 "has nowhere to live. Dispatch suppressed.");
260 "VertexFieldProcessor: operator has a cluster-scoped binding but "
261 "hash_cluster_id could not be derived (no primary GraphicsOperator, "
262 "or it reports zero points). Dispatch suppressed.");
279 foundry.update_descriptor_buffer(
281 vk::DescriptorType::eStorageBuffer, handle, 0, bytes);
#define MF_INFO(comp, ctx,...)
#define MF_ERROR(comp, ctx,...)
#define MF_RT_ERROR(comp, ctx,...)
#define MF_RT_TRACE(comp, ctx,...)
std::shared_ptr< NetworkGeometryBuffer > buffer
virtual void on_attach(const std::shared_ptr< Buffer > &)
Called when this processor is attached to a buffer.
ProcessingToken m_processing_token
const ShaderDispatchConfig & get_dispatch_config() const
Get current dispatch configuration.
Specialized ShaderProcessor for Compute Pipelines.
void set_push_constant_data(const T &data)
Update push constant data (type-safe)
void add_binding(const std::string &descriptor_name, const ShaderBinding &binding)
Add descriptor binding configuration.
void set_config(const ShaderConfig &config)
Update entire configuration.
void bind_buffer(const std::string &descriptor_name, const std::shared_ptr< VKBuffer > &buffer)
Bind a VKBuffer to a named shader descriptor.
std::vector< Portal::Graphics::DescriptorSetID > m_descriptor_set_ids
bool ensure_cluster_binding()
Ensure the backing hash_cluster_id state field exists, when m_needs_cluster_id is true.
bool on_before_execute(Portal::Graphics::CommandBufferID cmd_id, const std::shared_ptr< VKBuffer > &buffer) override
Rebuild on a stale revision, resolve the range, write push constants.
std::chrono::steady_clock::time_point m_epoch
std::shared_ptr< NetworkGeometryBuffer > m_network_buffer
uint32_t m_explicit_count
std::array< uint32_t, 3 > calculate_dispatch_size(const std::shared_ptr< VKBuffer > &buffer) override
One thread per record in the resolved range.
void clear_vertex_range()
Drop an explicit range and cover the whole buffer again.
uint32_t buffer_capacity(const std::shared_ptr< VKBuffer > &buffer) const
Records the buffer can hold at the operator's stride.
uint32_t m_explicit_first
std::shared_ptr< Nodes::Network::GpuFieldOperator > m_operator
void set_vertex_range(uint32_t first_vertex, uint32_t vertex_count)
Restrict the dispatch to a slice of the buffer.
bool sync_revision()
Recompile and rebuild the pipeline when the operator has changed.
void on_descriptors_created() override
Write the cluster_id descriptor when the operator needs one.
void on_attach(const std::shared_ptr< Buffer > &buffer) override
Called when this processor is attached to a buffer.
uint64_t m_built_revision
VertexFieldProcessor(std::shared_ptr< Nodes::Network::GpuFieldOperator > field_operator)
float elapsed() const
Seconds since construction, the value bound to the time parameter.
@ GRAPHICS_BACKEND
Standard graphics processing backend configuration.
@ BufferProcessing
Buffer processing (Buffers::BufferManager, processing chains)
@ Buffers
Buffers, Managers, processors and processing chains.
@ STORAGE
Large arrays or buffers the shader may write (SSBO)
MAYAFLUX_API ShaderFoundry & get_shader_foundry()
Get the global shader compiler instance.
Describes how a VKBuffer binds to a shader descriptor.
Push constant block when the operator carries parametric fields.