1 /// Image module 2 module gfx.graal.image; 3 4 import gfx.core.rc; 5 import gfx.core.typecons; 6 import gfx.graal.format; 7 import gfx.graal.memory; 8 import gfx.graal.pipeline : CompareOp; 9 10 import std.typecons : Flag; 11 12 enum ImageType { 13 d1, d1Array, 14 d2, d2Array, 15 d3, cube, cubeArray 16 } 17 18 bool isCube(in ImageType it) { 19 return it == ImageType.cube || it == ImageType.cubeArray; 20 } 21 22 bool isArray(in ImageType it) { 23 return it == ImageType.d1Array || it == ImageType.d2Array || it == ImageType.cubeArray; 24 } 25 26 enum CubeFace { 27 none, 28 posX, negX, 29 posY, negY, 30 posZ, negZ, 31 } 32 33 /// an array of faces in the order that is expected during cube initialization 34 immutable cubeFaces = [ 35 CubeFace.posX, CubeFace.negX, 36 CubeFace.posY, CubeFace.negY, 37 CubeFace.posZ, CubeFace.negZ, 38 ]; 39 40 struct ImageDims 41 { 42 uint width; 43 uint height; 44 uint depth; 45 uint layers; 46 47 static ImageDims d1 (in uint width) { 48 return ImageDims(width, 1, 1, 1); 49 } 50 static ImageDims d2 (in uint width, in uint height) { 51 return ImageDims(width, height, 1, 1); 52 } 53 static ImageDims d3 (in uint width, in uint height, in uint depth) { 54 return ImageDims(width, height, depth, 1); 55 } 56 static ImageDims cube (in uint width, in uint height) { 57 return ImageDims(width, height, 6, 1); 58 } 59 static ImageDims d1Array (in uint width, in uint layers) { 60 return ImageDims(width, 1, 1, layers); 61 } 62 static ImageDims d2Array (in uint width, uint height, in uint layers) { 63 return ImageDims(width, height, 1, layers); 64 } 65 static ImageDims cubeArray (in uint width, in uint height, in uint layers) { 66 return ImageDims(width, height, 6, layers); 67 } 68 } 69 70 enum ImageUsage { 71 none = 0, 72 transferSrc = 0x01, 73 transferDst = 0x02, 74 sampled = 0x04, 75 storage = 0x08, 76 colorAttachment = 0x10, 77 depthStencilAttachment = 0x20, 78 transientAttachment = 0x40, 79 inputAttachment = 0x80, 80 } 81 82 enum ImageLayout { 83 undefined = 0, 84 general = 1, 85 colorAttachmentOptimal = 2, 86 depthStencilAttachmentOptimal = 3, 87 depthStencilReadOnlyOptimal = 4, 88 shaderReadOnlyOptimal = 5, 89 transferSrcOptimal = 6, 90 transferDstOptimal = 7, 91 preinitialized = 8, 92 presentSrc = 1000001002, // TODO impl actual mapping to vulkan 93 } 94 95 enum ImageAspect { 96 color = 0x01, 97 depth = 0x02, 98 stencil = 0x04, 99 depthStencil = depth | stencil, 100 } 101 102 103 struct ImageSubresourceRange 104 { 105 ImageAspect aspect; 106 size_t firstLevel; 107 size_t levels; 108 size_t firstLayer; 109 size_t layers; 110 } 111 112 enum CompSwizzle : ubyte 113 { 114 identity, 115 zero, one, 116 r, g, b, a, 117 } 118 119 alias Swizzle = CompSwizzle[4]; 120 121 interface Image 122 { 123 @property ImageType type(); 124 @property Format format(); 125 @property ImageDims dims(); 126 @property uint levels(); 127 128 // TODO: deduce view type from subrange and image type 129 ImageView createView(ImageType viewtype, ImageSubresourceRange isr, Swizzle swizzle); 130 } 131 132 interface ImageRc : Image, AtomicRefCounted 133 { 134 @property MemoryRequirements memoryRequirements(); 135 /// The image keeps a reference of the device memory 136 void bindMemory(DeviceMemory mem, in size_t offset); 137 } 138 139 interface ImageView : AtomicRefCounted 140 { 141 @property Image image(); 142 @property ImageSubresourceRange subresourceRange(); 143 @property Swizzle swizzle(); 144 } 145 146 147 enum Filter { 148 nearest, 149 linear, 150 } 151 152 153 /// Specifies how texture coordinates outside the range `[0, 1]` are handled. 154 enum WrapMode { 155 /// Repeat the texture. That is, sample the coordinate modulo `1.0`. 156 repeat, 157 /// Mirror the texture. Like tile, but uses abs(coord) before the modulo. 158 mirrorRepeat, 159 /// Clamp the texture to the value at `0.0` or `1.0` respectively. 160 clamp, 161 /// Use border color. 162 border, 163 } 164 165 enum BorderColor 166 { 167 floatTransparent, 168 intTransparent, 169 floatBlack, 170 intBlack, 171 floatWhite, 172 intWhite, 173 } 174 175 /// 176 struct SamplerInfo { 177 Filter minFilter; 178 Filter magFilter; 179 Filter mipmapFilter; 180 WrapMode[3] wrapMode; 181 Option!float anisotropy; 182 float lodBias; 183 float[2] lodRange; 184 Option!CompareOp compare; 185 BorderColor borderColor; 186 Flag!"unnormalizeCoords" unnormalizeCoords; 187 188 static @property SamplerInfo bilinear() { 189 SamplerInfo si; 190 si.minFilter = Filter.linear; 191 si.magFilter = Filter.linear; 192 return si; 193 } 194 195 static @property SamplerInfo trilinear() { 196 SamplerInfo si; 197 si.minFilter = Filter.linear; 198 si.magFilter = Filter.linear; 199 si.mipmapFilter = Filter.linear; 200 return si; 201 } 202 } 203 204 interface Sampler : AtomicRefCounted 205 {}