[WHLSL] Implement texture types
[WebKit-https.git] / Tools / WebGPUShadingLanguageRI / Texture.js
1 /*
2  * Copyright (C) 2018 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 "use strict";
26
27 class Texture {
28     constructor(dimension, width, height, depth, levelCount, layerCount, innerType, data)
29     {
30         this._dimension = dimension;
31         this._width = width;
32         this._height = height;
33         this._depth = depth;
34         this._levelCount = levelCount;
35         this._layerCount = layerCount;
36         this._innerType = innerType;
37         this._data = data;
38     }
39
40     get dimension() { return this._dimension; }
41     get width() { return this._width; }
42     get height() { return this._height; }
43     get depth() { return this._depth; }
44     get levelCount() { return this._levelCount; }
45     get layerCount() { return this._layerCount; }
46     get innerType() { return this._innerType; }
47     get data() { return this._data; }
48
49     elementChecked(layer, level, k, j, i)
50     {
51         if (layer < 0 || layer >= this.layerCount
52             || level < 0 || level >= this.levelCount
53             || k < 0 || k >= this.depth
54             || j < 0 || j >= this.height
55             || i < 0 || i >= this.width)
56             return undefined;
57         return this.element(layer, level, k, j, i);
58     }
59
60     setElementChecked(layer, level, k, j, i, value)
61     {
62         if (layer < 0 || layer >= this.layerCount
63             || level < 0 || level >= this.levelCount
64             || k < 0 || k >= this.depth
65             || j < 0 || j >= this.height
66             || i < 0 || i >= this.width)
67             return false;
68         this.setElement(layer, level, k, j, i, value);
69         return true;
70     }
71 }
72
73 class Texture1D extends Texture {
74     constructor(innerType, data)
75     {
76         // "data" is an array of mipmaps.
77         // The first mipmap is an array of elements.
78         // Each element may be a scalar or an array of 2-4 scalars.
79         // The width must be a power-of-two.
80         // Each mipmap is half-size of the previous size.
81
82         let dimension = 1;
83         let width = data[0].length;
84         let height = 1;
85         let depth = 1;
86         let levelCount = data.length;
87         let layerCount = 1;
88         super(dimension, width, height, depth, levelCount, layerCount, innerType, data);
89     }
90
91     widthAtLevel(level)
92     {
93         return this.data[level].length;
94     }
95
96     heightAtLevel(level)
97     {
98         return 1;
99     }
100
101     depthAtLevel(level)
102     {
103         return 1;
104     }
105
106     element(layer, level, k, j, i)
107     {
108         return this.data[level][i];
109     }
110
111     setElement(layer, level, k, j, i, value)
112     {
113         this.data[level][i] = value;
114     }
115 }
116
117 class Texture1DArray extends Texture {
118     constructor(innerType, data)
119     {
120         // "data" is an array of 1D textures.
121         // All textures must have the same width and number of mipmaps.
122
123         let dimension = 1;
124         let width = data[0][0].length;
125         let height = 1;
126         let depth = 1;
127         let levelCount = data[0].length;
128         let layerCount = data.length;
129         super(dimension, width, height, depth, levelCount, layerCount, innerType, data);
130     }
131
132     widthAtLevel(level)
133     {
134         return this.data[0][level].length;
135     }
136
137     heightAtLevel(level)
138     {
139         return 1;
140     }
141
142     depthAtLevel(level)
143     {
144         return 1;
145     }
146
147     element(layer, level, k, j, i)
148     {
149         return this.data[layer][level][i];
150     }
151
152     setElement(layer, level, k, j, i, value)
153     {
154         this.data[layer][level][i] = value;
155     }
156 }
157
158 class Texture2D extends Texture {
159     constructor(innerType, data)
160     {
161         // "data" is an array of mipmaps.
162         // The first mipmap is a rectangular array of rows, where each row is an array of elements.
163         // Each element may be a scalar or an array of 2-4 scalars.
164         // The width and height must be powers-of-two.
165         // Each mipmap is half-width and half-height of the previous size.
166
167         let dimension = 2;
168         let width = data[0][0].length;
169         let height = data[0].length;
170         let depth = 1;
171         let levelCount = data.length;
172         let layerCount = 1;
173         super(dimension, width, height, depth, levelCount, layerCount, innerType, data);
174     }
175
176     widthAtLevel(level)
177     {
178         return this.data[level][0].length;
179     }
180
181     heightAtLevel(level)
182     {
183         return this.data[level].length;
184     }
185
186     depthAtLevel(level)
187     {
188         return 1;
189     }
190
191     element(layer, level, k, j, i)
192     {
193         return this.data[level][j][i];
194     }
195
196     setElement(layer, level, k, j, i, value)
197     {
198         this.data[level][j][i] = value;
199     }
200 }
201
202 let TextureDepth2D = Texture2D;
203
204 class Texture2DArray extends Texture {
205     constructor(innerType, data)
206     {
207         // "data" is an array of 2D textures.
208         // All textures must have the same width, height and number of mipmaps.
209
210         let dimension = 2;
211         let width = data[0][0][0].length;
212         let height = data[0][0].length;
213         let depth = 1;
214         let levelCount = data[0].length;
215         let layerCount = data.length;
216         super(dimension, width, height, depth, levelCount, layerCount, innerType, data);
217     }
218
219     widthAtLevel(level)
220     {
221         return this.data[0][level][0].length;
222     }
223
224     heightAtLevel(level)
225     {
226         return this.data[0][level].length;
227     }
228
229     depthAtLevel(level)
230     {
231         return 1;
232     }
233
234     element(layer, level, k, j, i)
235     {
236         return this.data[layer][level][j][i];
237     }
238
239     setElement(layer, level, k, j, i, value)
240     {
241         this.data[layer][level][j][i] = value;
242     }
243 }
244
245 let TextureDepth2DArray = Texture2DArray;
246
247 class Texture3D extends Texture {
248     constructor(innerType, data)
249     {
250         // "data" is an array of mipmaps.
251         // The first mipmap is an array of depth slices, each depth slice is an array of rows, and each row is an array of elements.
252         // Each element may be a scalar or an array of 2-4 scalars.
253         // The width, height, and depth must be powers-of-two.
254         // Each mipmap is half-width, half-height, and half-depth of the previous size.
255
256         let dimension = 3;
257         let width = data[0][0][0].length;
258         let height = data[0][0].length;
259         let depth = data[0].length;
260         let levelCount = data.length;
261         let layerCount = 1;
262         super(dimension, width, height, depth, levelCount, layerCount, innerType, data);
263     }
264
265     widthAtLevel(level)
266     {
267         return this.data[level][0][0].length;
268     }
269
270     heightAtLevel(level)
271     {
272         return this.data[level][0].length;
273     }
274
275     depthAtLevel(level)
276     {
277         return this.data[level].length;
278     }
279
280     element(layer, level, k, j, i)
281     {
282         return this.data[level][k][j][i];
283     }
284
285     setElement(layer, level, k, j, i, value)
286     {
287         this.data[level][k][j][i] = value;
288     }
289 }
290
291 class TextureCube extends Texture {
292     constructor(innerType, data)
293     {
294         // "data" is an array of 6 2D textures.
295         // All textures must have the same width, height, depth, and number of mipmaps.
296
297         let dimension = 2;
298         let width = data[0][0][0].length;
299         let height = data[0][0].length;
300         let depth = 1;
301         let levelCount = data[0].length;
302         let layerCount = data.length;
303         super(dimension, width, height, depth, levelCount, layerCount, innerType, data);
304     }
305
306     widthAtLevel(level)
307     {
308         return this.data[0][level][0].length;
309     }
310
311     heightAtLevel(level)
312     {
313         return this.data[0][level].length;
314     }
315
316     depthAtLevel(level)
317     {
318         return 1;
319     }
320
321     element(layer, level, k, j, i)
322     {
323         return this.data[layer][level][j][i];
324     }
325
326     setElement(layer, level, k, j, i, value)
327     {
328         this.data[layer][level][j][i] = value;
329     }
330 }
331
332 let TextureDepthCube = TextureCube;
333
334 class Texture1DRW extends Texture {
335     constructor(innerType, data)
336     {
337         // "data" is an array of elements.
338         // Each element may be a scalar or an array of 2-4 scalars.
339         // The width must be a power-of-two.
340
341         let dimension = 1;
342         let width = data.length;
343         let height = 1;
344         let depth = 1;
345         let levelCount = 1;
346         let layerCount = 1;
347         super(dimension, width, height, depth, levelCount, layerCount, innerType, data);
348     }
349
350     widthAtLevel(level)
351     {
352         return this.data.length;
353     }
354
355     heightAtLevel(level)
356     {
357         return 1;
358     }
359
360     depthAtLevel(level)
361     {
362         return 1;
363     }
364
365     element(layer, level, k, j, i)
366     {
367         return this.data[i];
368     }
369
370     setElement(layer, level, k, j, i, value)
371     {
372         this.data[i] = value;
373     }
374 }
375
376 class Texture1DArrayRW extends Texture {
377     constructor(innerType, data)
378     {
379         // "data" is an array of 1D RW textures.
380         // All textures must have the same size.
381
382         let dimension = 1;
383         let width = data[0].length;
384         let height = 1;
385         let depth = 1;
386         let levelCount = 1;
387         let layerCount = data.length;
388         super(dimension, width, height, depth, levelCount, layerCount, innerType, data);
389     }
390
391     widthAtLevel(level)
392     {
393         return this.data[0].length;
394     }
395
396     heightAtLevel(level)
397     {
398         return 1;
399     }
400
401     depthAtLevel(level)
402     {
403         return 1;
404     }
405
406     element(layer, level, k, j, i)
407     {
408         return this.data[layer][i];
409     }
410
411     setElement(layer, level, k, j, i, value)
412     {
413         this.data[layer][i] = value;
414     }
415 }
416
417 class Texture2DRW extends Texture {
418     constructor(innerType, data)
419     {
420         // "data" is a rectangular array of rows, where each row is an array of elements.
421         // Each element may be a scalar or an array of 2-4 scalars.
422         // The width and height must be powers-of-two.
423
424         let dimension = 2;
425         let width = data[0].length;
426         let height = data.length;
427         let depth = 1;
428         let levelCount = 1;
429         let layerCount = 1;
430         super(dimension, width, height, depth, levelCount, layerCount, innerType, data);
431     }
432
433     widthAtLevel(level)
434     {
435         return this.data[0].length;
436     }
437
438     heightAtLevel(level)
439     {
440         return this.data.length;
441     }
442
443     depthAtLevel(level)
444     {
445         return 1;
446     }
447
448     element(layer, level, k, j, i)
449     {
450         return this.data[j][i];
451     }
452
453     setElement(layer, level, k, j, i, value)
454     {
455         this.data[j][i] = value;
456     }
457 }
458
459 let TextureDepth2DRW = Texture2DRW;
460
461 class Texture2DArrayRW extends Texture {
462     constructor(innerType, data)
463     {
464         // "data" is an array of 2D RW textures.
465         // All textures must have the same width and height.
466
467         let dimension = 2;
468         let width = data[0][0].length;
469         let height = data[0].length;
470         let depth = 1;
471         let levelCount = 1;
472         let layerCount = data.length;
473         super(dimension, width, height, depth, levelCount, layerCount, innerType, data);
474     }
475
476     widthAtLevel(level)
477     {
478         return this.data[0][0].length;
479     }
480
481     heightAtLevel(level)
482     {
483         return this.data[0].length;
484     }
485
486     depthAtLevel(level)
487     {
488         return 1;
489     }
490
491     element(layer, level, k, j, i)
492     {
493         return this.data[layer][j][i];
494     }
495
496     setElement(layer, level, k, j, i, value)
497     {
498         this.data[layer][j][i] = value;
499     }
500 }
501
502 let TextureDepth2DArrayRW = Texture2DArrayRW
503
504 class Texture3DRW extends Texture {
505     constructor(innerType, data)
506     {
507         // "data" is an array of depth slices, each depth slice is an array of rows, and each row is an array of elements.
508         // Each element may be a scalar or an array of 2-4 scalars.
509         // The width, height, and depth must be powers-of-two.
510
511         let dimension = 3;
512         let width = data[0][0].length;
513         let height = data[0].length;
514         let depth = data.length;
515         let levelCount = 1;
516         let layerCount = 1;
517         super(dimension, width, height, depth, levelCount, layerCount, innerType, data);
518     }
519
520     widthAtLevel(level)
521     {
522         return this.data[0][0].length;
523     }
524
525     heightAtLevel(level)
526     {
527         return this.data[0].length;
528     }
529
530     depthAtLevel(level)
531     {
532         return this.data.length;
533     }
534
535     element(layer, level, k, j, i)
536     {
537         return this.data[k][j][i];
538     }
539
540     setElement(layer, level, k, j, i, value)
541     {
542         this.data[k][j][i] = value;
543     }
544 }