1 module gfx.graal.pipeline; 2 3 import gfx.core.rc; 4 import gfx.core.typecons; 5 import gfx.graal.buffer; 6 import gfx.graal.format; 7 import gfx.graal.image; 8 import gfx.graal.renderpass; 9 import gfx.graal.types; 10 11 import std.typecons : Flag; 12 13 interface ShaderModule : AtomicRefCounted 14 { 15 import gfx.graal.device : Device; 16 17 /// Get the parent device 18 @property Device device(); 19 20 @property string entryPoint(); 21 } 22 23 interface PipelineLayout : AtomicRefCounted 24 { 25 import gfx.graal.device : Device; 26 27 /// Get the parent device 28 @property Device device(); 29 } 30 31 interface Pipeline : AtomicRefCounted 32 { 33 import gfx.graal.device : Device; 34 35 /// Get the parent device 36 @property Device device(); 37 } 38 39 interface DescriptorSetLayout : AtomicRefCounted 40 { 41 import gfx.graal.device : Device; 42 43 /// Get the parent device 44 @property Device device(); 45 } 46 47 interface DescriptorPool : AtomicRefCounted 48 { 49 import gfx.graal.device : Device; 50 51 /// Get the parent device 52 @property Device device(); 53 54 /// Allocate a descriptor set per descriptor layout passed as argument 55 DescriptorSet[] allocate(DescriptorSetLayout[] layouts); 56 57 /// Reset this pool. 58 /// All descriptors allocated with this pool are invalid after this call 59 void reset(); 60 } 61 62 interface DescriptorSet 63 { 64 @property DescriptorPool pool(); 65 } 66 67 struct PipelineInfo { 68 GraphicsShaderSet shaders; 69 VertexInputBinding[] inputBindings; 70 VertexInputAttrib[] inputAttribs; 71 InputAssembly assembly; 72 Rasterizer rasterizer; 73 /// Viewport configuration of the pipeline. 74 /// For dynamic viewport, leave this array empty 75 ViewportConfig[] viewports; 76 77 // TODO: tesselation, multisample 78 79 DepthInfo depthInfo; 80 StencilInfo stencilInfo; 81 ColorBlendInfo blendInfo; 82 83 DynamicState[] dynamicStates; 84 85 PipelineLayout layout; 86 87 RenderPass renderPass; 88 uint subpassIndex; 89 } 90 91 enum ShaderStage { 92 vertex = 0x01, 93 tessellationControl = 0x02, 94 tessellationEvaluation = 0x04, 95 geometry = 0x08, 96 fragment = 0x10, 97 compute = 0x20, 98 99 allGraphics = 0x1f, 100 all = allGraphics | compute, 101 } 102 103 struct GraphicsShaderSet { 104 ShaderModule vertex; 105 ShaderModule tessControl; 106 ShaderModule tessEval; 107 ShaderModule geometry; 108 ShaderModule fragment; 109 } 110 111 112 /// Describes the binding of a buffer to the pipeline 113 struct VertexInputBinding { 114 uint binding; 115 size_t stride; 116 Flag!"instanced" instanced; 117 } 118 119 /// Describes a vertex attribute 120 struct VertexInputAttrib { 121 uint location; 122 uint binding; 123 Format format; 124 size_t offset; 125 } 126 127 128 enum Primitive { 129 pointList, lineList, lineStrip, 130 triangleList, triangleStrip, triangleFan, 131 lineListAdjacency, lineStripAdjacency, 132 triangleListAdjacency, triangleStripAdjacency, 133 patchList, 134 } 135 136 struct InputAssembly { 137 Primitive primitive; 138 Flag!"primitiveRestart" primitiveRestart; 139 } 140 141 enum FrontFace { 142 ccw, cw, 143 } 144 145 enum Cull { 146 none = 0x00, 147 front = 0x01, 148 back = 0x02, 149 frontAndBack = front | back, 150 } 151 152 enum PolygonMode { 153 fill, line, point, 154 } 155 156 /// Defines how a polygon can be offset (mainly to avoid shadow artifacts). 157 /// Given m as maximum depth slope of the triangle and r as implementation defined 158 /// minimal resolvable difference, the offset of the triangle is defined as follow: 159 /// o = m * slopeFactor + r * constantFactor 160 /// If clamp == 0f, o is used directly as effective offset. 161 /// If clamp > 0f, the effective offset is min(o, clamp) 162 /// If clamp < 0f, the effective offset is max(o, clamp) 163 struct DepthBias 164 { 165 /// Factor multiplied by the minimal resolvable difference of the depth buffer 166 float constantFactor; 167 /// Clamps the effective offset to a particular value 168 float clamp; 169 /// Factor multiplied by the maximum depth slope of the polygon. 170 float slopeFactor; 171 } 172 173 struct Rasterizer { 174 PolygonMode mode; 175 Cull cull; 176 FrontFace front; 177 Flag!"depthClamp" depthClamp; 178 Option!DepthBias depthBias; 179 float lineWidth=1f; 180 } 181 182 struct ViewportConfig { 183 Viewport viewport; 184 Rect scissors; 185 } 186 187 enum CompareOp 188 { 189 never, less, equal, lessOrEqual, greater, notEqual, greaterOrEqual, always, 190 } 191 192 enum StencilOp 193 { 194 keep, 195 zero, 196 replace, 197 incrementAndClamp, 198 decrementAndClamp, 199 invert, 200 incrementAndWrap, 201 decrementAndWrap, 202 } 203 204 struct DepthInfo 205 { 206 Flag!"enabled" enabled; 207 Flag!"write" write; 208 CompareOp compareOp; 209 Flag!"boundsTest" boundsTest; 210 float minBounds; 211 float maxBounds; 212 213 @property static DepthInfo none() { 214 return DepthInfo.init; 215 } 216 } 217 218 struct StencilOpState 219 { 220 StencilOp failOp; 221 StencilOp passOp; 222 StencilOp depthFailOp; 223 CompareOp compareOp; 224 uint compareMask; 225 uint writeMask; 226 uint refMask; 227 } 228 229 struct StencilInfo 230 { 231 Flag!"enabled" enabled; 232 StencilOpState front; 233 StencilOpState back; 234 235 @property static StencilInfo none() { 236 return StencilInfo.init; 237 } 238 } 239 240 241 enum BlendFactor 242 { 243 zero = 0, 244 one = 1, 245 srcColor = 2, 246 oneMinusSrcColor = 3, 247 dstColor = 4, 248 oneMinusDstColor = 5, 249 srcAlpha = 6, 250 oneMinusSrcAlpha = 7, 251 dstAlpha = 8, 252 oneMinusDstAlpha = 9, 253 constantColor = 10, 254 oneMinusConstantColor = 11, 255 constantAlpha = 12, 256 oneMinusConstantAlpha = 13, 257 srcAlphaSaturate = 14, 258 src1Color = 15, 259 oneMinusSrc1Color = 16, 260 src1Alpha = 17, 261 oneMinusSrc1Alpha = 18, 262 } 263 264 enum BlendOp { 265 add, 266 subtract, 267 reverseSubtract, 268 min, 269 max, 270 } 271 272 struct BlendState { 273 Trans!BlendFactor factor; 274 BlendOp op; 275 } 276 277 enum ColorMask { 278 r = 0x01, 279 g = 0x02, 280 b = 0x04, 281 a = 0x08, 282 283 none = 0x00, 284 all = r | g | b | a, 285 rg = r | g, 286 rb = r | b, 287 ra = r | a, 288 gb = g | b, 289 ga = g | a, 290 ba = b | a, 291 rgb = r | g | b, 292 rga = r | g | a, 293 rba = r | b | a, 294 gba = g | b | a, 295 rgba = r | g | b | a, 296 } 297 298 struct ColorBlendAttachment { 299 Flag!"enabled" enabled; 300 BlendState colorBlend; 301 BlendState alphaBlend; 302 ColorMask colorMask; 303 304 static ColorBlendAttachment solid(in ColorMask mask=ColorMask.all) { 305 import std.typecons : No; 306 return ColorBlendAttachment( 307 No.enabled, BlendState.init, BlendState.init, mask 308 ); 309 } 310 311 static ColorBlendAttachment blend(in BlendState blendState, 312 in ColorMask mask=ColorMask.all) { 313 import std.typecons : Yes; 314 return ColorBlendAttachment( 315 Yes.enabled, blendState, blendState, mask 316 ); 317 } 318 319 static ColorBlendAttachment blend(in BlendState color, in BlendState alpha, 320 in ColorMask mask=ColorMask.all) { 321 import std.typecons : Yes; 322 return ColorBlendAttachment( 323 Yes.enabled, color, alpha, mask 324 ); 325 } 326 } 327 328 enum LogicOp { 329 clear, 330 and, 331 andReverse, 332 copy, 333 andInverted, 334 noop, 335 xor, 336 or, 337 nor, 338 equivalent, 339 invert, 340 orReverse, 341 copyInverted, 342 orInverted, 343 nand, 344 set, 345 } 346 347 struct ColorBlendInfo 348 { 349 Option!LogicOp logicOp; 350 ColorBlendAttachment[] attachments; 351 float[4] blendConstants = [ 0f, 0f, 0f, 0f ]; 352 } 353 354 enum DynamicState { 355 viewport, 356 scissor, 357 lineWidth, 358 depthBias, 359 blendConstants, 360 depthBounds, 361 stencilCmpMask, 362 stencilWriteMask, 363 stencilRef, 364 } 365 366 enum DescriptorType { 367 sampler, 368 combinedImageSampler, 369 sampledImage, 370 storageImage, 371 uniformTexelBuffer, 372 storageTexelBuffer, 373 uniformBuffer, 374 storageBuffer, 375 uniformBufferDynamic, 376 storageBufferDynamic, 377 inputAttachment, 378 } 379 380 struct PipelineLayoutBinding { 381 uint binding; 382 DescriptorType descriptorType; 383 uint descriptorCount; 384 ShaderStage stages; 385 } 386 387 struct PushConstantRange { 388 ShaderStage stages; 389 uint offset; 390 uint size; 391 } 392 393 struct DescriptorPoolSize { 394 DescriptorType type; 395 uint count; 396 } 397 398 struct WriteDescriptorSet { 399 DescriptorSet dstSet; 400 uint dstBinding; 401 uint dstArrayElem; 402 DescriptorWrites writes; 403 } 404 405 struct CopyDescritporSet { 406 Trans!DescriptorSet set; 407 Trans!uint binding; 408 Trans!uint arrayElem; 409 } 410 411 abstract class DescriptorWrites 412 { 413 this(DescriptorType type, size_t count) { 414 _type = type; 415 _count = count; 416 } 417 final @property DescriptorType type() const { 418 return _type; 419 } 420 final @property size_t count() const { 421 return _count; 422 } 423 private DescriptorType _type; 424 private size_t _count; 425 } 426 427 class TDescWritesBase(Desc) : DescriptorWrites 428 { 429 this(Desc[] descs, DescriptorType type) { 430 super(type, descs.length); 431 _descs = descs; 432 } 433 final @property Desc[] descs() { 434 return _descs; 435 } 436 private Desc[] _descs; 437 } 438 439 final class TDescWrites(Desc, DescriptorType ctType) : TDescWritesBase!Desc 440 { 441 this(Desc[] descs) { 442 super(descs, ctType); 443 } 444 } 445 446 struct CombinedImageSampler { 447 Sampler sampler; 448 ImageView view; 449 ImageLayout layout; 450 } 451 452 struct ImageViewLayout { 453 ImageView view; 454 ImageLayout layout; 455 } 456 457 struct BufferRange { 458 Buffer buffer; 459 size_t offset; 460 size_t range; 461 } 462 463 alias SamplerDescWrites = TDescWrites!(Sampler, DescriptorType.sampler); 464 alias CombinedImageSamplerDescWrites = TDescWrites!(CombinedImageSampler, DescriptorType.combinedImageSampler); 465 alias SampledImageDescWrites = TDescWrites!(ImageViewLayout, DescriptorType.sampledImage); 466 alias StorageImageDescWrites = TDescWrites!(ImageViewLayout, DescriptorType.storageImage); 467 alias InputAttachmentDescWrites = TDescWrites!(ImageViewLayout, DescriptorType.inputAttachment); 468 alias UniformBufferDescWrites = TDescWrites!(BufferRange, DescriptorType.uniformBuffer); 469 alias StorageBufferDescWrites = TDescWrites!(BufferRange, DescriptorType.storageBuffer); 470 alias UniformBufferDynamicDescWrites = TDescWrites!(BufferRange, DescriptorType.uniformBufferDynamic); 471 alias StorageBufferDynamicDescWrites = TDescWrites!(BufferRange, DescriptorType.storageBufferDynamic); 472 alias UniformTexelBufferDescWrites = TDescWrites!(BufferView, DescriptorType.uniformTexelBuffer); 473 alias StorageTexelBufferDescWrites = TDescWrites!(BufferView, DescriptorType.storageTexelBuffer);