1 module gfx.gl3.device; 2 3 package: 4 5 import gfx.graal.cmd : CommandPool; 6 import gfx.graal.device : Device; 7 import gfx.graal.sync : Fence, Semaphore; 8 9 class GlDevice : Device 10 { 11 import core.time : Duration; 12 import gfx.core.rc : atomicRcCode, Rc; 13 import gfx.gl3 : GlInstance, GlPhysicalDevice, GlShare; 14 import gfx.gl3.queue : GlQueue; 15 import gfx.graal : Instance; 16 import gfx.graal.buffer : Buffer, BufferUsage; 17 import gfx.graal.device : MappedMemorySet; 18 import gfx.graal.format : Format; 19 import gfx.graal.image : Image, ImageInfo, ImageUsage, ImageView, 20 Sampler, SamplerInfo; 21 import gfx.graal.memory : DeviceMemory, MemoryProperties; 22 import gfx.graal.presentation : CompositeAlpha, PresentMode, Surface, 23 Swapchain; 24 import gfx.graal.queue : Queue; 25 import gfx.graal.renderpass : AttachmentDescription, Framebuffer, 26 RenderPass, SubpassDependency, 27 SubpassDescription; 28 import gfx.graal.pipeline : CopyDescritporSet, DescriptorSet, 29 DescriptorSetLayout, DescriptorPool, 30 DescriptorPoolSize, Pipeline, PipelineInfo, 31 PipelineLayout, PipelineLayoutBinding, 32 PushConstantRange, ShaderModule, 33 WriteDescriptorSet; 34 import std.typecons : Flag; 35 36 mixin(atomicRcCode); 37 38 private GlPhysicalDevice _phd; 39 private Rc!Instance _inst; 40 private Rc!GlShare _share; 41 private MemoryProperties _memProps; 42 private GlQueue _queue; 43 44 45 this (GlPhysicalDevice phd, GlInstance inst) { 46 _phd = phd; 47 _inst = inst; 48 _share = inst.share; 49 _memProps = phd.memoryProperties; 50 _queue = new GlQueue(_share, this, 0); 51 } 52 53 override void dispose() { 54 _queue.dispose(); 55 _share.unload(); 56 _inst.unload(); 57 } 58 59 override GlPhysicalDevice physicalDevice() { 60 return _phd; 61 } 62 63 override Instance instance() { 64 return _inst; 65 } 66 67 override void waitIdle() {} 68 69 override Queue getQueue(uint queueFamilyIndex, uint queueIndex) { 70 return _queue; 71 } 72 73 CommandPool createCommandPool(uint queueFamilyIndex) { 74 import gfx.gl3.queue : GlCommandPool; 75 return new GlCommandPool(_queue); 76 } 77 78 DeviceMemory allocateMemory(uint memPropIndex, size_t size) { 79 import gfx.gl3.resource : GlDeviceMemory; 80 return new GlDeviceMemory(this, memPropIndex, _memProps.types[memPropIndex].props, size); 81 } 82 83 void flushMappedMemory(MappedMemorySet set) {} 84 void invalidateMappedMemory(MappedMemorySet set) {} 85 86 Buffer createBuffer(BufferUsage usage, size_t size) { 87 import gfx.gl3.resource : GlBuffer; 88 return new GlBuffer(this, _share, usage, size); 89 } 90 91 Image createImage(in ImageInfo info) { 92 import gfx.gl3.resource : GlImage; 93 return new GlImage(this, _share, info); 94 } 95 96 Sampler createSampler(in SamplerInfo info) { 97 import gfx.gl3.resource : GlSampler; 98 return new GlSampler(this, _share, info); 99 } 100 101 Semaphore createSemaphore() { 102 return new GlSemaphore(this); 103 } 104 105 Fence createFence(Flag!"signaled" signaled) { 106 return new GlFence(this, signaled); 107 } 108 109 void resetFences(Fence[] fences) {} 110 void waitForFences(Fence[] fences, Flag!"waitAll" waitAll, Duration timeout) {} 111 112 Swapchain createSwapchain(Surface surface, PresentMode pm, uint numImages, 113 Format format, uint[2] size, ImageUsage usage, 114 CompositeAlpha alpha, Swapchain former=null) { 115 import gfx.gl3.swapchain : GlSwapchain; 116 return new GlSwapchain(this, _share, surface, pm, numImages, format, size, usage, alpha, former); 117 } 118 119 RenderPass createRenderPass(in AttachmentDescription[] attachments, 120 in SubpassDescription[] subpasses, 121 in SubpassDependency[] dependencies) { 122 import gfx.gl3.pipeline : GlRenderPass; 123 return new GlRenderPass(this, attachments, subpasses, dependencies); 124 } 125 126 Framebuffer createFramebuffer(RenderPass rp, ImageView[] attachments, 127 uint width, uint height, uint layers) { 128 import gfx.gl3.pipeline : GlFramebuffer, GlRenderPass; 129 import gfx.gl3.resource : GlImageView; 130 import std.algorithm : map; 131 import std.array : array; 132 133 return new GlFramebuffer(_share, cast(GlRenderPass)rp, 134 attachments.map!(iv => cast(GlImageView)iv).array, 135 width, height, layers); 136 } 137 138 ShaderModule createShaderModule(const(uint)[] code, string entryPoint) { 139 import gfx.gl3.pipeline : GlShaderModule; 140 import std.exception : enforce; 141 142 enforce(entryPoint == "main"); 143 return new GlShaderModule(this, _share, code); 144 } 145 146 DescriptorSetLayout createDescriptorSetLayout(in PipelineLayoutBinding[] bindings) { 147 import gfx.gl3.pipeline : GlDescriptorSetLayout; 148 return new GlDescriptorSetLayout(this, bindings); 149 } 150 151 PipelineLayout createPipelineLayout(DescriptorSetLayout[] layouts, in PushConstantRange[] ranges) { 152 import gfx.gl3.pipeline : GlPipelineLayout; 153 return new GlPipelineLayout(this, layouts, ranges); 154 } 155 156 DescriptorPool createDescriptorPool(in uint maxSets, in DescriptorPoolSize[] sizes) { 157 import gfx.gl3.pipeline : GlDescriptorPool; 158 return new GlDescriptorPool(this, maxSets, sizes); 159 } 160 161 void updateDescriptorSets(WriteDescriptorSet[] writeOps, CopyDescritporSet[] copyOps) { 162 import gfx.gl3.pipeline : GlDescriptorSet; 163 foreach (wo; writeOps) { 164 auto glSet = cast(GlDescriptorSet)wo.dstSet; 165 glSet.write(wo.dstBinding, wo.dstArrayElem, wo.write); 166 } 167 } 168 169 Pipeline[] createPipelines(PipelineInfo[] infos) { 170 import gfx.gl3.pipeline : GlPipeline; 171 import std.algorithm : map; 172 import std.array : array; 173 return infos.map!(pi => cast(Pipeline)new GlPipeline(this, _share, pi)).array; 174 } 175 } 176 177 private final class GlSemaphore : Semaphore { 178 import gfx.core.rc : atomicRcCode, Rc; 179 mixin(atomicRcCode); 180 181 private Rc!GlDevice _dev; 182 183 this(GlDevice dev) { 184 _dev = dev; 185 } 186 override void dispose() { 187 _dev.unload(); 188 } 189 override @property GlDevice device() { 190 return _dev; 191 } 192 } 193 194 private final class GlFence : Fence { 195 import core.time : Duration; 196 import gfx.core.rc : atomicRcCode, Rc; 197 mixin(atomicRcCode); 198 199 private Rc!GlDevice _dev; 200 private bool _signaled; 201 202 this(GlDevice dev, bool signaled) { 203 _dev = dev; 204 _signaled = signaled; 205 } 206 override void dispose() { 207 _dev.unload(); 208 } 209 override @property GlDevice device() { 210 return _dev; 211 } 212 override @property bool signaled() { return _signaled; } 213 override void reset() {} 214 override void wait(Duration timeout) {} 215 } 216