From 03da52cff839a47d811c66c996d4e36a1dd0f953 Mon Sep 17 00:00:00 2001 From: Raph Levien Date: Tue, 19 May 2020 08:21:09 -0700 Subject: [PATCH] Start implementing fills This should get the "right_edge" value for each segment plumbed through to the binning phase. It also needs to be plumbed to coarse raster and wired up there. Also considering WIP because none of this logic has been tested yet. --- piet-gpu-types/src/state.rs | 1 + piet-gpu/shader/binning.comp | 52 ++++++++++++++++++++++++++++++++-- piet-gpu/shader/binning.spv | Bin 16812 -> 21800 bytes piet-gpu/shader/elements.comp | 10 +++++-- piet-gpu/shader/elements.spv | Bin 43780 -> 45068 bytes piet-gpu/shader/setup.h | 5 ++++ piet-gpu/shader/state.h | 10 +++++-- piet-gpu/src/lib.rs | 4 +-- 8 files changed, 73 insertions(+), 9 deletions(-) diff --git a/piet-gpu-types/src/state.rs b/piet-gpu-types/src/state.rs index 35076f0..b93e9f3 100644 --- a/piet-gpu-types/src/state.rs +++ b/piet-gpu-types/src/state.rs @@ -8,6 +8,7 @@ piet_gpu! { translate: [f32; 2], bbox: [f32; 4], linewidth: f32, + right_edge: f32, flags: u32, } } diff --git a/piet-gpu/shader/binning.comp b/piet-gpu/shader/binning.comp index c3067e7..cba0217 100644 --- a/piet-gpu/shader/binning.comp +++ b/piet-gpu/shader/binning.comp @@ -11,24 +11,33 @@ layout(set = 0, binding = 0) buffer AnnotatedBuf { uint[] annotated; }; -layout(set = 0, binding = 1) buffer AllocBuf { +// This is for scanning forward for right_edge data. +layout(set = 0, binding = 1) buffer StateBuf { + uint[] state; +}; + +layout(set = 0, binding = 2) buffer AllocBuf { uint n_elements; // Will be incremented atomically to claim tiles uint tile_ix; uint alloc; }; -layout(set = 0, binding = 2) buffer BinsBuf { +layout(set = 0, binding = 3) buffer BinsBuf { uint[] bins; }; #include "annotated.h" +#include "state.h" #include "bins.h" // scale factors useful for converting coordinates to bins #define SX (1.0 / float(N_TILE_X * TILE_WIDTH_PX)) #define SY (1.0 / float(N_TILE_Y * TILE_HEIGHT_PX)) +// Constant not available in GLSL. Also consider uintBitsToFloat(0x7f800000) +#define INFINITY (1.0 / 0.0) + // Note: cudaraster has N_TILE + 1 to cut down on bank conflicts. shared uint bitmaps[N_SLICE][N_TILE]; shared uint count[N_SLICE][N_TILE]; @@ -37,6 +46,14 @@ shared uint sh_chunk_start[N_TILE]; shared uint sh_chunk_end[N_TILE]; shared uint sh_chunk_jump[N_TILE]; +shared float sh_right_edge[N_TILE]; + +#define StateBuf_stride (4 + 2 * State_size) + +StateRef state_aggregate_ref(uint partition_ix) { + return StateRef(8 + partition_ix * StateBuf_stride); +} + void main() { BinChunkRef chunk_ref = BinChunkRef((gl_LocalInvocationID.x * N_WG + gl_WorkGroupID.x) * BIN_INITIAL_ALLOC); uint wr_limit = chunk_ref.offset + BIN_INITIAL_ALLOC; @@ -65,6 +82,7 @@ void main() { tag = Annotated_tag(ref); } int x0 = 0, y0 = 0, x1 = 0, y1 = 0; + float my_right_edge = INFINITY; switch (tag) { case Annotated_Line: AnnoLineSeg line = Annotated_Line_read(ref); @@ -82,8 +100,37 @@ void main() { y0 = int(floor(fill.bbox.y * SY)); x1 = int(ceil(fill.bbox.z * SX)); y1 = int(ceil(fill.bbox.w * SY)); + my_right_edge = x1; break; } + + // If the last element in this partition is a fill edge, then we need to do a + // look-forward to find the right edge of its corresponding fill. That data is + // recorded in aggregates computed in the element processing pass. + if (gl_LocalInvocationID.x == N_TILE - 1 && tag == Annotated_Line) { + uint aggregate_ix = (my_tile + 1) * ELEMENT_BINNING_RATIO; + // This is sequential but the expectation is that the amount of + // look-forward is small (performance may degrade in the case + // of massively complex paths). + do { + StateRef agg_ref = state_aggregate_ref(aggregate_ix); + my_right_edge = State_read(agg_ref).right_edge; + aggregate_ix++; + } while (isinf(my_right_edge)); + } + + // Now propagate right_edge backward, from fill to segment. + for (uint i = 0; i < LG_N_TILE; i++) { + // Note: we could try to cut down on write bandwidth here if the value hasn't + // changed, but not sure it's worth the complexity to track. + sh_right_edge[gl_LocalInvocationID.x] = my_right_edge; + barrier(); + if (gl_LocalInvocationID.x + (1 << i) < N_TILE && isinf(my_right_edge)) { + my_right_edge = sh_right_edge[gl_LocalInvocationID.x + (1 << i)]; + } + barrier(); + } + // At this point, we run an iterator over the coverage area, // trying to keep divergence low. // Right now, it's just a bbox, but we'll get finer with @@ -141,6 +188,7 @@ void main() { chunk_n = element_count - chunk_n; } else { chunk_end = ~0; + chunk_new_start = ~0; chunk_n = element_count; } sh_chunk_start[gl_LocalInvocationID.x] = instance_ref.offset; diff --git a/piet-gpu/shader/binning.spv b/piet-gpu/shader/binning.spv index 76148c2c44d71cb55a0d2ef55715d2d6f77ee77c..a5379e6dad7ab1566cc2378b2fa9ed054c62b1a3 100644 GIT binary patch literal 21800 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 literal 16812 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 diff --git a/piet-gpu/shader/elements.comp b/piet-gpu/shader/elements.comp index 8f87b87..15ad80d 100644 --- a/piet-gpu/shader/elements.comp +++ b/piet-gpu/shader/elements.comp @@ -10,7 +10,7 @@ #define N_ROWS 4 #define WG_SIZE 32 #define LG_WG_SIZE 5 -#define TILE_SIZE (WG_SIZE * N_ROWS) +#define PARTITION_SIZE (WG_SIZE * N_ROWS) layout(local_size_x = WG_SIZE, local_size_y = 1) in; @@ -81,6 +81,7 @@ State combine_state(State a, State b) { c.translate.x = a.mat.x * b.translate.x + a.mat.z * b.translate.y + a.translate.x; c.translate.y = a.mat.y * b.translate.x + a.mat.w * b.translate.y + a.translate.y; c.linewidth = (b.flags & FLAG_SET_LINEWIDTH) == 0 ? a.linewidth : b.linewidth; + c.right_edge = (a.flags & FLAG_SET_BBOX) != 0 ? a.right_edge : (a.flags & FLAG_RESET_BBOX) != 0 ? a.bbox.z : c.right_edge; c.flags = (a.flags & (FLAG_SET_LINEWIDTH | FLAG_SET_BBOX)) | b.flags; c.flags |= (a.flags & FLAG_RESET_BBOX) >> 1; return c; @@ -143,6 +144,7 @@ shared vec4 sh_mat[WG_SIZE]; shared vec2 sh_translate[WG_SIZE]; shared vec4 sh_bbox[WG_SIZE]; shared float sh_width[WG_SIZE]; +shared float sh_right_edge[WG_SIZE]; shared uint sh_flags[WG_SIZE]; shared uint sh_tile_ix; @@ -158,7 +160,7 @@ void main() { barrier(); uint tile_ix = sh_tile_ix; - uint ix = tile_ix * TILE_SIZE + gl_LocalInvocationID.x * N_ROWS; + uint ix = tile_ix * PARTITION_SIZE + gl_LocalInvocationID.x * N_ROWS; ElementRef ref = ElementRef(ix * Element_size); th_state[0] = map_element(ref); @@ -172,6 +174,7 @@ void main() { sh_translate[gl_LocalInvocationID.x] = agg.translate; sh_bbox[gl_LocalInvocationID.x] = agg.bbox; sh_width[gl_LocalInvocationID.x] = agg.linewidth; + sh_right_edge[gl_LocalInvocationID.x] = agg.right_edge; sh_flags[gl_LocalInvocationID.x] = agg.flags; for (uint i = 0; i < LG_WG_SIZE; i++) { barrier(); @@ -190,6 +193,7 @@ void main() { sh_translate[gl_LocalInvocationID.x] = agg.translate; sh_bbox[gl_LocalInvocationID.x] = agg.bbox; sh_width[gl_LocalInvocationID.x] = agg.linewidth; + sh_right_edge[gl_LocalInvocationID.x] = agg.right_edge; sh_flags[gl_LocalInvocationID.x] = agg.flags; } @@ -198,6 +202,7 @@ void main() { exclusive.mat = vec4(1.0, 0.0, 0.0, 1.0); exclusive.translate = vec2(0.0, 0.0); exclusive.linewidth = 1.0; //TODO should be 0.0 + exclusive.right_edge = 0.0; exclusive.flags = 0; // Publish aggregate for this partition @@ -250,6 +255,7 @@ void main() { other.translate = sh_translate[ix]; other.bbox = sh_bbox[ix]; other.linewidth = sh_width[ix]; + other.right_edge = sh_right_edge[ix]; other.flags = sh_flags[ix]; row = combine_state(row, other); } diff --git a/piet-gpu/shader/elements.spv b/piet-gpu/shader/elements.spv index 7828aa4732cc2ea3c5291afc93f45b4af815d3c3..ff0ae2d456ea352ee946cbe946a3e9b56ffc4853 100644 GIT binary patch literal 45068 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 O*%GYo{9Hr1YxqAgC=VY1 diff --git a/piet-gpu/shader/setup.h b/piet-gpu/shader/setup.h index 5d8fb9b..6b00661 100644 --- a/piet-gpu/shader/setup.h +++ b/piet-gpu/shader/setup.h @@ -51,9 +51,14 @@ #define N_TILE_X 16 #define N_TILE_Y 16 #define N_TILE (N_TILE_X * N_TILE_Y) +#define LG_N_TILE 8 #define N_SLICE (N_TILE / 32) // Number of workgroups for binning kernel #define N_WG 16 +// This is the ratio of the number of elements in a binning workgroup +// over the number of elements in a partition workgroup. +#define ELEMENT_BINNING_RATIO 4 + #define BIN_INITIAL_ALLOC 64 #define BIN_ALLOC 256 diff --git a/piet-gpu/shader/state.h b/piet-gpu/shader/state.h index 2547b93..bc6192f 100644 --- a/piet-gpu/shader/state.h +++ b/piet-gpu/shader/state.h @@ -9,10 +9,11 @@ struct State { vec2 translate; vec4 bbox; float linewidth; + float right_edge; uint flags; }; -#define State_size 48 +#define State_size 52 StateRef State_index(StateRef ref, uint index) { return StateRef(ref.offset + index * State_size); @@ -32,12 +33,14 @@ State State_read(StateRef ref) { uint raw9 = state[ix + 9]; uint raw10 = state[ix + 10]; uint raw11 = state[ix + 11]; + uint raw12 = state[ix + 12]; State s; s.mat = vec4(uintBitsToFloat(raw0), uintBitsToFloat(raw1), uintBitsToFloat(raw2), uintBitsToFloat(raw3)); s.translate = vec2(uintBitsToFloat(raw4), uintBitsToFloat(raw5)); s.bbox = vec4(uintBitsToFloat(raw6), uintBitsToFloat(raw7), uintBitsToFloat(raw8), uintBitsToFloat(raw9)); s.linewidth = uintBitsToFloat(raw10); - s.flags = raw11; + s.right_edge = uintBitsToFloat(raw11); + s.flags = raw12; return s; } @@ -54,6 +57,7 @@ void State_write(StateRef ref, State s) { state[ix + 8] = floatBitsToUint(s.bbox.z); state[ix + 9] = floatBitsToUint(s.bbox.w); state[ix + 10] = floatBitsToUint(s.linewidth); - state[ix + 11] = s.flags; + state[ix + 11] = floatBitsToUint(s.right_edge); + state[ix + 12] = s.flags; } diff --git a/piet-gpu/src/lib.rs b/piet-gpu/src/lib.rs index 2dca39d..70b02f5 100644 --- a/piet-gpu/src/lib.rs +++ b/piet-gpu/src/lib.rs @@ -185,10 +185,10 @@ impl Renderer { ]) ?; let bin_code = include_bytes!("../shader/binning.spv"); - let bin_pipeline = device.create_simple_compute_pipeline(bin_code, 3, 0)?; + let bin_pipeline = device.create_simple_compute_pipeline(bin_code, 4, 0)?; let bin_ds = device.create_descriptor_set( &bin_pipeline, - &[&anno_buf, &bin_alloc_buf_dev, &bin_buf], + &[&anno_buf, &state_buf, &bin_alloc_buf_dev, &bin_buf], &[], )?;