1 /// An idiomatic D wrapper for <a href="https://github.com/gfx-rs/wgpu-native">wgpu-native</a>. 2 /// 3 /// Authors: Chance Snow 4 /// Copyright: Copyright © 2020 Chance Snow. All rights reserved. 5 /// License: MIT License 6 module wgpu.api; 7 8 import core.stdc.config : c_ulong; 9 import std.conv : to; 10 import std.string : toStringz; 11 import std.traits : fullyQualifiedName; 12 13 import wgpu.bindings; 14 15 /// Version of <a href="https://github.com/gfx-rs/wgpu-native">wgpu-native</a> this library binds. 16 /// See_Also: <a href="https://github.com/gfx-rs/wgpu-native/releases/tag/v0.6.0">github.com/gfx-rs/wgpu-native/releases/tag/v0.6.0</a> 17 static const VERSION = "0.6.0"; 18 /// Buffer-Texture copies must have bytes_per_row aligned to this number. 19 /// 20 /// This doesn't apply to `Queue.writeTexture`. 21 static const COPY_BYTES_PER_ROW_ALIGNMENT = 256; 22 23 // TODO: Does the library need these? 24 /// Unknown 25 static const DESIRED_NUM_FRAMES = 3; 26 /// Maximum anisotropy. 27 static const MAX_ANISOTROPY = 16; 28 /// Maximum number of color targets. 29 static const MAX_COLOR_TARGETS = 4; 30 /// Maximum amount of mipmap levels. 31 static const MAX_MIP_LEVELS = 16; 32 /// Maximum number of vertex buffers. 33 static const MAX_VERTEX_BUFFERS = 16; 34 35 alias WgpuId = c_ulong; 36 alias RequestAdapterOptions = WGPURequestAdapterOptions; 37 /// Metadata about a backend adapter. 38 /// See_Also: <a href="https://docs.rs/wgpu/0.6.0/wgpu/struct.AdapterInfo.html">wgpu::AdapterInfo</a> 39 alias AdapterInfo = WGPUCAdapterInfo; 40 /// Features that are not guaranteed to be supported. 41 /// 42 /// These are either part of the webgpu standard, or are extension features supported by wgpu when targeting native. 43 /// 44 /// If you want to use a feature, you need to first verify that the adapter supports the feature. If the adapter 45 /// does not support the feature, requesting a device with it enabled will panic. 46 /// See_Also: <a href="https://docs.rs/wgpu/0.6.0/wgpu/struct.Features.html">wgpu::Features</a> 47 alias Features = WGPUFeatures; 48 /// Represents the sets of limits an adapter/device supports. 49 /// 50 /// Limits "better" than the default must be supported by the adapter and requested when requesting a device. 51 /// If limits "better" than the adapter supports are requested, requesting a device will panic. Once a device is 52 /// requested, you may only use resources up to the limits requested even if the adapter supports "better" limits. 53 /// 54 /// Requesting limits that are "better" than you need may cause performance to decrease because the implementation 55 /// needs to support more than is needed. You should ideally only request exactly what you need. 56 /// 57 /// <strong>See Also</strong>: https://gpuweb.github.io/gpuweb/#dictdef-gpulimits 58 /// See_Also: <a href="https://docs.rs/wgpu/0.6.0/wgpu/struct.Limits.html">wgpu::Limits</a> 59 alias Limits = WGPUCLimits; 60 /// RGBA double precision color. 61 /// 62 /// This is not to be used as a generic color type, only for specific wgpu interfaces. 63 /// See_Also: <a href="https://docs.rs/wgpu/0.6.0/wgpu/struct.Color.html">wgpu::Color</a> 64 alias Color = WGPUColor; 65 /// Describes a `Texture`. 66 alias TextureDescriptor = WGPUTextureDescriptor; 67 /// Describes a `TextureView`. 68 alias TextureViewDescriptor = WGPUTextureViewDescriptor; 69 /// Describes a `Sampler`. 70 alias SamplerDescriptor = WGPUSamplerDescriptor; 71 /// Extent of a texture related operation. 72 alias Extent3d = WGPUExtent3d; 73 /// Describes a `SwapChain`. 74 alias SwapChainDescriptor = WGPUSwapChainDescriptor; 75 76 /// Integral type used for buffer offsets. 77 alias BufferAddress = WGPUBufferAddress; 78 /// Describes a `Buffer`. 79 alias BufferDescriptor = WGPUBufferDescriptor; 80 /// Describes a `CommandEncoder`. 81 alias CommandEncoderDescriptor = WGPUCommandEncoderDescriptor; 82 /// Origin of a copy to/from a texture. 83 alias Origin3d = WGPUOrigin3d; 84 /// View of a texture which can be used to copy to/from a buffer/texture. 85 alias TextureCopyView = WGPUTextureCopyView; 86 /// Layout of a texture in a buffer's memory. 87 alias TextureDataLayout = WGPUTextureDataLayout; 88 /// View of a buffer which can be used to copy to/from a texture. 89 alias BufferCopyView = WGPUBufferCopyView; 90 /// Describes a `BindGroup`. 91 alias BindGroupDescriptor = WGPUBindGroupDescriptor; 92 /// Describes a single binding inside a bind group. 93 alias BindGroupLayoutEntry = WGPUBindGroupLayoutEntry; 94 /// Describes a `BindGroupLayout`. 95 alias BindGroupLayoutDescriptor = WGPUBindGroupLayoutDescriptor; 96 /// Describes a `PipelineLayout`. 97 alias PipelineLayoutDescriptor = WGPUPipelineLayoutDescriptor; 98 /// Describes a `RenderPipeline`. 99 alias RenderPipelineDescriptor = WGPURenderPipelineDescriptor; 100 /// Describes a `ComputePipeline`. 101 alias ComputePipelineDescriptor = WGPUComputePipelineDescriptor; 102 /// Describes a `RenderPass`. 103 alias RenderPassDescriptor = WGPURenderPassDescriptor; 104 /// Describes a color attachment to a `RenderPass`. 105 alias RenderPassColorAttachmentDescriptor = WGPURenderPassColorAttachmentDescriptor; 106 alias PassChannel_Color = WGPUPassChannel_Color; 107 /// Describes a `ComputePass`. 108 alias ComputePassDescriptor = WGPUComputePassDescriptor; 109 /// Describes a `CommandBuffer`. 110 alias CommandBufferDescriptor = WGPUCommandBufferDescriptor; 111 112 public import wgpu.bindings: AddressMode, Backend, BindingType, BlendFactor, BlendOperation, CDeviceType, 113 CompareFunction, CullMode, FilterMode, FrontFace, IndexFormat, InputStepMode, LoadOp, LogLevel, PowerPreference, 114 PresentMode, PrimitiveTopology, SType, StencilOperation, StoreOp, SwapChainStatus, TextureAspect, 115 TextureComponentType, TextureDimension, TextureFormat, TextureViewDimension, VertexFormat; 116 117 /// Describes the shader stages that a binding will be visible from. 118 /// 119 /// These can be combined in a bitwise combination. 120 /// 121 /// For example, something that is visible from both vertex and fragment shaders can be defined as: 122 /// 123 /// `ShaderStage.vertex | ShaderStage.fragment` 124 /// See_Also: <a href="https://docs.rs/wgpu/0.6.0/wgpu/struct.ShaderStage.html">wgpu::ShaderStage</a> 125 enum ShaderStage : WGPUShaderStage { 126 /// Binding is not visible from any shader stage. 127 none = 0, 128 /// Binding is visible from the vertex shader of a render pipeline. 129 vertex = 1, 130 /// Binding is visible from the fragment shader of a render pipeline. 131 fragment = 2, 132 /// Binding is visible from the compute shader of a compute pipeline. 133 compute = 4 134 } 135 136 /// Different ways that you can use a buffer. 137 /// 138 /// The usages determine what kind of memory the buffer is allocated from and what actions the buffer can partake in. 139 /// 140 /// These can be combined in a bitwise combination. 141 /// See_Also: <a href="https://docs.rs/wgpu/0.6.0/wgpu/struct.BufferUsage.html">wgpu::BufferUsage</a> 142 enum BufferUsage : WGPUBufferUsage { 143 mapRead = 1, 144 mapWrite = 2, 145 copySrc = 4, 146 copyDst = 8, 147 index = 16, 148 vertex = 32, 149 uniform = 64, 150 storage = 128, 151 indirect = 256 152 } 153 154 /// Different ways that you can use a texture. 155 /// 156 /// The usages determine what kind of memory the texture is allocated from and what actions the texture can partake in. 157 /// 158 /// These can be combined in a bitwise combination. 159 /// See_Also: <a href="https://docs.rs/wgpu/0.6.0/wgpu/struct.TextureUsage.html">wgpu::TextureUsage</a> 160 enum TextureUsage : WGPUTextureUsage { 161 copySrc = 1, 162 copyDst = 2, 163 sampled = 4, 164 storage = 8, 165 outputAttachment = 16 166 } 167 168 extern (C) private void wgpu_request_adapter_callback(ulong id, void* data) { 169 assert(data !is null); 170 auto adapter = cast(Adapter*) data; 171 assert(id > 0); 172 adapter.id = id; 173 } 174 175 /// A handle to a physical graphics and/or compute device. 176 /// 177 /// See_Also: <a href="https://docs.rs/wgpu/0.6.0/wgpu/struct.Adapter.html">wgpu::Adapter</a> 178 struct Adapter { 179 /// Handle identifier. 180 WgpuId id; 181 182 /// Requests a new Adapter, asynchronously. 183 /// 184 /// Use `ready` to determine whether an Adapter was successfully requested. 185 this(const RequestAdapterOptions options) { 186 const allowedBackends = Backend.Vulkan | Backend.Metal | Backend.Dx12; 187 wgpu_request_adapter_async(&options, allowedBackends, false, &wgpu_request_adapter_callback, &this); 188 } 189 190 /// Release the given handle. 191 void destroy() { 192 if (ready) wgpu_adapter_destroy(id); 193 id = 0; 194 } 195 196 /// Whether this Adapter handle has finished being requested and is ready for use. 197 bool ready() @property const { 198 return id > 0; 199 } 200 201 /// Information about this Adapter. 202 AdapterInfo info() @property const { 203 assert(ready); 204 AdapterInfo info; 205 wgpu_adapter_get_info(id, &info); 206 return info; 207 } 208 209 /// List all features that are supported with this adapter. 210 /// 211 /// Features must be explicitly requested in `Adapter.requestDevice` in order to use them. 212 Features features() @property const { 213 return wgpu_adapter_features(id); 214 } 215 216 /// List the "best" limits that are supported by this adapter. 217 /// 218 /// Limits must be explicitly requested in `Adapter.requestDevice` to set the values that you are allowed to use. 219 Limits limits() @property const { 220 return wgpu_adapter_limits(id); 221 } 222 223 /// Requests a connection to a physical device, creating a logical device. 224 /// 225 /// Params: 226 /// limits = The sets of limits the device supports. 227 /// label = Optional label for the `Device`. 228 Device requestDevice(const Limits limits, string label = fullyQualifiedName!Device) { 229 assert(ready); 230 auto id = wgpu_adapter_request_device(id, 0, &limits, true, toStringz(label)); 231 return Device(id, label); 232 } 233 } 234 235 /// An open connection to a graphics and/or compute device. 236 /// 237 /// The `Device` is the responsible for the creation of most rendering and compute resources, as well as exposing `Queue` objects. 238 /// See_Also: <a href="https://docs.rs/wgpu/0.6.0/wgpu/struct.Device.html">wgpu::Device</a> 239 struct Device { 240 /// Handle identifier. 241 WgpuId id; 242 /// Label for this Device. 243 string label; 244 245 /// Release the given handle. 246 void destroy() { 247 if (ready) wgpu_device_destroy(id); 248 id = 0; 249 } 250 251 /// Whether this Device handle is valid and ready for use. 252 /// 253 /// If `false`, `Adapter.requestDevice` likely failed. 254 bool ready() @property const { 255 return id > 0; 256 } 257 258 /// List all limits that were requested of this device. 259 /// 260 /// If any of these limits are exceeded, functions may panic. 261 Limits limits() @property const { 262 return wgpu_device_limits(id); 263 } 264 265 /// Obtains a queue which can accept `CommandBuffer` submissions. 266 Queue queue() @property const { 267 return Queue(wgpu_device_get_default_queue(id)); 268 } 269 270 /// Check for resource cleanups and mapping callbacks. 271 /// Params: 272 /// forceWait = Whether or not the call should block. 273 void poll(bool forceWait = false) { 274 wgpu_device_poll(id, forceWait); 275 } 276 277 /// Creates a shader module from SPIR-V source code. 278 ShaderModule createShaderModule(const byte[] spv) { 279 import std.algorithm.iteration : map; 280 import std.array : array; 281 282 const bytes = spv.map!(byte_ => byte_.to!(const uint)).array; 283 return ShaderModule(wgpu_device_create_shader_module( 284 id, 285 WGPUShaderSource(bytes.ptr, spv.length)) 286 ); 287 } 288 289 /// Creates an empty `CommandEncoder`. 290 CommandEncoder createCommandEncoder(const CommandEncoderDescriptor descriptor) { 291 return CommandEncoder(wgpu_device_create_command_encoder(id, &descriptor), descriptor); 292 } 293 294 /// Creates a new bind group. 295 BindGroup createBindGroup(const BindGroupDescriptor descriptor) { 296 return BindGroup(wgpu_device_create_bind_group(id, &descriptor), descriptor); 297 } 298 299 /// Creates a bind group layout. 300 BindGroupLayout createBindGroupLayout(const BindGroupLayoutDescriptor descriptor) { 301 return BindGroupLayout(wgpu_device_create_bind_group_layout(id, &descriptor), descriptor); 302 } 303 304 /// Creates a bind group layout. 305 PipelineLayout createPipelineLayout(const PipelineLayoutDescriptor descriptor) { 306 return PipelineLayout(wgpu_device_create_pipeline_layout(id, &descriptor), descriptor); 307 } 308 309 /// Creates a render pipeline. 310 RenderPipeline createRenderPipeline(const RenderPipelineDescriptor descriptor) { 311 return RenderPipeline(wgpu_device_create_render_pipeline(id, &descriptor), descriptor); 312 } 313 314 /// Creates a compute pipeline. 315 ComputePipeline createComputePipeline(const ComputePipelineDescriptor descriptor) { 316 return ComputePipeline(wgpu_device_create_compute_pipeline(id, &descriptor), descriptor); 317 } 318 319 /// Creates a new buffer. 320 Buffer createBuffer(const BufferDescriptor descriptor) { 321 return Buffer(wgpu_device_create_buffer(id, &descriptor), descriptor); 322 } 323 324 /// Creates a new `Texture`. 325 /// 326 /// Params: 327 /// descriptor = Specifies the general format of the texture. 328 Texture createTexture(const TextureDescriptor descriptor) { 329 return Texture(wgpu_device_create_texture(id, &descriptor), descriptor); 330 } 331 332 /// Creates a new `Sampler`. 333 /// 334 /// Params: 335 /// descriptor = Specifies the behavior of the sampler. 336 Sampler createSampler(const SamplerDescriptor descriptor) { 337 return Sampler(wgpu_device_create_sampler(id, &descriptor), descriptor); 338 } 339 340 /// Create a new `SwapChain` which targets `surface`. 341 SwapChain createSwapChain(const Surface surface, const SwapChainDescriptor descriptor) { 342 return SwapChain(wgpu_device_create_swap_chain(id, surface.id, &descriptor), descriptor); 343 } 344 } 345 346 /// A handle to a presentable surface. 347 /// 348 /// A Surface represents a platform-specific surface (e.g. a window) to which rendered images may be presented. 349 /// A Surface may be created with `Surface.create`. 350 /// See_Also: <a href="https://docs.rs/wgpu/0.6.0/wgpu/struct.Surface.html">wgpu::Surface</a> 351 struct Surface { 352 /// Handle identifier. 353 WgpuId id; 354 355 version (Windows) { 356 /// Create a new `Surface` from an Android handle. 357 static Surface fromAndroid(void* androidNativeWindow) { 358 return Surface(wgpu_create_surface_from_android( androidNativeWindow)); 359 } 360 } 361 version (OSX) { 362 /// Create a new `Surface` from a Metal layer. 363 static Surface fromMetalLayer(void* layer) { 364 return Surface(wgpu_create_surface_from_metal_layer(layer)); 365 } 366 } 367 version (linux) { 368 /// Create a new `Surface` from a Wayland window handle. 369 static Surface fromWayland(void* surface, void* display) { 370 return Surface(wgpu_create_surface_from_wayland(surface, display)); 371 } 372 } 373 version (Windows) { 374 /// Create a new `Surface` from a Windows window handle. 375 static Surface fromWindowsHwnd(void* _hinstance, void* hwnd) { 376 return Surface(wgpu_create_surface_from_windows_hwnd(_hinstance, hwnd)); 377 } 378 } 379 version (linux) { 380 /// Create a new `Surface` from a Xlib window handle. 381 static Surface fromXlib(const(void)** display, c_ulong window) { 382 return Surface(wgpu_create_surface_from_xlib(display, window)); 383 } 384 } 385 version (D_Ddoc) { 386 /// Create a new `Surface` from an Android handle. 387 static Surface fromAndroid(void* androidNativeWindow) { 388 return Surface(wgpu_create_surface_from_android( androidNativeWindow)); 389 } 390 /// Create a new `Surface` from a Metal layer. 391 static Surface fromMetalLayer(void* layer) { 392 return Surface(wgpu_create_surface_from_metal_layer(layer)); 393 } 394 /// Create a new `Surface` from a Wayland window handle. 395 static Surface fromWayland(void* surface, void* display) { 396 return Surface(wgpu_create_surface_from_wayland(surface, display)); 397 } 398 /// Create a new `Surface` from a Windows window handle. 399 static Surface fromWindowsHwnd(void* _hinstance, void* hwnd) { 400 return Surface(wgpu_create_surface_from_windows_hwnd(_hinstance, hwnd)); 401 } 402 /// Create a new `Surface` from a Xlib window handle. 403 static Surface fromXlib(const(void)** display, c_ulong window) { 404 return Surface(wgpu_create_surface_from_xlib(display, window)); 405 } 406 } 407 } 408 409 /// A handle to a swap chain. 410 /// 411 /// A `SwapChain` represents the image or series of images that will be presented to a `Surface`. 412 /// A `SwapChain` may be created with `Device.createSwapChain`. 413 /// See_Also: <a href="https://docs.rs/wgpu/0.6.0/wgpu/struct.SwapChain.html">wgpu::SwapChain</a> 414 struct SwapChain { 415 /// Handle identifier. 416 WgpuId id; 417 /// Describes this `SwapChain.` 418 SwapChainDescriptor descriptor; 419 420 /// Returns the next texture to be presented by the swapchain for drawing. 421 SwapChainOutput getNextTexture() { 422 auto output = wgpu_swap_chain_get_next_texture(id); 423 auto status = output.status.to!int.to!SwapChainStatus; 424 auto successful = status == SwapChainStatus.Good || status == SwapChainStatus.Suboptimal; 425 TextureView* view = null; 426 if (successful) view = new TextureView(output.view_id); 427 428 return SwapChainOutput( 429 view, 430 successful, 431 status == SwapChainStatus.Suboptimal, 432 output.status.to!int > 1 ? output.status.to!int.to!SwapChainError : SwapChainError.None 433 ); 434 } 435 } 436 437 /// Result of an unsuccessful call to `SwapChain.getNextTexture`. 438 enum SwapChainError { 439 None = 0, 440 /// A timeout was encountered while trying to acquire the next frame. 441 Timeout = 2, 442 /// The underlying surface has changed, and therefore the swap chain must be updated. 443 Outdated = 3, 444 /// The swap chain has been lost and needs to be recreated. 445 Lost = 4, 446 /// There is no more memory left to allocate a new frame. 447 OutOfMemory = 5, 448 } 449 450 /// Result of a call to `SwapChain.getNextTexture`. 451 /// See_Also: <a href="https://docs.rs/wgpu/0.6.0/wgpu/struct.SwapChainFrame.html">wgpu::SwapChainFrame</a> 452 const struct SwapChainOutput { 453 /// The texture into which the next frame should be rendered. `null` if the call to `SwapChain.getNextTexture` was unsuccessful. 454 TextureView* view; 455 /// Whether a call to `SwapChain.getNextTexture` was successful. 456 bool success = false; 457 /// `true` if the acquired buffer can still be used for rendering, but should be recreated for maximum performance. 458 bool suboptimal = false; 459 /// Result of an unsuccessful call to `SwapChain.getNextTexture`. `SwapChainError.None` if the call was successful. 460 SwapChainError error = SwapChainError.None; 461 } 462 463 /// Result of a call to `Buffer.mapReadAsync` or `Buffer.mapWriteAsync`. 464 enum BufferMapAsyncStatus { 465 success = 0, 466 error = 1, 467 unknown = 2, 468 contextLost = 3 469 } 470 471 extern (C) private void wgpu_buffer_map_callback(WGPUBufferMapAsyncStatus status, ubyte* data) { 472 assert(data !is null); 473 auto buffer = cast(Buffer*) data; 474 assert(buffer.id); 475 476 buffer.status = status.to!int.to!BufferMapAsyncStatus; 477 } 478 479 /// A handle to a GPU-accessible buffer. 480 /// See_Also: <a href="https://docs.rs/wgpu/0.6.0/wgpu/struct.Buffer.html">wgpu::Buffer</a> 481 struct Buffer { 482 /// Handle identifier. 483 WgpuId id; 484 /// Describes this `Buffer`. 485 BufferDescriptor descriptor; 486 /// Result of a call to `Buffer.mapReadAsync` or `Buffer.mapWriteAsync`. 487 BufferMapAsyncStatus status = BufferMapAsyncStatus.unknown; 488 489 /// Release the given handle. 490 void destroy() { 491 if (id) wgpu_buffer_destroy(id); 492 id = 0; 493 } 494 495 /// Get the sliced `Buffer` data requested by either `Buffer.mapReadAsync` or `Buffer.mapWriteAsync`. 496 ubyte[] getMappedRange(BufferAddress start, BufferAddress size) { 497 assert(status == BufferMapAsyncStatus.success); 498 499 auto data = wgpu_buffer_get_mapped_range(id, start, size); 500 return data[0 .. size]; 501 } 502 503 /// Map the buffer for reading asynchronously. 504 /// See_Also: <a href="https://docs.rs/wgpu/0.6.0/wgpu/struct.BufferSlice.html#method.map_async">wgpu::BufferSlice::map_async</a> 505 void mapReadAsync(BufferAddress start, BufferAddress size) { 506 wgpu_buffer_map_read_async(id, start, size, &wgpu_buffer_map_callback, cast(ubyte*) &this); 507 } 508 509 /// Map the buffer for writing asynchronously. 510 /// See_Also: <a href="https://docs.rs/wgpu/0.6.0/wgpu/struct.BufferSlice.html#method.map_async">wgpu::BufferSlice::map_async</a> 511 void mapWriteAsync(BufferAddress start, BufferAddress size) { 512 wgpu_buffer_map_write_async(id, start, size, &wgpu_buffer_map_callback, cast(ubyte*) &this); 513 } 514 515 /// Flushes any pending write operations and unmaps the buffer from host memory. 516 void unmap() { 517 wgpu_buffer_unmap(id); 518 } 519 } 520 521 /// A handle to a texture on the GPU. 522 /// See_Also: <a href="https://docs.rs/wgpu/0.6.0/wgpu/struct.Texture.html">wgpu::Texture</a> 523 struct Texture { 524 /// Handle identifier. 525 WgpuId id; 526 /// Describes this `Texture`. 527 TextureDescriptor descriptor; 528 529 /// Release the given handle. 530 void destroy() { 531 if (id) wgpu_texture_destroy(id); 532 id = 0; 533 } 534 535 /// Creates a view of this texture. 536 TextureView createView(const TextureViewDescriptor descriptor) { 537 return TextureView(wgpu_texture_create_view(id, &descriptor)); 538 } 539 540 /// Creates a default view of this whole texture. 541 TextureView createDefaultView() { 542 return TextureView(wgpu_texture_create_view(id, null)); 543 } 544 } 545 546 /// A handle to a texture view. 547 /// 548 /// A `TextureView` object describes a texture and associated metadata needed by a `RenderPipeline` or `BindGroup`. 549 /// See_Also: <a href="https://docs.rs/wgpu/0.6.0/wgpu/struct.TextureView.html">wgpu::TextureView</a> 550 struct TextureView { 551 /// Handle identifier. 552 WgpuId id; 553 } 554 555 /// A handle to a sampler. 556 /// 557 /// A Sampler object defines how a pipeline will sample from a `TextureView`. Samplers define image 558 /// filters (including anisotropy) and address (wrapping) modes, among other things. 559 /// 560 /// See the documentation for `SamplerDescriptor` for more information. 561 /// See_Also: <a href="https://docs.rs/wgpu/0.6.0/wgpu/struct.Sampler.html">wgpu::Sampler</a> 562 struct Sampler { 563 /// Handle identifier. 564 WgpuId id; 565 /// Describes this `Sampler`. 566 SamplerDescriptor descriptor; 567 } 568 569 /// A Queue executes finished C`ommandBuffer` objects. 570 /// See_Also: <a href="https://docs.rs/wgpu/0.6.0/wgpu/struct.Queue.html">wgpu::Queue</a> 571 struct Queue { 572 /// Handle identifier. 573 WgpuId id; 574 575 /// Submits a finished command buffer for execution. 576 void submit(CommandBuffer commands) { 577 submit([commands]); 578 } 579 /// Submits a series of finished command buffers for execution. 580 void submit(CommandBuffer[] commandBuffers) { 581 import std.algorithm.iteration : map; 582 import std.array : array; 583 584 const commandBufferIds = commandBuffers.map!(c => c.id).array; 585 wgpu_queue_submit(id, commandBufferIds.ptr, commandBuffers.length); 586 } 587 } 588 589 /// An opaque handle to a command buffer on the GPU. 590 /// 591 /// A `CommandBuffer` represents a complete sequence of commands that may be submitted to a command queue with `Queue.submit`. 592 /// A `CommandBuffer` is obtained by recording a series of commands to a `CommandEncoder` and then calling `CommandEncoder.finish`. 593 /// See_Also: <a href="https://docs.rs/wgpu/0.6.0/wgpu/struct.CommandBuffer.html">wgpu::CommandBuffer</a> 594 struct CommandBuffer { 595 /// Handle identifier. 596 WgpuId id; 597 /// Describes a `CommandBuffer`. 598 const CommandBufferDescriptor descriptor; 599 } 600 601 /// A handle to a compiled shader module. 602 /// 603 /// A `ShaderModule` represents a compiled shader module on the GPU. It can be created by passing valid SPIR-V source code to `Device.createShaderModule`. 604 /// Shader modules are used to define programmable stages of a pipeline. 605 /// See_Also: <a href="https://docs.rs/wgpu/0.6.0/wgpu/struct.ShaderModule.html">wgpu::ShaderModule</a> 606 struct ShaderModule { 607 /// Handle identifier. 608 WgpuId id; 609 } 610 611 /// An object that encodes GPU operations. 612 /// 613 /// A `CommandEncoder` can record `RenderPass`es, `ComputePass`es, and transfer operations between driver-managed resources like `Buffer`s and `Texture`s. 614 /// 615 /// When finished recording, call `CommandEncoder.finish` to obtain a `CommandBuffer` which may be submitted for execution. 616 /// See_Also: <a href="https://docs.rs/wgpu/0.6.0/wgpu/struct.CommandEncoder.html">wgpu::CommandEncoder</a> 617 struct CommandEncoder { 618 /// Handle identifier. 619 WgpuId id; 620 /// Describes a `CommandEncoder`. 621 const CommandEncoderDescriptor descriptor; 622 623 /// Finishes recording and returns a `CommandBuffer` that can be submitted for execution. 624 CommandBuffer finish() { 625 auto commandBufferDescriptor = CommandBufferDescriptor(); 626 return CommandBuffer(wgpu_command_encoder_finish(id, &commandBufferDescriptor), commandBufferDescriptor); 627 } 628 629 /// Begins recording of a render pass. 630 /// 631 /// This function returns a `RenderPass` object which records a single render pass. 632 RenderPass beginRenderPass(const RenderPassDescriptor descriptor) { 633 return RenderPass(wgpu_command_encoder_begin_render_pass(id, &descriptor)); 634 } 635 636 /// Begins recording of a compute pass. 637 /// 638 /// This function returns a `ComputePass` object which records a single compute pass. 639 ComputePass beginComputePass(const ComputePassDescriptor descriptor) { 640 return ComputePass(wgpu_command_encoder_begin_compute_pass(id, &descriptor)); 641 } 642 643 /// Copy data from a texture to a buffer. 644 void copyTextureToBuffer(const TextureCopyView source, const BufferCopyView destination, const Extent3d copySize) { 645 wgpu_command_encoder_copy_texture_to_buffer(id, &source, &destination, ©Size); 646 } 647 } 648 649 /// An opaque handle to a binding group. 650 /// 651 /// A `BindGroup` represents the set of resources bound to the bindings described by a `BindGroupLayout`. 652 /// It can be created with `Device.createBindGroup`. A `BindGroup` can be bound to a particular `RenderPass` 653 /// with `RenderPass.setBindGroup`, or to a `ComputePass` with `ComputePass.setBindGroup`. 654 /// See_Also: <a href="https://docs.rs/wgpu/0.6.0/wgpu/struct.BindGroup.html">wgpu::BindGroup</a> 655 struct BindGroup { 656 /// Handle identifier. 657 WgpuId id; 658 /// Describes this `BindGroup`. 659 BindGroupDescriptor descriptor; 660 } 661 662 /// An opaque handle to a binding group layout. 663 /// 664 /// A `BindGroupLayout` is a handle to the GPU-side layout of a binding group. It can be used to create 665 /// a `BindGroupDescriptor` object, which in turn can be used to create a `BindGroup` object with 666 /// `Device.createBindGroup`. A series of `BindGroupLayout`s can also be used to create a 667 /// `PipelineLayoutDescriptor`, which can be used to create a `PipelineLayout`. 668 /// See_Also: <a href="https://docs.rs/wgpu/0.6.0/wgpu/struct.BindGroupLayout.html">wgpu::BindGroupLayout</a> 669 struct BindGroupLayout { 670 /// Handle identifier. 671 WgpuId id; 672 /// Describes this `BindGroupLayout`. 673 BindGroupLayoutDescriptor descriptor; 674 } 675 676 /// An opaque handle to a pipeline layout. 677 /// 678 /// A `PipelineLayout` object describes the available binding groups of a pipeline. 679 /// See_Also: <a href="https://docs.rs/wgpu/0.6.0/wgpu/struct.PipelineLayout.html">wgpu::PipelineLayout</a> 680 struct PipelineLayout { 681 /// Handle identifier. 682 WgpuId id; 683 /// Describes this `PipelineLayout`. 684 PipelineLayoutDescriptor descriptor; 685 } 686 687 /// A handle to a rendering (graphics) pipeline. 688 /// 689 /// A `RenderPipeline` object represents a graphics pipeline and its stages, bindings, vertex buffers and targets. 690 /// A `RenderPipeline` may be created with `Device.createRenderPipeline`. 691 /// See_Also: <a href="https://docs.rs/wgpu/0.6.0/wgpu/struct.RenderPipeline.html">wgpu::RenderPipeline</a> 692 struct RenderPipeline { 693 /// Handle identifier. 694 WgpuId id; 695 /// Describes this `RenderPipeline`. 696 RenderPipelineDescriptor descriptor; 697 698 /// Release the given handle. 699 void destroy() { 700 if (id) wgpu_render_pipeline_destroy(id); 701 id = 0; 702 } 703 } 704 705 /// An in-progress recording of a render pass. 706 /// See_Also: <a href="https://docs.rs/wgpu/0.6.0/wgpu/struct.RenderPass.html">wgpu::RenderPass</a> 707 struct RenderPass { 708 import std.typecons : Tuple; 709 710 package WGPURenderPass* instance; 711 /// Describes this `RenderPass`. 712 RenderPassDescriptor descriptor; 713 714 /// Sets the active bind group for a given bind group index. 715 void setBindGroup(const uint index, const BindGroup bindGroup, BufferAddress[] offsets) { 716 import std.algorithm.iteration : map; 717 import std.array : array; 718 719 auto offsetsAsUints = offsets.map!(offset => offset.to!(const uint)).array; 720 wgpu_render_pass_set_bind_group(instance, index, bindGroup.id, offsetsAsUints.ptr, offsets.length); 721 } 722 723 /// Sets the active render pipeline. 724 /// 725 /// Subsequent draw calls will exhibit the behavior defined by `pipeline`. 726 void setPipeline(const RenderPipeline pipeline) { 727 wgpu_render_pass_set_pipeline(instance, pipeline.id); 728 } 729 730 void setBlendColor(const Color color) { 731 wgpu_render_pass_set_blend_color(instance, &color); 732 } 733 734 /// Sets the active index buffer. 735 /// 736 /// Subsequent calls to `drawIndexed` on this `RenderPass` will use buffer as the source index buffer. 737 void setIndexBuffer(const Buffer buffer, const BufferAddress offset) { 738 wgpu_render_pass_set_index_buffer(instance, buffer.id, offset, buffer.descriptor.size); 739 } 740 741 /// Sets the active vertex buffers, starting from `startSlot`. 742 /// 743 /// Each element of `bufferPairs` describes a vertex buffer and an offset in bytes into that buffer. 744 /// The offset must be aligned to a multiple of 4 bytes. 745 void setVertexBuffers(uint startSlot, Tuple!(Buffer, BufferAddress)[] bufferPairs) { 746 foreach (bufferPair; bufferPairs) { 747 auto buffer = bufferPair[0]; 748 auto bufferAddress = bufferPair[1]; 749 wgpu_render_pass_set_vertex_buffer(instance, startSlot, buffer.id, bufferAddress, buffer.descriptor.size); 750 } 751 } 752 753 /// Sets the scissor region. 754 /// 755 /// Subsequent draw calls will discard any fragments that fall outside this region. 756 void setScissorRect(uint x, uint y, uint w, uint h) { 757 wgpu_render_pass_set_scissor_rect(instance, x, y, w, h); 758 } 759 760 /// Sets the viewport region. 761 /// 762 /// Subsequent draw calls will draw any fragments in this region. 763 void setViewport(float x, float y, float w, float h, float minDepth, float maxDepth) { 764 wgpu_render_pass_set_viewport(instance, x, y, w, h, minDepth, maxDepth); 765 } 766 767 /// Sets the stencil reference. 768 /// 769 /// Subsequent stencil tests will test against this value. 770 void setStencilReference(uint reference) { 771 wgpu_render_pass_set_stencil_reference(instance, reference); 772 } 773 774 /// Draws primitives from the active vertex buffer(s). 775 /// 776 /// The active vertex buffers can be set with `RenderPass.setVertexBuffers`. 777 void draw(uint[] vertices, uint[] instances) { 778 assert(vertices.length); 779 assert(instances.length); 780 } 781 782 /// Draws indexed primitives using the active index buffer and the active vertex buffers. 783 /// 784 /// The active index buffer can be set with `RenderPass.setIndexBuffer`, while the active vertex 785 /// buffers can be set with `RenderPass.setVertexBuffers`. 786 void drawIndexed(uint[] indices, int baseVertex, uint[] instances) { 787 assert(indices.length); 788 assert(baseVertex >= 0); 789 assert(instances.length); 790 } 791 } 792 793 /// A handle to a compute pipeline. 794 /// See_Also: <a href="https://docs.rs/wgpu/0.6.0/wgpu/struct.ComputePipeline.html">wgpu::ComputePipeline</a> 795 struct ComputePipeline { 796 /// Handle identifier. 797 WgpuId id; 798 /// Describes this `ComputePipeline`. 799 ComputePipelineDescriptor descriptor; 800 801 /// Release the given handle. 802 void destroy() { 803 if (id) wgpu_compute_pipeline_destroy(id); 804 id = 0; 805 } 806 } 807 808 /// An in-progress recording of a compute pass. 809 /// See_Also: <a href="https://docs.rs/wgpu/0.6.0/wgpu/struct.ComputePass.html">wgpu::ComputePass</a> 810 struct ComputePass { 811 package WGPUComputePass* instance; 812 /// Describes this `ComputePass`. 813 ComputePassDescriptor descriptor; 814 815 /// Sets the active bind group for a given bind group index. 816 void setBindGroup(const uint index, const BindGroup bindGroup, BufferAddress[] offsets) { 817 import std.algorithm.iteration : map; 818 import std.array : array; 819 820 auto offsetsAsUints = offsets.map!(offset => offset.to!(const uint)).array; 821 wgpu_compute_pass_set_bind_group(instance, index, bindGroup.id, offsetsAsUints.ptr, offsets.length); 822 } 823 824 /// Sets the active compute pipeline. 825 void setPipeline(const ComputePipeline pipeline) { 826 wgpu_compute_pass_set_pipeline(instance, pipeline.id); 827 } 828 829 ///Dispatches compute work operations. 830 /// 831 /// x, y and z denote the number of work groups to dispatch in each dimension. 832 void dispatch(const uint x, const uint y, const uint z) { 833 wgpu_compute_pass_dispatch(instance, x, y, z); 834 } 835 }