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