1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
//! GPU compute pipeline system for Tessera UI framework.
//!
//! This module provides the infrastructure for GPU compute operations in Tessera,
//! enabling advanced visual effects and post-processing operations that would be
//! inefficient or impossible to achieve with traditional CPU-based approaches.
//!
//! # Architecture Overview
//!
//! The compute pipeline system is designed to work seamlessly with the rendering
//! pipeline, using a ping-pong buffer approach for efficient multi-pass operations.
//! Each compute pipeline processes a specific type of compute command and operates
//! on texture data using GPU compute shaders.
//!
//! ## Key Components
//!
//! - [`ComputablePipeline<C>`]: The main trait for implementing custom compute pipelines
//! - [`ComputePipelineRegistry`]: Manages and dispatches commands to registered compute pipelines
//! - [`ComputeResourceManager`]: Manages GPU buffers and resources for compute operations
//!
//! # Design Philosophy
//!
//! The compute pipeline system embraces WGPU's compute shader capabilities to enable:
//!
//! - **Advanced Post-Processing**: Blur, contrast adjustment, color grading, and other image effects
//! - **Parallel Processing**: Leverage GPU parallelism for computationally intensive operations
//! - **Real-Time Effects**: Achieve complex visual effects at interactive frame rates
//! - **Memory Efficiency**: Use GPU memory directly without CPU roundtrips
//!
//! # Ping-Pong Rendering
//!
//! The system uses a ping-pong approach where:
//!
//! 1. **Input Texture**: Contains the result from previous rendering or compute pass
//! 2. **Output Texture**: Receives the processed result from the current compute operation
//! 3. **Format Convention**: All textures use `wgpu::TextureFormat::Rgba8Unorm` for compatibility
//!
//! This approach enables efficient chaining of multiple compute operations without
//! intermediate CPU involvement.
//!
//! # Implementation Guide
//!
//! ## Creating a Custom Compute Pipeline
//!
//! To create a custom compute pipeline:
//!
//! 1. Define your compute command struct implementing [`ComputeCommand`]
//! 2. Create a pipeline struct implementing [`ComputablePipeline<YourCommand>`]
//! 3. Write a compute shader in WGSL
//! 4. Register the pipeline with [`ComputePipelineRegistry::register`]
//!
//! ## Example: Simple Brightness Adjustment Pipeline
//!
//! ```rust,ignore
//! use tessera_ui::{ComputeCommand, ComputablePipeline, compute::resource::ComputeResourceManager};
//! use wgpu;
//!
//! // 1. Define the compute command
//! #[derive(Debug)]
//! struct BrightnessCommand {
//! brightness: f32,
//! }
//!
//! impl ComputeCommand for BrightnessCommand {}
//!
//! // 2. Implement the pipeline
//! struct BrightnessPipeline {
//! compute_pipeline: wgpu::ComputePipeline,
//! bind_group_layout: wgpu::BindGroupLayout,
//! }
//!
//! impl BrightnessPipeline {
//! fn new(device: &wgpu::Device) -> Self {
//! // Create compute shader and pipeline
//! let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
//! label: Some("Brightness Shader"),
//! source: wgpu::ShaderSource::Wgsl(include_str!("brightness.wgsl").into()),
//! });
//!
//! // ... setup bind group layout and pipeline ...
//! # unimplemented!()
//! }
//! }
//!
//! impl ComputablePipeline<BrightnessCommand> for BrightnessPipeline {
//! fn dispatch(&mut self, context: &mut ComputeContext<BrightnessCommand>) {
//! // Create uniforms buffer with brightness value
//! let uniforms = [context.items[0].command.brightness];
//! let uniform_buffer = context.device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
//! label: Some("Brightness Uniforms"),
//! contents: bytemuck::cast_slice(&uniforms),
//! usage: wgpu::BufferUsages::UNIFORM,
//! });
//!
//! // Create bind group with input/output textures and uniforms
//! let bind_group = context.device.create_bind_group(&wgpu::BindGroupDescriptor {
//! layout: &self.bind_group_layout,
//! entries: &[
//! wgpu::BindGroupEntry { binding: 0, resource: uniform_buffer.as_entire_binding() },
//! wgpu::BindGroupEntry { binding: 1, resource: wgpu::BindingResource::TextureView(context.input_view) },
//! wgpu::BindGroupEntry { binding: 2, resource: wgpu::BindingResource::TextureView(context.output_view) },
//! ],
//! label: Some("brightness_bind_group"),
//! });
//!
//! // Dispatch compute shader
//! context.compute_pass.set_pipeline(&self.compute_pipeline);
//! context.compute_pass.set_bind_group(0, &bind_group, &[]);
//! context.compute_pass.dispatch_workgroups(
//! (context.config.width + 7) / 8,
//! (context.config.height + 7) / 8,
//! 1
//! );
//! }
//! }
//!
//! // 3. Register the pipeline
//! let mut registry = ComputePipelineRegistry::new();
//! let brightness_pipeline = BrightnessPipeline::new(&device);
//! registry.register(brightness_pipeline);
//! ```
//!
//! ## Example WGSL Compute Shader
//!
//! ```wgsl
//! @group(0) @binding(0) var<uniform> brightness: f32;
//! @group(0) @binding(1) var input_texture: texture_2d<f32>;
//! @group(0) @binding(2) var output_texture: texture_storage_2d<rgba8unorm, write>;
//!
//! @compute @workgroup_size(8, 8)
//! fn main(@builtin(global_invocation_id) global_id: vec3<u32>) {
//! let coords = vec2<i32>(global_id.xy);
//! let input_color = textureLoad(input_texture, coords, 0);
//! let output_color = vec4<f32>(input_color.rgb * brightness, input_color.a);
//! textureStore(output_texture, coords, output_color);
//! }
//! ```
//!
//! # Integration with Basic Components
//!
//! The `tessera_basic_components` crate provides several compute pipeline implementations:
//!
//! - **BlurPipeline**: Gaussian blur effects for backgrounds and UI elements
//! - **MeanPipeline**: Average color calculation for adaptive UI themes
//! - **ContrastPipeline**: Contrast and saturation adjustments
//!
//! These pipelines demonstrate real-world usage patterns and can serve as references
//! for implementing custom compute operations.
//!
//! # Performance Considerations
//!
//! - **Workgroup Size**: Choose workgroup sizes that align with GPU architecture (typically 8x8 or 16x16)
//! - **Memory Access**: Optimize memory access patterns in shaders for better cache utilization
//! - **Resource Reuse**: Use the [`ComputeResourceManager`] to reuse buffers across frames
//! - **Batch Operations**: Combine multiple similar operations when possible
//!
//! # Texture Format Requirements
//!
//! Due to WGPU limitations, compute shaders require specific texture formats:
//!
//! - **Input Textures**: Can be any readable format, typically from render passes
//! - **Output Textures**: Must use `wgpu::TextureFormat::Rgba8Unorm` for storage binding
//! - **sRGB Limitation**: sRGB formats cannot be used as storage textures
//!
//! The framework automatically handles format conversions when necessary.
use ;
use crate::;
use ComputeCommand;
/// Type-erased metadata describing a compute command within a batch.
/// Strongly typed metadata describing a compute command within a batch.
/// Provides comprehensive context for compute operations within a compute pass.
///
/// This struct bundles essential WGPU resources, configuration, and command-specific data
/// required for a compute pipeline to process its commands.
///
/// # Type Parameters
///
/// * `C` - The specific [`ComputeCommand`] type being processed.
///
/// # Fields
///
/// * `device` - The WGPU device, used for creating and managing GPU resources.
/// * `queue` - The WGPU queue, used for submitting command buffers and writing buffer data.
/// * `config` - The current surface configuration, providing information like format and dimensions.
/// * `compute_pass` - The active `wgpu::ComputePass` encoder, used to record compute commands.
/// * `items` - A slice of [`ComputeBatchItem`]s, each containing a compute command and its metadata.
/// * `resource_manager` - A mutable reference to the [`ComputeResourceManager`], used for managing reusable GPU buffers.
/// * `input_view` - A view of the input texture for the compute operation.
/// * `output_view` - A view of the output texture for the compute operation.
/// Core trait for implementing GPU compute pipelines.
///
/// This trait defines the interface for compute pipelines that process specific types
/// of compute commands using GPU compute shaders. Each pipeline is responsible for
/// setting up compute resources, managing shader dispatch, and processing texture data.
///
/// # Type Parameters
///
/// * `C` - The specific [`ComputeCommand`] type this pipeline can handle
///
/// # Design Principles
///
/// - **Single Responsibility**: Each pipeline handles one specific type of compute operation
/// - **Stateless Operation**: Pipelines should not maintain state between dispatch calls
/// - **Resource Efficiency**: Reuse GPU resources when possible through the resource manager
/// - **Thread Safety**: All implementations must be `Send + Sync` for parallel execution
///
/// # Integration with Rendering
///
/// Compute pipelines operate within the broader rendering pipeline, typically:
///
/// 1. **After Rendering**: Process the rendered scene for post-effects
/// 2. **Between Passes**: Transform data between different rendering stages
/// 3. **Before Rendering**: Prepare data or textures for subsequent render operations
///
/// # Example Implementation Pattern
///
/// ```rust,ignore
/// impl ComputablePipeline<MyCommand> for MyPipeline {
/// fn dispatch(&mut self, context: &mut ComputeContext<MyCommand>) {
/// for item in context.items {
/// // 1. Create or retrieve uniform buffer
/// let uniforms = create_uniforms_from_command(item.command);
/// let uniform_buffer = context.device.create_buffer_init(...);
///
/// // 2. Create bind group with textures and uniforms
/// let bind_group = context.device.create_bind_group(...);
///
/// // 3. Set pipeline and dispatch
/// context.compute_pass.set_pipeline(&self.compute_pipeline);
/// context.compute_pass.set_bind_group(0, &bind_group, &[]);
/// context.compute_pass.dispatch_workgroups(workgroup_x, workgroup_y, 1);
/// }
/// }
/// }
/// ```
/// Internal trait for type erasure of computable pipelines.
///
/// This trait enables dynamic dispatch of compute commands to their corresponding pipelines
/// without knowing the specific command type at compile time. It's used internally by
/// the [`ComputePipelineRegistry`] and should not be implemented directly by users.
///
/// The type erasure is achieved through the [`AsAny`] trait, which allows downcasting
/// from `&dyn ComputeCommand` to concrete command types.
///
/// # Implementation Note
///
/// This trait is automatically implemented for any type that implements
/// [`ComputablePipeline<C>`] through the [`ComputablePipelineImpl`] wrapper.
pub
/// A wrapper to implement `ErasedComputablePipeline` for any `ComputablePipeline`.
/// Registry for managing and dispatching compute pipelines.
///
/// The `ComputePipelineRegistry` serves as the central hub for all compute pipelines
/// in the Tessera framework. It maintains a collection of registered pipelines and
/// handles the dispatch of compute commands to their appropriate pipelines.
///
/// # Architecture
///
/// The registry uses type erasure to store pipelines of different types in a single
/// collection. When a compute command needs to be processed, the registry attempts
/// to dispatch it to all registered pipelines until one handles it successfully.
///
/// # Usage Pattern
///
/// 1. Create a new registry
/// 2. Register all required compute pipelines during application initialization
/// 3. The renderer uses the registry to dispatch commands during frame rendering
///
/// # Example
///
/// ```rust,ignore
/// use tessera_ui::renderer::compute::ComputePipelineRegistry;
///
/// // Create registry and register pipelines
/// let mut registry = ComputePipelineRegistry::new();
/// registry.register(blur_pipeline);
/// registry.register(contrast_pipeline);
/// registry.register(brightness_pipeline);
///
/// // Registry is now ready for use by the renderer
/// ```
///
/// # Performance Considerations
///
/// - Pipeline lookup is O(1) on average due to HashMap implementation.
///
/// # Thread Safety
///
/// The registry and all registered pipelines must be `Send + Sync` to support
/// parallel execution in the rendering system.