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 size_t linearOptimalGranularity=1; 38 } 39 40 enum DeviceType { 41 other, 42 integratedGpu, 43 discreteGpu, 44 virtualGpu, 45 cpu 46 } 47 48 /// A request for a queue family and each queue to be created within that family. 49 /// The amount of queue to be created is given by priorities.length. 50 /// Priorities represent the relative priority to be given to each queue (from 0 to 1) 51 struct QueueRequest 52 { 53 uint familyIndex; 54 float[] priorities; 55 } 56 57 /// Represent a physical device. This interface is meant to describe a graphics 58 /// device and open a logical device out of it. 59 interface PhysicalDevice 60 { 61 import gfx.graal : Instance; 62 63 /// The instance this physical device is issued from 64 @property Instance instance(); 65 @property string name(); 66 67 @property DeviceType type(); 68 final @property bool softwareRendering() { 69 return type == DeviceType.cpu; 70 } 71 72 @property DeviceFeatures features(); 73 74 @property DeviceLimits limits(); 75 76 @property MemoryProperties memoryProperties(); 77 78 /// Get the queue families for the device 79 /// See_Also: QueueFamily 80 @property QueueFamily[] queueFamilies(); 81 82 /// Get the features supported for the given format 83 FormatProperties formatProperties(in Format format); 84 85 /// Check whether the given queue family supports presentation on the 86 /// give surface. 87 bool supportsSurface(uint queueFamilyIndex, Surface surface); 88 89 /// Get the capabilities of surface on this device. 90 SurfaceCaps surfaceCaps(Surface surface); 91 92 /// Get the formats supported by the given surface. 93 /// Params: 94 /// surface = the Surface to query the formats from 95 /// Returns: the formats supported by the surface. `[ Formats.undefined ]` 96 /// can be returned to indicate that any format is supported. 97 Format[] surfaceFormats(Surface surface); 98 99 /// Get the present mode supported by the given surface. 100 PresentMode[] surfacePresentModes(Surface surface); 101 102 /// Open a logical device with the specified queues. 103 /// Returns: null if it can't meet all requested queues, the opened device otherwise. 104 Device open(in QueueRequest[] queues, in DeviceFeatures features=DeviceFeatures.all) 105 in { 106 assert(queues.isConsistentWith(queueFamilies)); 107 } 108 } 109 110 /// Checks that the requests are consistent with families 111 private bool isConsistentWith(in QueueRequest[] requests, in QueueFamily[] families) 112 { 113 // TODO 114 return true; 115 } 116 117 struct MappedMemorySet 118 { 119 package(gfx) static struct MM { 120 DeviceMemory dm; 121 size_t offset; 122 size_t size; 123 } 124 125 package(gfx) void addMM(MM mm) { 126 mms ~= mm; 127 } 128 129 package(gfx) MM[] mms; 130 } 131 132 /// Handle to a logical device 133 interface Device : IAtomicRefCounted 134 { 135 import gfx.graal : Instance; 136 137 @property PhysicalDevice physicalDevice(); 138 @property Instance instance(); 139 140 /// Wait that device finishes all operations in progress 141 void waitIdle(); 142 143 Queue getQueue(uint queueFamilyIndex, uint queueIndex); 144 145 CommandPool createCommandPool(uint queueFamilyIndex); 146 147 DeviceMemory allocateMemory(uint memPropIndex, size_t size) 148 in { 149 assert(size > 0, "cannot allocate memory of null size"); 150 } 151 void flushMappedMemory(MappedMemorySet set); 152 void invalidateMappedMemory(MappedMemorySet set); 153 154 Buffer createBuffer(BufferUsage usage, size_t size) 155 in { 156 assert(size > 0, "cannot create a buffer of null size"); 157 } 158 159 Image createImage(in ImageInfo info); 160 161 Sampler createSampler(in SamplerInfo info); 162 163 Semaphore createSemaphore(); 164 Fence createFence(Flag!"signaled" signaled); 165 void resetFences(Fence[] fences); 166 void waitForFences(Fence[] fences, Flag!"waitAll" waitAll, Duration timeout); 167 168 Swapchain createSwapchain(Surface surface, PresentMode pm, uint numImages, 169 Format format, uint[2] size, ImageUsage usage, 170 CompositeAlpha alpha, Swapchain former=null); 171 172 RenderPass createRenderPass(in AttachmentDescription[] attachments, 173 in SubpassDescription[] subpasses, 174 in SubpassDependency[] dependencies); 175 176 Framebuffer createFramebuffer(RenderPass rp, ImageView[] attachments, 177 uint width, uint height, uint layers); 178 179 ShaderModule createShaderModule(const(uint)[] spirV, string entryPoint); 180 181 DescriptorSetLayout createDescriptorSetLayout(in PipelineLayoutBinding[] bindings); 182 183 PipelineLayout createPipelineLayout(DescriptorSetLayout[] layouts, in PushConstantRange[] ranges); 184 185 DescriptorPool createDescriptorPool(in uint maxSets, in DescriptorPoolSize[] sizes); 186 187 void updateDescriptorSets(WriteDescriptorSet[] writeOps, CopyDescritporSet[] copyOps); 188 189 Pipeline[] createPipelines(PipelineInfo[] infos); 190 }