2020-12-12 01:01:48 +11:00
|
|
|
// SPDX-License-Identifier: Apache-2.0 OR MIT OR Unlicense
|
|
|
|
|
2020-06-03 10:10:20 +10:00
|
|
|
// Allocation and initialization of tiles for paths.
|
|
|
|
|
|
|
|
#version 450
|
|
|
|
#extension GL_GOOGLE_include_directive : enable
|
|
|
|
|
2020-12-12 04:30:20 +11:00
|
|
|
#include "mem.h"
|
2020-12-24 22:00:53 +11:00
|
|
|
#include "setup.h"
|
2020-06-03 10:10:20 +10:00
|
|
|
|
2020-09-13 20:58:47 +10:00
|
|
|
#define LG_TILE_ALLOC_WG (7 + LG_WG_FACTOR)
|
2020-06-04 06:04:52 +10:00
|
|
|
#define TILE_ALLOC_WG (1 << LG_TILE_ALLOC_WG)
|
2020-06-03 10:10:20 +10:00
|
|
|
|
|
|
|
layout(local_size_x = TILE_ALLOC_WG, local_size_y = 1) in;
|
|
|
|
|
2020-12-12 04:30:20 +11:00
|
|
|
layout(set = 0, binding = 1) readonly buffer ConfigBuf {
|
|
|
|
Config conf;
|
2020-06-03 10:10:20 +10:00
|
|
|
};
|
|
|
|
|
|
|
|
#include "annotated.h"
|
|
|
|
#include "tile.h"
|
|
|
|
|
|
|
|
// scale factors useful for converting coordinates to tiles
|
|
|
|
#define SX (1.0 / float(TILE_WIDTH_PX))
|
|
|
|
#define SY (1.0 / float(TILE_HEIGHT_PX))
|
|
|
|
|
2020-06-04 06:04:52 +10:00
|
|
|
shared uint sh_tile_count[TILE_ALLOC_WG];
|
2020-12-24 22:00:53 +11:00
|
|
|
shared MallocResult sh_tile_alloc;
|
2020-06-04 06:04:52 +10:00
|
|
|
|
2020-06-03 10:10:20 +10:00
|
|
|
void main() {
|
2020-06-04 06:04:52 +10:00
|
|
|
uint th_ix = gl_LocalInvocationID.x;
|
2020-06-03 10:10:20 +10:00
|
|
|
uint element_ix = gl_GlobalInvocationID.x;
|
2020-12-24 22:00:53 +11:00
|
|
|
PathRef path_ref = PathRef(conf.tile_alloc.offset + element_ix * Path_size);
|
|
|
|
AnnotatedRef ref = AnnotatedRef(conf.anno_alloc.offset + element_ix * Annotated_size);
|
2020-06-03 10:10:20 +10:00
|
|
|
|
|
|
|
uint tag = Annotated_Nop;
|
2020-12-12 04:30:20 +11:00
|
|
|
if (element_ix < conf.n_elements) {
|
2021-03-17 20:51:38 +11:00
|
|
|
tag = Annotated_tag(conf.anno_alloc, ref).tag;
|
2020-06-03 10:10:20 +10:00
|
|
|
}
|
|
|
|
int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
|
|
|
|
switch (tag) {
|
2021-03-17 22:02:41 +11:00
|
|
|
case Annotated_Color:
|
2021-03-19 05:21:07 +11:00
|
|
|
case Annotated_Image:
|
2020-11-21 04:26:02 +11:00
|
|
|
case Annotated_BeginClip:
|
|
|
|
case Annotated_EndClip:
|
|
|
|
// Note: we take advantage of the fact that fills, strokes, and
|
|
|
|
// clips have compatible layout.
|
2021-03-19 05:21:07 +11:00
|
|
|
AnnoEndClip clip = Annotated_EndClip_read(conf.anno_alloc, ref);
|
2021-03-17 22:02:41 +11:00
|
|
|
x0 = int(floor(clip.bbox.x * SX));
|
|
|
|
y0 = int(floor(clip.bbox.y * SY));
|
|
|
|
x1 = int(ceil(clip.bbox.z * SX));
|
|
|
|
y1 = int(ceil(clip.bbox.w * SY));
|
2020-06-03 10:10:20 +10:00
|
|
|
break;
|
|
|
|
}
|
2020-12-18 10:55:21 +11:00
|
|
|
x0 = clamp(x0, 0, int(conf.width_in_tiles));
|
|
|
|
y0 = clamp(y0, 0, int(conf.height_in_tiles));
|
|
|
|
x1 = clamp(x1, 0, int(conf.width_in_tiles));
|
|
|
|
y1 = clamp(y1, 0, int(conf.height_in_tiles));
|
2020-06-03 10:10:20 +10:00
|
|
|
|
|
|
|
Path path;
|
|
|
|
path.bbox = uvec4(x0, y0, x1, y1);
|
2020-06-04 06:04:52 +10:00
|
|
|
uint tile_count = (x1 - x0) * (y1 - y0);
|
2020-11-21 04:26:02 +11:00
|
|
|
if (tag == Annotated_EndClip) {
|
|
|
|
// Don't actually allocate tiles for an end clip, but we do want
|
|
|
|
// the path structure (especially bbox) allocated for it.
|
|
|
|
tile_count = 0;
|
|
|
|
}
|
2020-06-04 06:04:52 +10:00
|
|
|
|
|
|
|
sh_tile_count[th_ix] = tile_count;
|
2020-12-24 22:00:53 +11:00
|
|
|
uint total_tile_count = tile_count;
|
2020-06-04 06:04:52 +10:00
|
|
|
// Prefix sum of sh_tile_count
|
|
|
|
for (uint i = 0; i < LG_TILE_ALLOC_WG; i++) {
|
|
|
|
barrier();
|
|
|
|
if (th_ix >= (1 << i)) {
|
2020-12-24 22:00:53 +11:00
|
|
|
total_tile_count += sh_tile_count[th_ix - (1 << i)];
|
2020-06-03 10:10:20 +10:00
|
|
|
}
|
2020-06-04 06:04:52 +10:00
|
|
|
barrier();
|
2020-12-24 22:00:53 +11:00
|
|
|
sh_tile_count[th_ix] = total_tile_count;
|
2020-06-04 06:04:52 +10:00
|
|
|
}
|
|
|
|
if (th_ix == TILE_ALLOC_WG - 1) {
|
2020-12-24 22:00:53 +11:00
|
|
|
sh_tile_alloc = malloc(total_tile_count * Tile_size);
|
2020-06-03 10:10:20 +10:00
|
|
|
}
|
2020-06-04 06:04:52 +10:00
|
|
|
barrier();
|
2020-12-24 22:00:53 +11:00
|
|
|
MallocResult alloc_start = sh_tile_alloc;
|
2021-04-12 22:41:03 +10:00
|
|
|
if (alloc_start.failed || mem_error != NO_ERROR) {
|
2020-12-12 04:30:20 +11:00
|
|
|
return;
|
|
|
|
}
|
2020-06-04 06:04:52 +10:00
|
|
|
|
2020-12-12 04:30:20 +11:00
|
|
|
if (element_ix < conf.n_elements) {
|
2020-06-05 08:58:38 +10:00
|
|
|
uint tile_subix = th_ix > 0 ? sh_tile_count[th_ix - 1] : 0;
|
2020-12-24 22:00:53 +11:00
|
|
|
Alloc tiles_alloc = slice_mem(alloc_start.alloc, Tile_size * tile_subix, Tile_size * tile_count);
|
|
|
|
path.tiles = TileRef(tiles_alloc.offset);
|
|
|
|
Path_write(conf.tile_alloc, path_ref, path);
|
2020-06-05 08:58:38 +10:00
|
|
|
}
|
2020-06-04 06:04:52 +10:00
|
|
|
|
|
|
|
// Zero out allocated tiles efficiently
|
|
|
|
uint total_count = sh_tile_count[TILE_ALLOC_WG - 1] * (Tile_size / 4);
|
2020-12-24 22:00:53 +11:00
|
|
|
uint start_ix = alloc_start.alloc.offset >> 2;
|
2020-06-04 06:04:52 +10:00
|
|
|
for (uint i = th_ix; i < total_count; i += TILE_ALLOC_WG) {
|
|
|
|
// Note: this interleaving is faster than using Tile_write
|
|
|
|
// by a significant amount.
|
2020-12-24 22:00:53 +11:00
|
|
|
write_mem(alloc_start.alloc, start_ix + i, 0);
|
2020-06-04 06:04:52 +10:00
|
|
|
}
|
2020-06-03 10:10:20 +10:00
|
|
|
}
|