-
-
Notifications
You must be signed in to change notification settings - Fork 568
/
Copy pathreshade_api_device.hpp
1295 lines (1223 loc) · 80.8 KB
/
reshade_api_device.hpp
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
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
* Copyright (C) 2021 Patrick Mours
* SPDX-License-Identifier: BSD-3-Clause OR MIT
*/
#pragma once
#include "reshade_api_pipeline.hpp"
namespace reshade { namespace api
{
/// <summary>
/// Underlying graphics API a device is using.
/// </summary>
/// <seealso cref="device::get_api"/>
enum class device_api
{
/// <summary>Direct3D 9</summary>
/// <remarks>https://docs.microsoft.com/windows/win32/direct3d9</remarks>
d3d9 = 0x9000,
/// <summary>Direct3D 10</summary>
/// <remarks>https://docs.microsoft.com/windows/win32/direct3d10</remarks>
d3d10 = 0xa000,
/// <summary>Direct3D 11</summary>
/// <remarks>https://docs.microsoft.com/windows/win32/direct3d11</remarks>
d3d11 = 0xb000,
/// <summary>Direct3D 12</summary>
/// <remarks>https://docs.microsoft.com/windows/win32/direct3d12</remarks>
d3d12 = 0xc000,
/// <summary>OpenGL</summary>
/// <remarks>https://www.khronos.org/opengl/</remarks>
opengl = 0x10000,
/// <summary>Vulkan</summary>
/// <remarks>https://www.khronos.org/vulkan/</remarks>
vulkan = 0x20000
};
/// <summary>
/// Optional capabilities a device may support, depending on the underlying graphics API and hardware.
/// </summary>
/// <seealso cref="device::check_capability"/>
enum class device_caps
{
/// <summary>
/// Specifies whether compute shaders are supported.
/// If this feature is not present, the <see cref="pipeline_stage::compute_shader"/> stage and <see cref="command_list::dispatch"/> must not be used.
/// </summary>
compute_shader = 1,
/// <summary>
/// Specifies whether geometry shaders are supported.
/// If this feature is not present, the <see cref="pipeline_stage::geometry_shader"/> stage must not be used.
/// </summary>
geometry_shader,
/// <summary>
/// Specifies whether hull and domain (tessellation) shaders are supported.
/// If this feature is not present, the <see cref="pipeline_stage::hull_shader"/> and <see cref="pipeline_stage::domain_shader"/> stages must not be used.
/// </summary>
hull_and_domain_shader,
/// <summary>
/// Specifies whether logic operations are available in the blend state.
/// If this feature is not present, <see cref="blend_desc::logic_op_enable"/> and <see cref="blend_desc::logic_op"/> are ignored.
/// </summary>
logic_op,
/// <summary>
/// Specifies whether blend operations which take two sources are supported.
/// If this feature is not present, <see cref="blend_factor::source1_color"/>, <see cref="blend_factor::one_minus_source1_color"/>, <see cref="blend_factor::source1_alpha"/> and <see cref="blend_factor::one_minus_source1_alpha"/> must not be used.
/// </summary>
dual_source_blend,
/// <summary>
/// Specifies whether blend state is controlled independently per render target.
/// If this feature is not present, the blend state settings for all render targets must be identical.
/// </summary>
independent_blend,
/// <summary>
/// Specifies whether point and wireframe fill modes are supported.
/// If this feature is not present, <see cref="fill_mode::point"/> and <see cref="fill_mode::wireframe"/> must not be used.
/// </summary>
fill_mode_non_solid,
/// <summary>
/// Specifies whether conservative rasterization is supported.
/// If this feature is not present, <see cref="rasterizer_desc::conservative_rasterization"/> must be 0.
/// </summary>
conservative_rasterization,
/// <summary>
/// Specifies whether binding individual render target and depth-stencil resource views is supported.
/// If this feature is not present, <see cref="command_list::bind_render_targets_and_depth_stencil"/> must not be used (only render passes).
/// </summary>
bind_render_targets_and_depth_stencil,
/// <summary>
/// Specifies whther more than one viewport is supported.
/// If this feature is not present, the "first" and "count" parameters to <see cref="command_list::bind_viewports"/> and <see cref="command_list::bind_scissor_rects"/> must be 0 and 1.
/// </summary>
multi_viewport,
/// <summary>
/// Specifies whether partial push constant updates are supported.
/// If this feature is not present, the "first" parameter to <see cref="command_list::push_constants"/> must be 0 and "count" must cover the entire constant range.
/// </summary>
partial_push_constant_updates,
/// <summary>
/// Specifies whether partial push descriptor updates are supported.
/// If this feature is not present, the "first" parameter to <see cref="command_list::push_descriptors"/> must be 0 and "count" must cover the entire descriptor range.
/// </summary>
partial_push_descriptor_updates,
/// <summary>
/// Specifies whether instancing is supported.
/// If this feature is not present, the "instance_count" and "first_instance" parameters to <see cref="command_list::draw"/> and <see cref="command_list::draw_indexed"/> must be 1 and 0.
/// </summary>
draw_instanced,
/// <summary>
/// Specifies whether indirect draw or dispatch calls are supported.
/// If this feature is not present, <see cref="command_list::draw_or_dispatch_indirect"/> must not be used.
/// </summary>
draw_or_dispatch_indirect,
/// <summary>
/// Specifies whether copying between buffers is supported.
/// If this feature is not present, <see cref="command_list::copy_buffer_region"/> must not be used.
/// </summary>
copy_buffer_region,
/// <summary>
/// Specifies whether copying between buffers and textures is supported.
/// If this feature is not present, <see cref="command_list::copy_buffer_to_texture"/> and <see cref="command_list::copy_texture_to_buffer"/> must not be used.
/// </summary>
copy_buffer_to_texture,
/// <summary>
/// Specifies whether blitting between resources is supported.
/// If this feature is not present, the "source_box" and "dest_box" parameters to <see cref="command_list::copy_texture_region"/> must have the same dimensions.
/// </summary>
blit,
/// <summary>
/// Specifies whether resolving a region of a resource rather than its entirety is supported.
/// If this feature is not present, the "source_box", "dest_x", "dest_y" and "dest_z" parameters to <see cref="command_list::resolve_texture_region"/> must be <see langword="nullptr"/> and zero.
/// </summary>
resolve_region,
/// <summary>
/// Specifies whether copying query results to a buffer is supported.
/// If this feature is not present, <see cref="command_list::copy_query_heap_results"/> must not be used.
/// </summary>
copy_query_heap_results,
/// <summary>
/// Specifies whether comparison sampling is supported.
/// If this feature is not present, <see cref="sampler_desc::compare_op"/> is ignored and the compare filter types have no effect.
/// </summary>
sampler_compare,
/// <summary>
/// Specifies whether anisotropic filtering is supported.
/// If this feature is not present, <see cref="filter_mode::anisotropic"/> must not be used.
/// </summary>
sampler_anisotropic,
/// <summary>
/// Specifies whether combined sampler and resource view descriptors are supported.
/// If this feature is not present, <see cref="descriptor_type::sampler_with_resource_view"/> must not be used.
/// </summary>
sampler_with_resource_view,
/// <summary>
/// Specifies whether resource sharing is supported.
/// If this feature is not present, <see cref="resource_flags::shared"/> must not be used.
/// </summary>
shared_resource,
/// <summary>
/// Specifies whether resource sharing with NT handles is supported.
/// If this feature is not present, <see cref="resource_flags::shared_nt_handle"/> must not be used.
/// </summary>
shared_resource_nt_handle,
/// <summary>
/// Specifies whether resolving depth-stencil resources is supported.
/// If this feature is not present, <see cref="command_list::resolve_texture_region"/> must not be used with depth-stencil resources.
/// </summary>
resolve_depth_stencil,
/// <summary>
/// Specifies whether fence sharing is supported.
/// If this feature is not present, <see cref="fence_flags::shared"/> must not be used.
/// </summary>
shared_fence,
/// <summary>
/// Specifies whether fence sharing with NT handles is supported.
/// If this feature is not present, <see cref="fence_flags::shared_nt_handle"/> must not be used.
/// </summary>
shared_fence_nt_handle,
/// <summary>
/// Specifies whether amplification and mesh shaders are supported.
/// If this feature is not present, the <see cref="pipeline_stage::amplification_shader"/> and <see cref="pipeline_stage::mesh_shader"/> stages and <see cref="command_list::dispatch_mesh"/> must not be used.
/// </summary>
amplification_and_mesh_shader,
/// <summary>
/// Specifies whether ray tracing is supported.
/// If this feature is not present, <see cref="resource_view_type::acceleration_structure"/>, <see cref="command_list::dispatch_rays"/>, <see cref="command_list::copy_acceleration_structure"/>, <see cref="command_list::build_acceleration_structure"/> and <see cref="command_list::query_acceleration_structures"/> must not be used.
/// </summary>
ray_tracing,
};
/// <summary>
/// Properties that may be queried from a device.
/// </summary>
/// <seealso cref="device::get_property"/>
enum class device_properties
{
/// <summary>
/// Version of the underlying graphics API the device is using.
/// Data is a 32-bit unsigned integer value.
/// </summary>
api_version = 1,
/// <summary>
/// Version of the graphics driver that is being used.
/// Data is a 32-bit unsigned integer value.
/// </summary>
driver_version,
/// <summary>
/// PCI vendor ID of the hardware associated with the logical render device.
/// Data is a 32-bit unsigned integer value.
/// </summary>
vendor_id,
/// <summary>
/// PCI device ID of the hardware associated with the logical render device.
/// Data is a 32-bit unsigned integer value.
/// </summary>
device_id,
/// <summary>
/// Description text of the hardware associated with the logical render device.
/// Data is an array of 256 byte-sized characters representing a null-terminated string.
/// </summary>
description,
/// <summary>
/// Size of a <see cref="shader_group"/> handle as written by <see cref="device::get_pipeline_shader_group_handles"/>.
/// Data is a 32-bit unsigned integer value.
/// </summary>
shader_group_handle_size,
/// <summary>
/// Required alignment of the base <see cref="shader_group"/> handle in the buffers passed to <see cref="command_list::dispatch_rays"/>.
/// Data is a 32-bit unsigned integer value.
/// </summary>
shader_group_alignment,
/// <summary>
/// Required alignment of each <see cref="shader_group"/> handle in the buffers passed to <see cref="command_list::dispatch_rays"/>.
/// Data is a 32-bit unsigned integer value.
/// </summary>
shader_group_handle_alignment,
};
/// <summary>
/// The base class for objects provided by the ReShade API.
/// <para>This lets you store and retrieve custom data with objects, e.g. to be able to communicate persistent information between event callbacks.</para>
/// </summary>
struct __declspec(novtable) api_object
{
/// <summary>
/// Gets the underlying native object for this API object.
/// </summary>
/// <remarks>
/// For <see cref="device"/> this will be be a pointer to a 'IDirect3DDevice9', 'ID3D10Device', 'ID3D11Device' or 'ID3D12Device' object or a 'HGLRC' or 'VkDevice' handle.<br/>
/// For <see cref="command_list"/> this will be a pointer to a 'ID3D11DeviceContext' (when recording), 'ID3D11CommandList' (when executing) or 'ID3D12GraphicsCommandList' object or a 'VkCommandBuffer' handle.<br/>
/// For <see cref="command_queue"/> this will be a pointer to a 'ID3D11DeviceContext' or 'ID3D12CommandQueue' object or a 'VkQueue' handle.<br/>
/// For <see cref="swapchain"/> this will be a pointer to a 'IDirect3DSwapChain9' or 'IDXGISwapChain' object or a 'HDC' or 'VkSwapchainKHR' handle.
/// </remarks>
virtual uint64_t get_native() const = 0;
/// <summary>
/// Gets a user-defined 64-bit value from the object that was previously set via <see cref="set_private_data"/>, or zero if none associated with the specified <paramref name="guid"/> exists.
/// </summary>
virtual void get_private_data(const uint8_t guid[16], uint64_t *data) const = 0;
/// <summary>
/// Stores a user-defined 64-bit value in the object and associates it with the specified <paramref name="guid"/>.
/// </summary>
/// <remarks>
/// This function may NOT be called concurrently from multiple threads!
/// </remarks>
virtual void set_private_data(const uint8_t guid[16], const uint64_t data) = 0;
/// <summary>
/// Gets a reference to user-defined data from the object that was previously allocated via <see cref="create_private_data"/>.
/// </summary>
template <typename T>
T &get_private_data() const
{
uint64_t res;
get_private_data(reinterpret_cast<const uint8_t *>(&__uuidof(T)), &res);
return *reinterpret_cast<T *>(static_cast<uintptr_t>(res));
}
/// <summary>
/// Allocates user-defined data and stores it in the object.
/// </summary>
template <typename T, typename... Args>
T &create_private_data(Args &&... args)
{
uint64_t res = reinterpret_cast<uintptr_t>(new T(static_cast<Args &&>(args)...));
set_private_data(reinterpret_cast<const uint8_t *>(&__uuidof(T)), res);
return *reinterpret_cast<T *>(static_cast<uintptr_t>(res));
}
/// <summary>
/// Frees user-defined data that was previously allocated via <see cref="create_private_data"/>.
/// </summary>
template <typename T>
void destroy_private_data()
{
uint64_t res;
get_private_data(reinterpret_cast<const uint8_t *>(&__uuidof(T)), &res);
delete reinterpret_cast<T *>(static_cast<uintptr_t>(res));
set_private_data(reinterpret_cast<const uint8_t *>(&__uuidof(T)), 0);
}
};
/// <summary>
/// A logical render device, used for resource creation and global operations.
/// <para>Functionally equivalent to a 'IDirect3DDevice9', 'ID3D10Device', 'ID3D11Device', 'ID3D12Device', 'HGLRC' or 'VkDevice'.</para>
/// </summary>
/// <remarks>
/// This class is safe to use concurrently from multiple threads in D3D10+ and Vulkan.
/// </remarks>
struct __declspec(novtable) device : public api_object
{
/// <summary>
/// Gets the underlying graphics API used by this device.
/// </summary>
virtual device_api get_api() const = 0;
/// <summary>
/// Checks whether the device supports the specified <paramref name="capability"/>.
/// </summary>
virtual bool check_capability(device_caps capability) const = 0;
/// <summary>
/// Checks whether the specified texture <paramref name="format"/> supports the specified <paramref name="usage"/>.
/// </summary>
virtual bool check_format_support(format format, resource_usage usage) const = 0;
/// <summary>
/// Creates a new sampler state object.
/// </summary>
/// <param name="desc">Description of the sampler to create.</param>
/// <param name="out_sampler">Pointer to a variable that is set to the handle of the created sampler.</param>
/// <returns><see langword="true"/> if the sampler was successfully created, <see langword="false"/> otherwise (in this case <paramref name="out_sampler"/> is set to zero).</returns>
virtual bool create_sampler(const sampler_desc &desc, sampler *out_sampler) = 0;
/// <summary>
/// Instantly destroys a sampler that was previously created via <see cref="create_sampler"/>.
/// </summary>
virtual void destroy_sampler(sampler sampler) = 0;
/// <summary>
/// Allocates and creates a new resource.
/// </summary>
/// <param name="desc">Description of the resource to create.</param>
/// <param name="initial_data">Optional data to upload to the resource after creation. This should point to an array of <see cref="mapped_subresource"/>, one for each subresource (mipmap levels and array layers). Can be <see langword="nullptr"/> to indicate no initial data to upload.</param>
/// <param name="initial_state">Initial state of the resource after creation. This can later be changed via <see cref="command_list::barrier"/>. It should also be part of the <see cref="resource_desc::usage"/> flags of the description.</param>
/// <param name="out_resource">Pointer to a variable that is set to the handle of the created resource.</param>
/// <param name="shared_handle">Optional pointer to a variable of type <c>HANDLE</c> used when <see cref="resource_desc::flags"/> contains <see cref="resource_flags::shared"/>. When that variable is a <see langword="nullptr"/>, it is set to the exported shared handle of the created resource. When that variable is a valid handle, the resource is imported from that shared handle.</param>
/// <returns><see langword="true"/> if the resource was successfully created, <see langword="false"/> otherwise (in this case <paramref name="out_resource"/> is set to zero).</returns>
virtual bool create_resource(const resource_desc &desc, const subresource_data *initial_data, resource_usage initial_state, resource *out_resource, void **shared_handle = nullptr) = 0;
/// <summary>
/// Instantly destroys a resource that was previously created via <see cref="create_resource"/> and frees its memory.
/// Make sure the resource is no longer in use on the GPU (via any command list that may reference it and is still being executed) before doing this (e.g. with <see cref="command_queue::wait_idle"/>) and never try to destroy resources created by the application!
/// </summary>
virtual void destroy_resource(resource resource) = 0;
/// <summary>
/// Gets the description of the specified resource.
/// </summary>
virtual resource_desc get_resource_desc(resource resource) const = 0;
/// <summary>
/// Creates a new resource view for the specified <paramref name="resource"/>.
/// </summary>
/// <param name="resource">Resource to create the view to.</param>
/// <param name="usage_type">Usage type of the resource view to create. Set to <see cref="resource_usage::shader_resource"/> to create a shader resource view, <see cref="resource_usage::depth_stencil"/> for a depth-stencil view, <see cref="resource_usage::render_target"/> for a render target etc.</param>
/// <param name="desc">Description of the resource view to create.</param>
/// <param name="out_view">Pointer to a variable that is set to the handle of the created resource view.</param>
/// <returns><see langword="true"/> if the resource view was successfully created, <see langword="false"/> otherwise (in this case <paramref name="out_view"/> is set to zero).</returns>
virtual bool create_resource_view(resource resource, resource_usage usage_type, const resource_view_desc &desc, resource_view *out_view) = 0;
/// <summary>
/// Instantly destroys a resource view that was previously created via <see cref="create_resource_view"/>.
/// </summary>
virtual void destroy_resource_view(resource_view view) = 0;
/// <summary>
/// Gets the handle to the underlying resource the specified resource <paramref name="view"/> was created for.
/// </summary>
/// <remarks>
/// Resource views may be created without a resource in D3D12, which is used to initialize a null descriptor (reading zeroes, writes are discarded). This may therefore return zero for such views.
/// </remarks>
virtual resource get_resource_from_view(resource_view view) const = 0;
/// <summary>
/// Gets the description of the specified resource view.
/// </summary>
virtual resource_view_desc get_resource_view_desc(resource_view view) const = 0;
/// <summary>
/// Maps the memory of a buffer resource into application address space.
/// </summary>
/// <param name="resource">Buffer resource to map to host memory.</param>
/// <param name="offset">Offset (in bytes) into the buffer resource to start mapping.</param>
/// <param name="size">Number of bytes to map. Set to -1 (UINT64_MAX) to indicate that the entire buffer should be mapped.</param>
/// <param name="access">Hint on how the returned data pointer will be accessed.</param>
/// <param name="out_data">Pointer to a variable that is set to a pointer to the memory of the buffer resource.</param>
/// <returns><see langword="true"/> if the memory of the buffer resource was successfully mapped, <see langword="false"/> otherwise (in this case <paramref name="out_data"/> is set to <see langword="nullptr"/>).</returns>
virtual bool map_buffer_region(resource resource, uint64_t offset, uint64_t size, map_access access, void **out_data) = 0;
/// <summary>
/// Unmaps a previously mapped buffer resource.
/// </summary>
/// <param name="resource">Buffer resource to unmap from host memory.</param>
virtual void unmap_buffer_region(resource resource) = 0;
/// <summary>
/// Maps the memory of a texture resource into application address space.
/// </summary>
/// <param name="resource">Texture resource to map to host memory.</param>
/// <param name="subresource">Index of the subresource to map (<c>level + (layer * levels)</c>).</param>
/// <param name="box">Optional 3D box (or <see langword="nullptr"/> to reference the entire subresource) that defines the region in the <paramref name="resource"/> to map.</param>
/// <param name="access">Hint on how the returned data pointer will be accessed.</param>
/// <param name="out_data">Pointer to a variable that is set to a pointer to the memory of the texture resource and optionally the row and slice pitch of that data (depending on the resource type).</param>
/// <returns><see langword="true"/> if the memory of the texture resource was successfully mapped, <see langword="false"/> otherwise (in this case <paramref name="out_data"/> is set to <see langword="nullptr"/>).</returns>
virtual bool map_texture_region(resource resource, uint32_t subresource, const subresource_box *box, map_access access, subresource_data *out_data) = 0;
/// <summary>
/// Unmaps a previously mapped texture resource.
/// </summary>
/// <param name="resource">Texture resource to unmap from host memory.</param>
/// <param name="subresource">Index of the subresource to unmap (<c>level + (layer * levels)</c>).</param>
virtual void unmap_texture_region(resource resource, uint32_t subresource) = 0;
/// <summary>
/// Uploads data to a buffer resource.
/// </summary>
/// <param name="data">Pointer to the data to upload.</param>
/// <param name="resource">Buffer resource to upload to.</param>
/// <param name="offset">Offset (in bytes) into the buffer resource to start uploading to.</param>
/// <param name="size">Number of bytes to upload.</param>
virtual void update_buffer_region(const void *data, resource resource, uint64_t offset, uint64_t size) = 0;
/// <summary>
/// Uploads data to a texture resource.
/// </summary>
/// <param name="data">Pointer to the data to upload.</param>
/// <param name="resource">Texture resource to upload to.</param>
/// <param name="subresource">Index of the subresource to upload to (<c>level + (layer * levels)</c>).</param>
/// <param name="box">Optional 3D box (or <see langword="nullptr"/> to reference the entire subresource) that defines the region in the <paramref name="resource"/> to upload to.</param>
virtual void update_texture_region(const subresource_data &data, resource resource, uint32_t subresource, const subresource_box *box = nullptr) = 0;
/// <summary>
/// Creates a new pipeline state object.
/// </summary>
/// <param name="layout">Pipeline layout to use.</param>
/// <param name="subobject_count">Number of sub-objects.</param>
/// <param name="subobjects">Pointer to the first element of an array of sub-objects that describe this pipeline.</param>
/// <param name="out_pipeline">Pointer to a variable that is set to the handle of the created pipeline state object.</param>
/// <returns><see langword="true"/> if the pipeline state object was successfully created, <see langword="false"/> otherwise (in this case <paramref name="out_pipeline"/> is set to zero).</returns>
virtual bool create_pipeline(pipeline_layout layout, uint32_t subobject_count, const pipeline_subobject *subobjects, pipeline *out_pipeline) = 0;
/// <summary>
/// Instantly destroys a pipeline state object that was previously created via <see cref="create_pipeline"/>.
/// </summary>
virtual void destroy_pipeline(pipeline pipeline) = 0;
/// <summary>
/// Creates a new pipeline layout.
/// </summary>
/// <param name="param_count">Number of layout parameters.</param>
/// <param name="params">Pointer to the first element of an array of layout parameters that describe this pipeline layout.</param>
/// <param name="out_layout">Pointer to a variable that is set to the handle of the created pipeline layout.</param>
/// <returns><see langword="true"/> if the pipeline layout was successfully created, <see langword="false"/> otherwise (in this case <paramref name="out_layout"/> is set to zero).</returns>
virtual bool create_pipeline_layout(uint32_t param_count, const pipeline_layout_param *params, pipeline_layout *out_layout) = 0;
/// <summary>
/// Instantly destroys a pipeline layout that was previously created via <see cref="create_pipeline_layout"/>.
/// </summary>
virtual void destroy_pipeline_layout(pipeline_layout layout) = 0;
/// <summary>
/// Allocates a descriptor table from an internal descriptor heap.
/// </summary>
/// <param name="layout">Pipeline layout that contains a parameter that describes the descriptor table.</param>
/// <param name="param">Index of the pipeline layout parameter that describes the descriptor table.</param>
/// <param name="out_table">Pointer to a a variable that is set to the handles of the created descriptor table.</param>
/// <returns><see langword="true"/> if the descriptor table was successfully allocated, <see langword="false"/> otherwise (in this case <paramref name="out_table"/> is set to zeroe).</returns>
bool allocate_descriptor_table(pipeline_layout layout, uint32_t param, descriptor_table *out_table) { return allocate_descriptor_tables(1, layout, param, out_table); }
/// <summary>
/// Allocates one or more descriptor tables from an internal descriptor heap.
/// </summary>
/// <param name="count">Number of descriptor tables to allocate.</param>
/// <param name="layout">Pipeline layout that contains a parameter that describes the descriptor tables.</param>
/// <param name="param">Index of the pipeline layout parameter that describes the descriptor tables.</param>
/// <param name="out_tables">Pointer to the first element of an array of handles with at least <paramref name="count"/> elements that is filled with the handles of the created descriptor tables.</param>
/// <returns><see langword="true"/> if the descriptor tables were successfully allocated, <see langword="false"/> otherwise (in this case <paramref name="out_tables"/> is filled with zeroes).</returns>
virtual bool allocate_descriptor_tables(uint32_t count, pipeline_layout layout, uint32_t param, descriptor_table *out_tables) = 0;
/// <summary>
/// Frees a descriptor table that was previously allocated via <see cref="allocate_descriptor_table"/>.
/// </summary>
void free_descriptor_table(descriptor_table table) { free_descriptor_tables(1, &table); }
/// <summary>
/// Frees one or more descriptor tables that were previously allocated via <see cref="allocate_descriptor_tables"/>.
/// </summary>
virtual void free_descriptor_tables(uint32_t count, const descriptor_table *tables) = 0;
/// <summary>
/// Gets the offset (in descriptors) of the specified binding in the underlying descriptor heap of a descriptor table.
/// </summary>
/// <param name="table">Descriptor table to get the offset from.</param>
/// <param name="binding">Binding in the descriptor table to get the offset from.</param>
/// <param name="array_offset">Array index in the specified <paramref name="binding"/>.</param>
/// <param name="out_heap">Pointer to a variable that is set to the handle of the underlying descriptor heap the <paramref name="table"/> was allocated from.</param>
/// <param name="out_offset">Pointer to a variable that is set to the offset of the binding in the underlying descriptor heap.</param>
virtual void get_descriptor_heap_offset(descriptor_table table, uint32_t binding, uint32_t array_offset, descriptor_heap *out_heap, uint32_t *out_offset) const = 0;
/// <summary>
/// Copies the contents of a descriptor table to another descriptor table.
/// </summary>
/// <param name="copy">Descriptor table copy to process.</param>
void copy_descriptors(const descriptor_table_copy ©) { copy_descriptor_tables(1, ©); }
/// <summary>
/// Copies the contents between multiple descriptor tables.
/// </summary>
/// <param name="count">Number of <paramref name="copies"/> to process.</param>
/// <param name="copies">Pointer to the first element of an array of descriptor table copies to process.</param>
virtual void copy_descriptor_tables(uint32_t count, const descriptor_table_copy *copies) = 0;
/// <summary>
/// Updates the contents of a descriptor table with the specified descriptors.
/// </summary>
/// <param name="update">Descriptor table update to process.</param>
void update_descriptors(const descriptor_table_update &update) { update_descriptor_tables(1, &update); }
/// <summary>
/// Updates the contents of multiple descriptor tables with the specified descriptors.
/// </summary>
/// <param name="count">Number of <paramref name="updates"/> to process.</param>
/// <param name="updates">Pointer to the first element of an array of descriptor table updates to process.</param>
virtual void update_descriptor_tables(uint32_t count, const descriptor_table_update *updates) = 0;
/// <summary>
/// Creates a new query heap.
/// </summary>
/// <param name="type">Type of queries that will be used with this query heap.</param>
/// <param name="count">Number of queries to allocate in the query heap.</param>
/// <param name="out_heap">Pointer to a variable that is set to the handle of the created query heap.</param>
/// <returns><see langword="true"/> if the query heap was successfully created, <see langword="false"/> otherwise (in this case <paramref name="out_heap"/> is set to zero).</returns>
virtual bool create_query_heap(query_type type, uint32_t count, query_heap *out_heap) = 0;
/// <summary>
/// Instantly destroys a query heap that was previously created via <see cref="create_query_heap"/>.
/// </summary>
virtual void destroy_query_heap(query_heap heap) = 0;
/// <summary>
/// Gets the results of queries in a query heap.
/// </summary>
/// <param name="heap">Query heap that contains the queries.</param>
/// <param name="first">Index of the first query in the query heap to copy the results from.</param>
/// <param name="count">Number of query results to copy.</param>
/// <param name="results">Pointer to the first element of an array that is filled with the results. The necessary data type is documented at the <see cref="query_type"/> enumeration.</param>
/// <param name="stride">Size (in bytes) of each element in the <paramref name="results"/> array.</param>
/// <returns><see langword="true"/> if the query results were successfully downloaded from the GPU, <see langword="false"/> otherwise.</returns>
virtual bool get_query_heap_results(query_heap heap, uint32_t first, uint32_t count, void *results, uint32_t stride) = 0;
/// <summary>
/// Associates a name with a resource, for easier debugging in external tools.
/// </summary>
/// <param name="resource">Resource to associate a name with.</param>
/// <param name="name">Null-terminated name string.</param>
virtual void set_resource_name(resource resource, const char *name) = 0;
/// <summary>
/// Associates a name with a resource view, for easier debugging in external tools.
/// </summary>
/// <param name="view">Resource view to associate a name with.</param>
/// <param name="name">Null-terminated name string.</param>
virtual void set_resource_view_name(resource_view view, const char *name) = 0;
/// <summary>
/// Creates a new fence synchronization object.
/// </summary>
/// <param name="initial_value">The initial value for the fence.</param>
/// <param name="flags">Fence creation options.</param>
/// <param name="out_fence">Pointer to a variable that is set to the handle of the created fence.</param>
/// <param name="shared_handle">Optional pointer to a variable of type <c>HANDLE</c> used when <paramref name="flags"/> contains <see cref="fence_flags::shared"/>. When that variable is a <see langword="nullptr"/>, it is set to the exported shared handle of the created fence. When that variable is a valid handle, the fence is imported from that shared handle.</param>
/// <returns><see langword="true"/> if the fence was successfully created, <see langword="false"/> otherwise (in this case <paramref name="out_fence"/> is set to zero).</returns>
virtual bool create_fence(uint64_t initial_value, fence_flags flags, fence *out_fence, void **shared_handle = nullptr) = 0;
/// <summary>
/// Instantly destroys a fence that was previously created via <see cref="create_fence"/>.
/// </summary>
virtual void destroy_fence(fence fence) = 0;
/// <summary>
/// Gets the current value of the specified fence.
/// </summary>
virtual uint64_t get_completed_fence_value(fence fence) const = 0;
/// <summary>
/// Wait until the specified fence reached the specified value.
/// </summary>
/// <param name="fence">Fence to wait on.</param>
/// <param name="value">Value the fence has to each or exceed.</param>
/// <param name="timeout">Return early after the specified time in nanoseconds, or set to UINT64_MAX to never time out.</param>
/// <returns><see langword="true"/> if the wait operation was successful, <see langword="false"/> otherwise.</returns>
virtual bool wait(fence fence, uint64_t value, uint64_t timeout = UINT64_MAX) = 0;
/// <summary>
/// Updates the specified fence to the specified value.
/// </summary>
/// <param name="fence">Fence to update.</param>
/// <param name="value">Value the fence should be set to.</param>
/// <returns><see langword="true"/> if the signal operation was successful, <see langword="false"/> otherwise.</returns>
virtual bool signal(fence fence, uint64_t value) = 0;
/// <summary>
/// Gets data for a <paramref name="property"/> of this device.
/// </summary>
/// <param name="property">Property to query.</param>
/// <param name="data">Pointer to a variable that is set to the value of the property. The necessary data type is documented at the <see cref="device_properties"/> enumeration.</param>
/// <returns><see langword="true"/> if the property exists and was retrieved, <see langword="false"/> otherwise.</returns>
virtual bool get_property(device_properties property, void *data) const = 0;
/// <summary>
/// Gets the GPU address for a resource view.
/// </summary>
/// <param name="view">Resource view to query.</param>
/// <returns>GPU address of the resource view, or zero in case of failure or when no fixed GPU address exists.</returns>
virtual uint64_t get_resource_view_gpu_address(resource_view view) const = 0;
/// <summary>
/// Gets the required acceleration structure size needed to build the specified data.
/// </summary>
/// <seealso cref="device_caps::ray_tracing"/>
/// <param name="type">Type of the acceleration structure.</param>
/// <param name="flags">Acceleration structure build options.</param>
/// <param name="input_count">Number of build inputs.</param>
/// <param name="inputs">Pointer to the first element of an array of build inputs describing the geometry of the acceleration structure.</param>
/// <param name="out_size">Pointer to a variable that is set to the required buffer size for the acceleration structure.</param>
/// <param name="out_build_scratch_size">Pointer to a variable that is set to the required scratch buffer size for building the acceleration structure.</param>
/// <param name="out_update_scratch_size">Pointer to a variable that is set to the required scratch buffer size for updating the acceleration structure.</param>
virtual void get_acceleration_structure_size(acceleration_structure_type type, acceleration_structure_build_flags flags, uint32_t input_count, const acceleration_structure_build_input *inputs, uint64_t *out_size, uint64_t *out_build_scratch_size, uint64_t *out_update_scratch_size) const = 0;
/// <summary>
/// Gets the shader group handles for a ray tracing pipeline, to be put into a shader binding table.
/// </summary>
/// <seealso cref="device_caps::ray_tracing"/>
/// <param name="pipeline">Ray tracing pipeline to query.</param>
/// <param name="first">Index of the first shader group in the <see cref="pipeline_subobject_type::shader_groups"/> array that was used to create the pipeline.</param>
/// <param name="count">Number of shader groups to get handles for.</param>
/// <param name="out_handles">Pointer to the first element of an array (with elements of the size reported by <see cref="device_properties::shader_group_handle_size"/>) that is filled with the handles.</param>
/// <returns><see langword="true"/> if the shader group handles were successfully retrieved, <see langword="false"/> otherwise.</returns>
virtual bool get_pipeline_shader_group_handles(pipeline pipeline, uint32_t first, uint32_t count, void *out_handles) = 0;
};
/// <summary>
/// The base class for objects that are children to a logical render <see cref="device"/>.
/// </summary>
struct __declspec(novtable) device_object : public api_object
{
/// <summary>
/// Gets the parent device for this object.
/// </summary>
virtual device *get_device() = 0;
};
/// <summary>
/// Type of an indirect draw/dispatch command.
/// </summary>
/// <seealso cref="command_list::draw_or_dispatch_indirect"/>
enum class indirect_command
{
unknown,
draw,
draw_indexed,
dispatch,
dispatch_mesh,
dispatch_rays
};
/// <summary>
/// A command list, used to enqueue render commands on the CPU, before later executing them in a command queue.
/// <para>Functionally equivalent to a 'ID3D11CommandList', 'ID3D12CommandList' or 'VkCommandBuffer'.</para>
/// </summary>
/// <remarks>
/// This class may NOT be used concurrently from multiple threads!
/// </remarks>
struct __declspec(novtable) command_list : public device_object
{
/// <summary>
/// Adds a barrier for the specified <paramref name="resource"/> to the command stream.
/// Multiple barriers are more efficiently issued using the <see cref="command_list::barrier"/> overload that takes arrays.
/// When both <paramref name="old_state"/> and <paramref name="new_state"/> are <see cref="resource_usage::unordered_access"/>, a UAV barrier is added, otherwise a state transition is performed.
/// </summary>
/// <param name="resource">Resource to transition.</param>
/// <param name="old_state">Usage flags describing how the <paramref name="resource"/> was used before this barrier.</param>
/// <param name="new_state">Usage flags describing how the <paramref name="resource"/> will be used after this barrier.</param>
void barrier(resource resource, resource_usage old_state, resource_usage new_state) { barrier(1, &resource, &old_state, &new_state); }
/// <summary>
/// Adds a barrier for the specified <paramref name="resources"/> to the command stream.
/// </summary>
/// <param name="count">Number of resources to transition.</param>
/// <param name="resources">Pointer to the first element of an array of resources to transition.</param>
/// <param name="old_states">Pointer to the first element of an array of usage flags describing how the <paramref name="resources"/> were used before this barrier.</param>
/// <param name="new_states">Pointer to the first element of an array of usage flags describing how the <paramref name="resources"/> will be used after this barrier.</param>
virtual void barrier(uint32_t count, const resource *resources, const resource_usage *old_states, const resource_usage *new_states) = 0;
/// <summary>
/// Begins a render pass and binds render target and depth-stencil resource views.
/// </summary>
/// <param name="count">Number of render target views to bind.</param>
/// <param name="rts">Pointer to the first element of an array of render target descriptions.</param>
/// <param name="ds">Optional pointer to a depth-stencil description, or <see langword="nullptr"/> to bind none.</param>
virtual void begin_render_pass(uint32_t count, const render_pass_render_target_desc *rts, const render_pass_depth_stencil_desc *ds = nullptr) = 0;
/// <summary>
/// Ends a render pass.
/// This must be preceeded by a call to <see cref="begin_render_pass"/>.
/// Render passes cannot be nested.
/// </summary>
virtual void end_render_pass() = 0;
/// <summary>
/// Binds individual render target and depth-stencil resource views.
/// This must not be called between <see cref="begin_render_pass"/> and <see cref="end_render_pass"/>.
/// </summary>
/// <seealso cref="device_caps::bind_render_targets_and_depth_stencil"/>
/// <param name="count">Number of render target views to bind.</param>
/// <param name="rtvs">Pointer to the first element of an array of render target views to bind.</param>
/// <param name="dsv">Depth-stencil view to bind, or zero to bind none.</param>
virtual void bind_render_targets_and_depth_stencil(uint32_t count, const resource_view *rtvs, resource_view dsv = { 0 }) = 0;
/// <summary>
/// Binds a pipeline state object.
/// </summary>
/// <param name="stages">Pipeline stages to update with state from the pipeline state object.</param>
/// <param name="pipeline">Pipeline state object to bind.</param>
virtual void bind_pipeline(pipeline_stage stages, pipeline pipeline) = 0;
/// <summary>
/// Updates the specfified pipeline <paramref name="state"/> to the specified <paramref name="value"/>.
/// This is only valid for states that have been listed in the dynamic states provided at creation of the currently bound pipeline state object (<see cref="pipeline_subobject_type::dynamic_pipeline_states"/>).
/// </summary>
/// <param name="state">Pipeline state to update.</param>
/// <param name="value">Value to update the pipeline state to.</param>
void bind_pipeline_state(dynamic_state state, uint32_t value) { bind_pipeline_states(1, &state, &value); }
/// <summary>
/// Updates the specfified pipeline <paramref name="states"/> to the specified <paramref name="values"/>.
/// This is only valid for states that have been listed in the dynamic states provided at creation of the currently bound pipeline state object (<see cref="pipeline_subobject_type::dynamic_pipeline_states"/>).
/// </summary>
/// <param name="count">Number of pipeline states to update.</param>
/// <param name="states">Pointer to the first element of an array of pipeline states to update.</param>
/// <param name="values">Pointer to the first element of an array of values to update the pipeline states to, with one for each state in <paramref name="states"/>.</param>
virtual void bind_pipeline_states(uint32_t count, const dynamic_state *states, const uint32_t *values) = 0;
/// <summary>
/// Binds an array of viewports to the rasterizer stage.
/// </summary>
/// <seealso cref="device_caps::multi_viewport"/>
/// <param name="first">Index of the first viewport to bind. In D3D9, D3D10, D3D11 and D3D12 this has to be 0.</param>
/// <param name="count">Number of viewports to bind.</param>
/// <param name="viewports">Pointer to the first element of an array of viewports.</param>
virtual void bind_viewports(uint32_t first, uint32_t count, const viewport *viewports) = 0;
/// <summary>
/// Binds an array of scissor rectangles to the rasterizer stage.
/// </summary>
/// <seealso cref="device_caps::multi_viewport"/>
/// <param name="first">Index of the first scissor rectangle to bind. In D3D9, D3D10, D3D11 and D3D12 this has to be 0.</param>
/// <param name="count">Number of scissor rectangles to bind.</param>
/// <param name="rects">Pointer to the first element of an array of scissor rectangles.</param>
virtual void bind_scissor_rects(uint32_t first, uint32_t count, const rect *rects) = 0;
/// <summary>
/// Directly updates constant values in the specified shader pipeline stages.
/// <para>In D3D9 this updates the values of uniform registers, in D3D10/11 and OpenGL the constant buffer specified in the pipeline layout, in D3D12 it sets root constants and in Vulkan push constants.</para>
/// </summary>
/// <seealso cref="device_caps::partial_push_constant_updates"/>
/// <param name="stages">Shader stages that will use the updated constants.</param>
/// <param name="layout">Pipeline layout that describes where the constants are located.</param>
/// <param name="param">Layout parameter index of the constant range in the pipeline <paramref name="layout"/> (root parameter index in D3D12).</param>
/// <param name="first">Start offset (in 32-bit values) to the first constant in the constant range to begin updating.</param>
/// <param name="count">Number of 32-bit values to update.</param>
/// <param name="values">Pointer to the first element of an array of 32-bit values to set the constants to. These can be floating-point, integer or boolean depending on what the shader is expecting.</param>
virtual void push_constants(shader_stage stages, pipeline_layout layout, uint32_t param, uint32_t first, uint32_t count, const void *values) = 0;
/// <summary>
/// Directly binds a temporary descriptor table for the specfified shader pipeline stage and updates with an array of descriptors.
/// </summary>
/// <seealso cref="device_caps::partial_push_descriptor_updates"/>
/// <param name="stages">Shader stages that will use the updated descriptors.</param>
/// <param name="layout">Pipeline layout that describes the descriptors.</param>
/// <param name="param">Layout parameter index of the descriptor table in the pipeline <paramref name="layout"/> (root parameter index in D3D12, descriptor set index in Vulkan).</param>
/// <param name="update">Range of descriptors to update in the temporary descriptor table (<see cref="descriptor_table_update::table"/> is ignored).</param>
virtual void push_descriptors(shader_stage stages, pipeline_layout layout, uint32_t param, const descriptor_table_update &update) = 0;
/// <summary>
/// Binds a single descriptor table.
/// </summary>
/// <param name="stages">Shader stages that will use the descriptors.</param>
/// <param name="layout">Pipeline layout that describes the descriptors.</param>
/// <param name="param">Index of the pipeline <paramref name="layout"/> parameter that describes the descriptor table (root parameter index in D3D12, descriptor set index in Vulkan).</param>
/// <param name="table">Descriptor table to bind.</param>
void bind_descriptor_table(shader_stage stages, pipeline_layout layout, uint32_t param, descriptor_table table) { bind_descriptor_tables(stages, layout, param, 1, &table); }
/// <summary>
/// Binds an array of descriptor tables.
/// </summary>
/// <param name="stages">Shader stages that will use the descriptors.</param>
/// <param name="layout">Pipeline layout that describes the descriptors.</param>
/// <param name="first">Index of the first pipeline <paramref name="layout"/> parameter that describes the first descriptor table to bind (root parameter index in D3D12, descriptor set index in Vulkan).</param>
/// <param name="count">Number of descriptor tables to bind.</param>
/// <param name="tables">Pointer to the first element of an array of descriptor tables to bind.</param>
virtual void bind_descriptor_tables(shader_stage stages, pipeline_layout layout, uint32_t first, uint32_t count, const descriptor_table *tables) = 0;
/// <summary>
/// Binds an index buffer to the input-assembler stage.
/// </summary>
/// <param name="buffer">Index buffer resource. This resource must have been created with the <see cref="resource_usage::index_buffer"/> usage.</param>
/// <param name="offset">Offset (in bytes) from the start of the index buffer to the first index to use. In D3D9 this has to be 0.</param>
/// <param name="index_size">Size (in bytes) of each index. Can typically be 2 (16-bit indices) or 4 (32-bit indices).</param>
virtual void bind_index_buffer(resource buffer, uint64_t offset, uint32_t index_size) = 0;
/// <summary>
/// Binds a single vertex buffer to the input-assembler stage.
/// </summary>
/// <param name="index">Input slot for binding.</param>
/// <param name="buffer">Vertex buffer resource. This resources must have been created with the <see cref="resource_usage::vertex_buffer"/> usage.</param>
/// <param name="offset">Offset (in bytes) from the start of the vertex buffer to the first vertex element to use.</param>
/// <param name="stride">Size (in bytes) of the vertex element that will be used from the vertex buffer (is added to an element offset to advance to the next).</param>
void bind_vertex_buffer(uint32_t index, resource buffer, uint64_t offset, uint32_t stride) { bind_vertex_buffers(index, 1, &buffer, &offset, &stride); }
/// <summary>
/// Binds an array of vertex buffers to the input-assembler stage.
/// </summary>
/// <param name="first">First input slot for binding.</param>
/// <param name="count">Number of vertex buffers to bind.</param>
/// <param name="buffers">Pointer to the first element of an array of vertex buffer resources. These resources must have been created with the <see cref="resource_usage::vertex_buffer"/> usage.</param>
/// <param name="offsets">Pointer to the first element of an array of offset values, one for each buffer. Each offset is the number of bytes from the start of the vertex buffer to the first vertex element to use.</param>
/// <param name="strides">Pointer to the first element of an array of stride values, one for each buffer. Each stride is the size (in bytes) of the vertex element that will be used from that vertex buffer (is added to an element offset to advance to the next).</param>
virtual void bind_vertex_buffers(uint32_t first, uint32_t count, const resource *buffers, const uint64_t *offsets, const uint32_t *strides) = 0;
/// <summary>
/// Binds an array of buffers to the stream-output stage.
/// </summary>
/// <param name="first">First stream-output slot for binding.</param>
/// <param name="count">Number of stream-output targets to bind.</param>
/// <param name="buffers">Pointer to the first element of an array of buffer resources. These resources must have been created with the <see cref="resource_usage::stream_output"/> usage.</param>
/// <param name="offsets">Pointer to the first element of an array of offset values, one for each buffer. Each offset is the number of bytes from the start of the buffer to the first element to write to.</param>
/// <param name="max_sizes">Optional pointer to an array of size values, one for each buffer. Can be <see langword="nullptr"/> or have elements set to UINT64_MAX to use the entire buffer.</param>
/// <param name="counter_buffers">Pointer to the first element of an array of counter buffer resources. These resources must have been created with the <see cref="resource_usage::stream_output"/> usage.</param>
/// <param name="counter_offsets">Pointer to the first element of an array of counter offset values, one for each counter buffer. Each offset is the number of bytes from the start of the counter buffer to the first element to write to.</param>
virtual void bind_stream_output_buffers(uint32_t first, uint32_t count, const api::resource *buffers, const uint64_t *offsets, const uint64_t *max_sizes, const api::resource *counter_buffers, const uint64_t *counter_offsets) = 0;
/// <summary>
/// Draws non-indexed primitives.
/// </summary>
/// <seealso cref="device_caps::draw_instanced"/>
/// <param name="vertex_count">Number of vertices to draw.</param>
/// <param name="instance_count">Number of instances to draw. In D3D9 this has to be 1.</param>
/// <param name="first_vertex">Index of the first vertex.</param>
/// <param name="first_instance">Value added to each index before reading per-instance data from a vertex buffer. In D3D9 this has to be 0.</param>
virtual void draw(uint32_t vertex_count, uint32_t instance_count, uint32_t first_vertex, uint32_t first_instance) = 0;
/// <summary>
/// Draws indexed primitives.
/// </summary>
/// <seealso cref="device_caps::draw_instanced"/>
/// <param name="index_count">Number of indices read from the index buffer for each instance.</param>
/// <param name="instance_count">Number of instances to draw. In D3D9 this has to be 1.</param>
/// <param name="first_index">Location of the first index read from the index buffer.</param>
/// <param name="vertex_offset">Value added to each index before reading per-vertex data from a vertex buffer.</param>
/// <param name="first_instance">Value added to each index before reading per-instance data from a vertex buffer. In D3D9 this has to be 0.</param>
virtual void draw_indexed(uint32_t index_count, uint32_t instance_count, uint32_t first_index, int32_t vertex_offset, uint32_t first_instance) = 0;
/// <summary>
/// Performs a compute shader dispatch.
/// </summary>
/// <seealso cref="device_caps::compute_shader"/>
/// <param name="group_count_x">Number of thread groups dispatched in the x direction.</param>
/// <param name="group_count_y">Number of thread groups dispatched in the y direction.</param>
/// <param name="group_count_z">Number of thread groups dispatched in the z direction.</param>
virtual void dispatch(uint32_t group_count_x, uint32_t group_count_y, uint32_t group_count_z) = 0;
/// <summary>
/// Executes indirect draw or dispatch commands.
/// </summary>
/// <seealso cref="device_caps::draw_or_dispatch_indirect"/>
/// <param name="type">Specifies whether this is an indirect draw, indexed draw or dispatch command.</param>
/// <param name="buffer">Buffer resource that contains command arguments.</param>
/// <param name="offset">Offset (in bytes) from the start of the argument buffer to the first argument to use.</param>
/// <param name="draw_count">Number of commands to execute.</param>
/// <param name="stride">Stride (in bytes) between commands in the argument buffer.</param>
virtual void draw_or_dispatch_indirect(indirect_command type, resource buffer, uint64_t offset, uint32_t draw_count, uint32_t stride) = 0;
/// <summary>
/// Copies the entire contents of the <paramref name="source"/> resource to the <paramref name="dest"/>ination resource. Dimensions of the two resources have to match.
/// </summary>
/// <remarks>
/// The <paramref name="source"/> resource has to be in the <see cref="resource_usage::copy_source"/> state.
/// The <paramref name="dest"/>ination resource has to be in the <see cref="resource_usage::copy_dest"/> state.
/// </remarks>
/// <param name="source">Resource to copy from.</param>
/// <param name="dest">Resource to copy to.</param>
virtual void copy_resource(resource source, resource dest) = 0;
/// <summary>
/// Copies a linear memory region from the <paramref name="source"/> buffer to the <paramref name="dest"/>ination buffer.
/// </summary>
/// <remarks>
/// The <paramref name="source"/> resource has to be in the <see cref="resource_usage::copy_source"/> state.
/// The <paramref name="dest"/>ination resource has to be in the <see cref="resource_usage::copy_dest"/> state.
/// </remarks>
/// <seealso cref="device_caps::copy_buffer_region"/>
/// <param name="source">Buffer resource to copy from.</param>
/// <param name="source_offset">Offset (in bytes) into the <paramref name="source"/> buffer to start copying at.</param>
/// <param name="dest">Buffer resource to copy to.</param>
/// <param name="dest_offset">Offset (in bytes) into the <paramref name="dest"/>ination buffer to start copying to.</param>
/// <param name="size">Number of bytes to copy.</param>
virtual void copy_buffer_region(resource source, uint64_t source_offset, resource dest, uint64_t dest_offset, uint64_t size) = 0;
/// <summary>
/// Copies a texture region from the <paramref name="source"/> buffer to the <paramref name="dest"/>ination texture.
/// </summary>
/// <remarks>
/// The <paramref name="source"/> resource has to be in the <see cref="resource_usage::copy_source"/> state.
/// The <paramref name="dest"/>ination resource has to be in the <see cref="resource_usage::copy_dest"/> state.
/// </remarks>
/// <seealso cref="device_caps::copy_buffer_to_texture"/>
/// <param name="source">Buffer resource to copy from.</param>
/// <param name="source_offset">Offset (in bytes) into the <paramref name="source"/> buffer to start copying at.</param>
/// <param name="row_length">Number of pixels from one row to the next (in the buffer), or zero if data is tightly packed.</param>
/// <param name="slice_height">Number of rows from one slice to the next (in the buffer) or zero if data is tightly packed.</param>
/// <param name="dest">Texture resource to copy to.</param>
/// <param name="dest_subresource">Index of the subresource of the <paramref name="dest"/>ination texture to copy to.</param>
/// <param name="dest_box">Optional 3D box (or <see langword="nullptr"/> to reference the entire subresource) that defines the region in the <paramref name="dest"/>ination texture to copy to.</param>
virtual void copy_buffer_to_texture(resource source, uint64_t source_offset, uint32_t row_length, uint32_t slice_height, resource dest, uint32_t dest_subresource, const subresource_box *dest_box = nullptr) = 0;
/// <summary>
/// Copies or blits a texture region from the <paramref name="source"/> texture to the <paramref name="dest"/>ination texture.
/// </summary>
/// <remarks>
/// The <paramref name="source"/> resource has to be in the <see cref="resource_usage::copy_source"/> state.
/// The <paramref name="dest"/>ination resource has to be in the <see cref="resource_usage::copy_dest"/> state.
/// </remarks>
/// <seealso cref="device_caps::blit"/>
/// <param name="source">Texture resource to copy from.</param>
/// <param name="source_subresource">Index of the subresource of the <paramref name="source"/> texture to copy from.</param>
/// <param name="source_box">Optional 3D box (or <see langword="nullptr"/> to reference the entire subresource) that defines the region in the <paramref name="source"/> texture to blit from.</param>
/// <param name="dest">Texture resource to copy to.</param>
/// <param name="dest_subresource">Index of the subresource of the <paramref name="dest"/>ination texture to copy to.</param>
/// <param name="dest_box">Optional 3D box (or <see langword="nullptr"/> to reference the entire subresource) that defines the region in the <paramref name="dest"/>ination texture to blit to.</param>
/// <param name="filter">Filter to apply when copy requires scaling.</param>
virtual void copy_texture_region(resource source, uint32_t source_subresource, const subresource_box *source_box, resource dest, uint32_t dest_subresource, const subresource_box *dest_box, filter_mode filter = filter_mode::min_mag_mip_point) = 0;
/// <summary>
/// Copies a texture region from the <paramref name="source"/> texture to the <paramref name="dest"/>ination buffer.
/// </summary>
/// <remarks>
/// The <paramref name="source"/> resource has to be in the <see cref="resource_usage::copy_source"/> state.
/// The <paramref name="dest"/>ination resource has to be in the <see cref="resource_usage::copy_dest"/> state.
/// </remarks>
/// <seealso cref="device_caps::copy_buffer_to_texture"/>
/// <param name="source">Texture resource to copy from.</param>
/// <param name="source_subresource">Index of the subresource of the <paramref name="source"/> texture to copy from.</param>
/// <param name="source_box">Optional 3D box (or <see langword="nullptr"/> to reference the entire subresource) that defines the region in the <paramref name="source"/> texture to copy from.</param>
/// <param name="dest">Buffer resource to copy to.</param>
/// <param name="dest_offset">Offset (in bytes) into the <paramref name="dest"/>ination buffer to start copying to.</param>
/// <param name="row_length">Number of pixels from one row to the next (in the buffer), or zero if data is tightly packed.</param>
/// <param name="slice_height">Number of rows from one slice to the next (in the buffer), or zero if data is tightly packed.</param>
virtual void copy_texture_to_buffer(resource source, uint32_t source_subresource, const subresource_box *source_box, resource dest, uint64_t dest_offset, uint32_t row_length = 0, uint32_t slice_height = 0) = 0;
/// <summary>
/// Copies a region from the multisampled <paramref name="source"/> texture to the non-multisampled <paramref name="dest"/>ination texture.
/// </summary>
/// <remarks>
/// The <paramref name="source"/> resource has to be in the <see cref="resource_usage::resolve_source"/> state.
/// The <paramref name="dest"/>ination resource has to be in the <see cref="resource_usage::resolve_dest"/> state.
/// </remarks>
/// <seealso cref="device_caps::resolve_region"/>
/// <seealso cref="device_caps::resolve_depth_stencil"/>
/// <param name="source">Texture resource to resolve from.</param>
/// <param name="source_subresource">Index of the subresource of the <paramref name="source"/> texture to resolve from.</param>
/// <param name="source_box">Optional 3D box (or <see langword="nullptr"/> to reference the entire subresource) that defines the region in the <paramref name="source"/> texture to resolve.</param>
/// <param name="dest">Texture resource to resolve to.</param>
/// <param name="dest_subresource">Index of the subresource of the <paramref name="dest"/>ination texture to resolve to.</param>
/// <param name="dest_x">Optional X offset (in texels) that defines the region in the <paramref name="dest"/>ination texture to resolve to.</param>
/// <param name="dest_y">Optional Y offset (in texels) that defines the region in the <paramref name="dest"/>ination texture to resolve to.</param>
/// <param name="dest_z">Optional Z offset (in texels) that defines the region in the <paramref name="dest"/>ination texture to resolve to.</param>
/// <param name="format">Format of the resource data.</param>
virtual void resolve_texture_region(resource source, uint32_t source_subresource, const subresource_box *source_box, resource dest, uint32_t dest_subresource, uint32_t dest_x, uint32_t dest_y, uint32_t dest_z, format format) = 0;
/// <summary>
/// Clears the resource referenced by the depth-stencil view.
/// </summary>
/// <remarks>
/// The resource the depth-stencil view points to has to be in the <see cref="resource_usage::depth_stencil_write"/> state.
/// </remarks>
/// <param name="dsv">Resource view handle of the depth-stencil.</param>
/// <param name="depth">Optional value to clear the depth buffer with.</param>
/// <param name="stencil">Optional value to clear the stencil buffer with.</param>
/// <param name="rect_count">Number of rectangles to clear in the depth-stencil resource, or zero to clear the whole resource.</param>
/// <param name="rects">Pointer to the first element of an array of rectangles.</param>
virtual void clear_depth_stencil_view(resource_view dsv, const float *depth, const uint8_t *stencil, uint32_t rect_count = 0, const rect *rects = nullptr) = 0;
/// <summary>
/// Clears the resource referenced by the render target view.
/// </summary>
/// <remarks>
/// The resource the render target view points to has to be in the <see cref="resource_usage::render_target"/> state.
/// </remarks>
/// <param name="rtv">Resource view handle of the render target.</param>
/// <param name="color">Value to clear the resource with.</param>
/// <param name="rect_count">Number of rectangles to clear in the render target resource, or zero to clear the whole resource.</param>
/// <param name="rects">Pointer to the first element of an array of rectangles.</param>
virtual void clear_render_target_view(resource_view rtv, const float color[4], uint32_t rect_count = 0, const rect *rects = nullptr) = 0;
/// <summary>
/// Clears the resource referenced by the unordered access view.
/// </summary>
/// <remarks>
/// The resource the unordered access view points to has to be in the <see cref="resource_usage::unordered_access"/> state.
/// </remarks>
/// <param name="uav">Resource view handle of the unordered access view.</param>
/// <param name="values">Value to clear the resource with.</param>
/// <param name="rect_count">Number of rectangles to clear in the unordered access resource, or zero to clear the whole resource.</param>
/// <param name="rects">Pointer to the first element of an array of rectangles.</param>
virtual void clear_unordered_access_view_uint(resource_view uav, const uint32_t values[4], uint32_t rect_count = 0, const rect *rects = nullptr) = 0;
/// <summary>
/// Clears the resource referenced by the unordered access view.
/// </summary>
/// <remarks>
/// The resource the unordered access view points to has to be in the <see cref="resource_usage::unordered_access"/> state.
/// </remarks>
/// <param name="uav">Resource view handle of the unordered access view.</param>
/// <param name="values">Value to clear the resource with.</param>
/// <param name="rect_count">Number of rectangles to clear in the unordered access resource, or zero to clear the whole resource.</param>
/// <param name="rects">Pointer to the first element of an array of rectangles.</param>
virtual void clear_unordered_access_view_float(resource_view uav, const float values[4], uint32_t rect_count = 0, const rect *rects = nullptr) = 0;
/// <summary>
/// Generates the lower mipmap levels for the specified shader resource view.
/// Uses the largest mipmap level of the view to recursively generate the lower levels of the mipmap chain and stops with the smallest level that is specified by the view.
/// </summary>
/// <remarks>
/// This will invalidate all previous descriptor and pipeline bindings, which will need to be reset by calls to <see cref="bind_descriptor_tables"/> or <see cref="push_descriptors"/> and <see cref="bind_pipeline"/>.