1 module gfx.graal.device;
2 
3 import core.time : Duration;
4 
5 import gfx.core.rc;
6 import gfx.graal.buffer;
7 import gfx.graal.cmd;
8 import gfx.graal.format;
9 import gfx.graal.image;
10 import gfx.graal.memory;
11 import gfx.graal.pipeline;
12 import gfx.graal.presentation;
13 import gfx.graal.queue;
14 import gfx.graal.renderpass;
15 import gfx.graal.sync;
16 
17 import std.typecons : Flag;
18 
19 struct DeviceFeatures {
20     bool presentation;
21     bool anisotropy;
22 
23     static @property DeviceFeatures all() {
24         return DeviceFeatures(
25             true, true
26         );
27     }
28     static @property DeviceFeatures none() {
29         return DeviceFeatures(
30             false, false
31         );
32     }
33 }
34 
35 struct DeviceLimits {}
36 
37 enum DeviceType {
38     other,
39     integratedGpu,
40     discreteGpu,
41     virtualGpu,
42     cpu
43 }
44 
45 /// A request for a queue family and each queue to be created within that family.
46 /// The amount of queue to be created is given by priorities.length.
47 /// Priorities represent the relative priority to be given to each queue (from 0 to 1)
48 struct QueueRequest
49 {
50     uint familyIndex;
51     float[] priorities;
52 }
53 
54 /// Represent a physical device. This interface is meant to describe a graphics
55 /// device and open a logical device out of it.
56 interface PhysicalDevice : AtomicRefCounted
57 {
58     @property string name();
59 
60     @property DeviceType type();
61     final @property bool softwareRendering() {
62         return type == DeviceType.cpu;
63     }
64 
65     @property DeviceFeatures features();
66 
67     @property DeviceLimits limits();
68 
69     @property MemoryProperties memoryProperties();
70 
71     @property QueueFamily[] queueFamilies();
72 
73     FormatProperties formatProperties(in Format format);
74 
75     bool supportsSurface(uint queueFamilyIndex, Surface surface);
76     SurfaceCaps surfaceCaps(Surface surface);
77     Format[] surfaceFormats(Surface surface);
78     PresentMode[] surfacePresentModes(Surface surface);
79 
80     /// Open a logical device with the specified queues.
81     /// Returns: null if it can't meet all requested queues, the opened device otherwise.
82     Device open(in QueueRequest[] queues, in DeviceFeatures features=DeviceFeatures.all)
83     in {
84         assert(queues.isConsistentWith(queueFamilies));
85     }
86 }
87 
88 /// Checks that the requests are consistent with families
89 private bool isConsistentWith(in QueueRequest[] requests, in QueueFamily[] families)
90 {
91     // TODO
92     return true;
93 }
94 
95 struct MappedMemorySet
96 {
97     package(gfx) struct MM {
98         DeviceMemory dm;
99         size_t offset;
100         size_t size;
101     }
102 
103     package(gfx) void addMM(MM mm) {
104         mms ~= mm;
105     }
106 
107     package(gfx) MM[] mms;
108 }
109 
110 /// Handle to a logical device
111 interface Device : AtomicRefCounted
112 {
113     /// Wait that device finishes all operations in progress
114     void waitIdle();
115 
116     Queue getQueue(uint queueFamilyIndex, uint queueIndex);
117 
118     CommandPool createCommandPool(uint queueFamilyIndex);
119 
120     DeviceMemory allocateMemory(uint memPropIndex, size_t size);
121     void flushMappedMemory(MappedMemorySet set);
122     void invalidateMappedMemory(MappedMemorySet set);
123 
124     Buffer createBuffer(BufferUsage usage, size_t size);
125 
126     Image createImage(in ImageInfo info);
127 
128     Sampler createSampler(in SamplerInfo info);
129 
130     Semaphore createSemaphore();
131     Fence createFence(Flag!"signaled" signaled);
132     void resetFences(Fence[] fences);
133     void waitForFences(Fence[] fences, Flag!"waitAll" waitAll, Duration timeout);
134 
135     Swapchain createSwapchain(Surface surface, PresentMode pm, uint numImages,
136                               Format format, uint[2] size, ImageUsage usage,
137                               CompositeAlpha alpha, Swapchain former=null);
138 
139     RenderPass createRenderPass(in AttachmentDescription[] attachments,
140                                 in SubpassDescription[] subpasses,
141                                 in SubpassDependency[] dependencies);
142 
143     Framebuffer createFramebuffer(RenderPass rp, ImageView[] attachments,
144                                   uint width, uint height, uint layers);
145 
146     ShaderModule createShaderModule(const(uint)[] spirV, string entryPoint);
147 
148     DescriptorSetLayout createDescriptorSetLayout(in PipelineLayoutBinding[] bindings);
149 
150     PipelineLayout createPipelineLayout(DescriptorSetLayout[] layouts, PushConstantRange[] ranges);
151 
152     DescriptorPool createDescriptorPool(in uint maxSets, in DescriptorPoolSize[] sizes);
153 
154     void updateDescriptorSets(WriteDescriptorSet[] writeOps, CopyDescritporSet[] copyOps);
155 
156     Pipeline[] createPipelines(PipelineInfo[] infos);
157 }