diff --git a/piet-gpu-hal/src/vulkan.rs b/piet-gpu-hal/src/vulkan.rs index 2fac015..29d4fd3 100644 --- a/piet-gpu-hal/src/vulkan.rs +++ b/piet-gpu-hal/src/vulkan.rs @@ -1016,7 +1016,7 @@ unsafe fn choose_compute_device( devices: &[vk::PhysicalDevice], surface: Option<&VkSurface>, ) -> Option<(vk::PhysicalDevice, u32)> { - for pdevice in devices { + for pdevice in &devices[0..] { let props = instance.get_physical_device_queue_family_properties(*pdevice); for (ix, info) in props.iter().enumerate() { // Check for surface presentation support diff --git a/piet-gpu/shader/path_coarse.comp b/piet-gpu/shader/path_coarse.comp index 0b3bc8f..f587079 100644 --- a/piet-gpu/shader/path_coarse.comp +++ b/piet-gpu/shader/path_coarse.comp @@ -108,6 +108,12 @@ void main() { uint width = uint(x1 - x0); sh_width[th_ix] = width; uint draw_width = min(width, uint(1.0 + ceil(2.0 * c))); + if (draw_width == 0 && bbox.x == 0 && bbox.z > 0) { + // Create opportunity to draw backdrop for segments to the left of viewport. + // Note: predicate can be strengthened to exclude segments that don't cross + // a horizontal tile boundary. + draw_width = 1; + } sh_draw_width[th_ix] = draw_width; uint tile_count = draw_width * uint(y1 - y0); @@ -148,25 +154,24 @@ void main() { int xx0 = clamp(int(floor(t - c)), x0, x1); int xx1 = clamp(int(ceil(t + c)), x0, x1); int x = xx0 + dx; + vec2 tile_xy = vec2(x * TILE_WIDTH_PX, y * TILE_HEIGHT_PX); + vec2 p0 = sh_p0[el_ix]; + vec2 p1 = sh_p1[el_ix]; + uint tile_el = (sh_base[el_ix] + uint(y * sh_stride[el_ix] + x) * Tile_size) >> 2; + if (sh_tag[el_ix] == PathSeg_FillLine && dx == 0 && min(p0.y, p1.y) <= tile_xy.y) { + int xray = max(int(ceil(t - 0.5 * b)), x0); + if (xray < sh_bbox_x1[el_ix]) { + int backdrop = p1.y < p0.y ? 1 : -1; + atomicAdd(tile[tile_el + 1 + 2 * (xray - x)], backdrop); + } + } + if (x < xx1) { uint tile_offset = alloc_start + ix * TileSeg_size; - uint tile_el = (sh_base[el_ix] + uint(y * sh_stride[el_ix] + x) * Tile_size) >> 2; uint old = atomicExchange(tile[tile_el], tile_offset); TileSeg tile_seg; - vec2 p0 = sh_p0[el_ix]; - vec2 p1 = sh_p1[el_ix]; float y_edge = 0.0; if (sh_tag[el_ix] == PathSeg_FillLine) { - vec2 tile_xy = vec2(x * TILE_WIDTH_PX, y * TILE_HEIGHT_PX); - if (dx == 0 && min(p0.y, p1.y) <= tile_xy.y) { - // TODO: need a little more work to make sure this triggers even - // when line is to the left of bbox. - int xray = max(int(ceil(t - 0.5 * b)), x0); - if (xray < sh_bbox_x1[el_ix]) { - int backdrop = p1.y < p0.y ? 1 : -1; - atomicAdd(tile[tile_el + 1 + 2 * (xray - x)], backdrop); - } - } y_edge = mix(p0.y, p1.y, (tile_xy.x - p0.x) / (p1.x - p0.x)); if (min(p0.x, p1.x) < tile_xy.x && y_edge >= tile_xy.y && y_edge < tile_xy.y + TILE_HEIGHT_PX) { if (p0.x > p1.x) { diff --git a/piet-gpu/shader/path_coarse.spv b/piet-gpu/shader/path_coarse.spv index 8c4801b..a4db461 100644 Binary files a/piet-gpu/shader/path_coarse.spv and b/piet-gpu/shader/path_coarse.spv differ