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 }
22 
23 struct DeviceLimits {
24     ShaderLanguage supportedShaderLanguages;
25 }
26 
27 enum DeviceType {
28     other,
29     integratedGpu,
30     discreteGpu,
31     virtualGpu,
32     cpu
33 }
34 
35 /// A request for a queue family and each queue to be created within that family.
36 /// The amount of queue to be created is given by priorities.length.
37 /// Priorities represent the relative priority to be given to each queue (from 0 to 1)
38 struct QueueRequest
39 {
40     uint familyIndex;
41     float[] priorities;
42 }
43 
44 /// Represent a physical device. This interface is meant to describe a graphics
45 /// device and open a logical device out of it.
46 interface PhysicalDevice : AtomicRefCounted
47 {
48     @property uint apiVersion();
49 
50     @property uint driverVersion();
51 
52     @property uint vendorId();
53 
54     @property uint deviceId();
55 
56     @property string name();
57 
58     @property DeviceType type();
59     final @property bool softwareRendering() {
60         return type == DeviceType.cpu;
61     }
62 
63     @property DeviceFeatures features();
64 
65     @property DeviceLimits limits();
66 
67     @property MemoryProperties memoryProperties();
68 
69     @property QueueFamily[] queueFamilies();
70 
71     FormatProperties formatProperties(in Format format);
72 
73     bool supportsSurface(uint queueFamilyIndex, Surface surface);
74     SurfaceCaps surfaceCaps(Surface surface);
75     Format[] surfaceFormats(Surface surface);
76     PresentMode[] surfacePresentModes(Surface surface);
77 
78     /// Open a logical device with the specified queues.
79     /// Returns: null if it can't meet all requested queues, the opened device otherwise.
80     Device open(in QueueRequest[] queues)
81     in {
82         assert(queues.isConsistentWith(queueFamilies));
83     }
84 }
85 
86 /// Checks that the requests are consistent with families
87 private bool isConsistentWith(in QueueRequest[] requests, in QueueFamily[] families)
88 {
89     // TODO
90     return true;
91 }
92 
93 struct MappedMemorySet
94 {
95     package(gfx) struct MM {
96         DeviceMemory dm;
97         size_t offset;
98         size_t size;
99     }
100 
101     package(gfx) void addMM(MM mm) {
102         (cast(RcHack!DeviceMemory)mm.dm).retain();
103         mms ~= mm;
104     }
105 
106 
107     package(gfx) MM[] mms;
108 
109     this(this) {
110         import std.algorithm : each;
111         mms.each!(m => (cast(RcHack!DeviceMemory)m.dm).retain());
112     }
113 
114     ~this() {
115         import std.algorithm : each;
116         mms.each!(m => (cast(RcHack!DeviceMemory)m.dm).release());
117     }
118 }
119 
120 /// Handle to a logical device
121 interface Device : AtomicRefCounted
122 {
123     /// Wait that device finishes all operations in progress
124     void waitIdle();
125 
126     Queue getQueue(uint queueFamilyIndex, uint queueIndex);
127 
128     CommandPool createCommandPool(uint queueFamilyIndex);
129 
130     DeviceMemory allocateMemory(uint memPropIndex, size_t size);
131     void flushMappedMemory(MappedMemorySet set);
132     void invalidateMappedMemory(MappedMemorySet set);
133 
134     Buffer createBuffer(BufferUsage usage, size_t size);
135 
136     Image createImage(ImageType type, ImageDims dims, Format format,
137                       ImageUsage usage, uint samples, uint levels=1);
138 
139     Sampler createSampler(in SamplerInfo info);
140 
141     Semaphore createSemaphore();
142     Fence createFence(Flag!"signaled" signaled);
143     void resetFences(Fence[] fences);
144     void waitForFences(Fence[] fences, Flag!"waitAll" waitAll, Duration timeout);
145 
146     Swapchain createSwapchain(Surface surface, PresentMode pm, uint numImages,
147                               Format format, uint[2] size, ImageUsage usage,
148                               CompositeAlpha alpha, Swapchain former=null);
149 
150     RenderPass createRenderPass(in AttachmentDescription[] attachments,
151                                 in SubpassDescription[] subpasses,
152                                 in SubpassDependency[] dependencies);
153 
154     Framebuffer createFramebuffer(RenderPass rp, ImageView[] attachments,
155                                   uint width, uint height, uint layers);
156 
157     ShaderModule createShaderModule(ShaderLanguage language, string code, string entryPoint);
158 
159     PipelineLayout createPipelineLayout();
160 
161     Pipeline[] createPipelines(PipelineInfo[] infos);
162 }