diff --git a/Cargo.lock b/Cargo.lock index 8e28591d..d76f32b8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1788,8 +1788,10 @@ name = "pathfinder_gpu" version = "0.5.0" dependencies = [ "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "half 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "image 0.23.3 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "pathfinder_color 0.5.0", "pathfinder_geometry 0.5.1", "pathfinder_resources 0.5.0", @@ -1837,6 +1839,7 @@ dependencies = [ "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "cocoa 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)", "core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "dispatch 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "half 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "io-surface 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/renderer/src/gpu/debug.rs b/renderer/src/gpu/debug.rs index 1f85035a..ea7e9e31 100644 --- a/renderer/src/gpu/debug.rs +++ b/renderer/src/gpu/debug.rs @@ -15,10 +15,12 @@ //! //! The debug font atlas was generated using: https://evanw.github.io/font-texture-generator/ -use crate::gpu::renderer::{RenderStats, RenderTime}; -use pathfinder_geometry::vector::{Vector2I, vec2i}; +use crate::gpu::options::RendererLevel; +use crate::gpu::perf::{RenderStats, RenderTime}; use pathfinder_geometry::rect::RectI; +use pathfinder_geometry::vector::{Vector2I, vec2i}; use pathfinder_gpu::Device; +use pathfinder_gpu::allocator::GPUMemoryAllocator; use pathfinder_resources::ResourceLoader; use pathfinder_ui::{FONT_ASCENT, LINE_HEIGHT, PADDING, UIPresenter, WINDOW_COLOR}; use std::collections::VecDeque; @@ -27,35 +29,39 @@ use std::time::Duration; const SAMPLE_BUFFER_SIZE: usize = 60; -const STATS_WINDOW_WIDTH: i32 = 325; +const STATS_WINDOW_WIDTH: i32 = 275; const STATS_WINDOW_HEIGHT: i32 = LINE_HEIGHT * 4 + PADDING + 2; const PERFORMANCE_WINDOW_WIDTH: i32 = 400; -const PERFORMANCE_WINDOW_HEIGHT: i32 = LINE_HEIGHT * 4 + PADDING + 2; +const PERFORMANCE_WINDOW_HEIGHT_D3D9: i32 = LINE_HEIGHT * 8 + PADDING + 2; +const PERFORMANCE_WINDOW_HEIGHT_D3D11: i32 = LINE_HEIGHT * 10 + PADDING + 2; -pub struct DebugUIPresenter -where - D: Device, -{ +const INFO_WINDOW_WIDTH: i32 = 425; +const INFO_WINDOW_HEIGHT: i32 = LINE_HEIGHT * 2 + PADDING + 2; + +pub struct DebugUIPresenter where D: Device { pub ui_presenter: UIPresenter, cpu_samples: SampleBuffer, gpu_samples: SampleBuffer, + backend_name: &'static str, + device_name: String, + renderer_level: RendererLevel, } -impl DebugUIPresenter -where - D: Device, -{ - pub fn new( - device: &D, - resources: &dyn ResourceLoader, - framebuffer_size: Vector2I, - ) -> DebugUIPresenter { +impl DebugUIPresenter where D: Device { + pub fn new(device: &D, + resources: &dyn ResourceLoader, + framebuffer_size: Vector2I, + renderer_level: RendererLevel) + -> DebugUIPresenter { let ui_presenter = UIPresenter::new(device, resources, framebuffer_size); DebugUIPresenter { ui_presenter, cpu_samples: SampleBuffer::new(), gpu_samples: SampleBuffer::new(), + backend_name: device.backend_name(), + device_name: device.device_name(), + renderer_level, } } @@ -64,84 +70,222 @@ where self.gpu_samples.push(rendering_time); } - pub fn draw(&self, device: &D) { - self.draw_stats_window(device); - self.draw_performance_window(device); + pub fn draw(&self, device: &D, allocator: &mut GPUMemoryAllocator) { + self.draw_stats_window(device, allocator); + self.draw_performance_window(device, allocator); + self.draw_info_window(device, allocator); } - fn draw_stats_window(&self, device: &D) { + #[inline] + pub fn set_framebuffer_size(&mut self, new_framebuffer_size: Vector2I) { + self.ui_presenter.set_framebuffer_size(new_framebuffer_size) + } + + fn draw_info_window(&self, device: &D, allocator: &mut GPUMemoryAllocator) { + let framebuffer_size = self.ui_presenter.framebuffer_size(); + let bottom = framebuffer_size.y() - PADDING; + let window_rect = RectI::new( + vec2i(framebuffer_size.x() - PADDING - INFO_WINDOW_WIDTH, + bottom - INFO_WINDOW_HEIGHT), + vec2i(INFO_WINDOW_WIDTH, INFO_WINDOW_HEIGHT), + ); + + self.ui_presenter.draw_solid_rounded_rect(device, allocator, window_rect, WINDOW_COLOR); + + let origin = window_rect.origin() + vec2i(PADDING, PADDING + FONT_ASCENT); + let level = match self.renderer_level { + RendererLevel::D3D9 => "D3D9", + RendererLevel::D3D11 => "D3D11", + }; + self.ui_presenter.draw_text(device, + allocator, + &format!("{} ({} level)", self.backend_name, level), + origin + vec2i(0, LINE_HEIGHT * 0), + false); + self.ui_presenter.draw_text(device, + allocator, + &self.device_name, + origin + vec2i(0, LINE_HEIGHT * 1), + false); + + } + + fn performance_window_size(&self) -> Vector2I { + match self.renderer_level { + RendererLevel::D3D9 => vec2i(PERFORMANCE_WINDOW_WIDTH, PERFORMANCE_WINDOW_HEIGHT_D3D9), + RendererLevel::D3D11 => { + vec2i(PERFORMANCE_WINDOW_WIDTH, PERFORMANCE_WINDOW_HEIGHT_D3D11) + } + } + } + + fn draw_stats_window(&self, device: &D, allocator: &mut GPUMemoryAllocator) { + let performance_window_height = self.performance_window_size().y(); + let framebuffer_size = self.ui_presenter.framebuffer_size(); let bottom = framebuffer_size.y() - PADDING; let window_rect = RectI::new( vec2i(framebuffer_size.x() - PADDING - STATS_WINDOW_WIDTH, - bottom - PERFORMANCE_WINDOW_HEIGHT - PADDING - STATS_WINDOW_HEIGHT), - vec2i(STATS_WINDOW_WIDTH, STATS_WINDOW_HEIGHT), - ); + bottom - + PADDING - + INFO_WINDOW_HEIGHT - + performance_window_height - + PADDING - + STATS_WINDOW_HEIGHT), + vec2i(STATS_WINDOW_WIDTH, STATS_WINDOW_HEIGHT)); - self.ui_presenter.draw_solid_rounded_rect(device, window_rect, WINDOW_COLOR); + self.ui_presenter.draw_solid_rounded_rect(device, allocator, window_rect, WINDOW_COLOR); let mean_cpu_sample = self.cpu_samples.mean(); let origin = window_rect.origin() + vec2i(PADDING, PADDING + FONT_ASCENT); self.ui_presenter.draw_text( device, + allocator, &format!("Paths: {}", mean_cpu_sample.path_count), origin, false, ); self.ui_presenter.draw_text( device, - &format!("Solid Tiles: {}", mean_cpu_sample.solid_tile_count), + allocator, + &format!("Tiles: {}", mean_cpu_sample.total_tile_count), origin + vec2i(0, LINE_HEIGHT * 1), false, ); self.ui_presenter.draw_text( device, - &format!("Alpha Tiles: {}", mean_cpu_sample.alpha_tile_count), + allocator, + &format!("Masks: {}", mean_cpu_sample.alpha_tile_count), origin + vec2i(0, LINE_HEIGHT * 2), false, ); self.ui_presenter.draw_text( device, + allocator, &format!("Fills: {}", mean_cpu_sample.fill_count), origin + vec2i(0, LINE_HEIGHT * 3), false, ); } - fn draw_performance_window(&self, device: &D) { + fn draw_performance_window(&self, device: &D, allocator: &mut GPUMemoryAllocator) { + let performance_window_size = self.performance_window_size(); + let framebuffer_size = self.ui_presenter.framebuffer_size(); let bottom = framebuffer_size.y() - PADDING; let window_rect = RectI::new( - vec2i(framebuffer_size.x() - PADDING - PERFORMANCE_WINDOW_WIDTH, - bottom - PERFORMANCE_WINDOW_HEIGHT), - vec2i(PERFORMANCE_WINDOW_WIDTH, PERFORMANCE_WINDOW_HEIGHT), - ); + vec2i(framebuffer_size.x() - PADDING - performance_window_size.x(), + bottom - INFO_WINDOW_HEIGHT - PADDING - performance_window_size.y()), + performance_window_size); - self.ui_presenter.draw_solid_rounded_rect(device, window_rect, WINDOW_COLOR); + self.ui_presenter.draw_solid_rounded_rect(device, allocator, window_rect, WINDOW_COLOR); let mean_cpu_sample = self.cpu_samples.mean(); - let origin = window_rect.origin() + vec2i(PADDING, PADDING + FONT_ASCENT); - self.ui_presenter.draw_text( - device, - &format!("CPU: {:.3} ms", duration_to_ms(mean_cpu_sample.cpu_build_time)), - origin, - false, - ); - let mean_gpu_sample = self.gpu_samples.mean(); + let origin = window_rect.origin() + vec2i(PADDING, PADDING + FONT_ASCENT); + + let mut current_y = 0; self.ui_presenter.draw_text( device, - &format!("GPU: {:.3} ms", duration_to_ms(mean_gpu_sample.gpu_time)), - origin + vec2i(0, LINE_HEIGHT * 1), + allocator, + &format!("Drawcalls: {}", mean_cpu_sample.drawcall_count), + origin + vec2i(0, current_y), false, ); - - let wallclock_time = f64::max(duration_to_ms(mean_gpu_sample.gpu_time), - duration_to_ms(mean_cpu_sample.cpu_build_time)); + current_y += LINE_HEIGHT; self.ui_presenter.draw_text( device, + allocator, + &format!("VRAM Alloc.: {:.1} MB", + mean_cpu_sample.gpu_bytes_allocated as f64 / (1024.0 * 1024.0)), + origin + vec2i(0, current_y), + false, + ); + current_y += LINE_HEIGHT; + self.ui_presenter.draw_text( + device, + allocator, + &format!("VRAM Commit: {:.1} MB", + mean_cpu_sample.gpu_bytes_committed as f64 / (1024.0 * 1024.0)), + origin + vec2i(0, current_y), + false, + ); + current_y += LINE_HEIGHT; + + self.ui_presenter.draw_text( + device, + allocator, + &format!("CPU: {:.3} ms", duration_to_ms(mean_cpu_sample.cpu_build_time)), + origin + vec2i(0, current_y), + false, + ); + current_y += LINE_HEIGHT; + + match self.renderer_level { + RendererLevel::D3D11 => { + self.ui_presenter.draw_text( + device, + allocator, + &format!("GPU Dice: {:.3} ms", duration_to_ms(mean_gpu_sample.dice_time)), + origin + vec2i(0, current_y), + false, + ); + current_y += LINE_HEIGHT; + self.ui_presenter.draw_text( + device, + allocator, + &format!("GPU Bin: {:.3} ms", duration_to_ms(mean_gpu_sample.bin_time)), + origin + vec2i(0, current_y), + false, + ); + current_y += LINE_HEIGHT; + } + RendererLevel::D3D9 => {} + } + self.ui_presenter.draw_text( + device, + allocator, + &format!("GPU Fill: {:.3} ms", duration_to_ms(mean_gpu_sample.fill_time)), + origin + vec2i(0, current_y), + false, + ); + current_y += LINE_HEIGHT; + self.ui_presenter.draw_text( + device, + allocator, + &format!("GPU Comp.: {:.3} ms", duration_to_ms(mean_gpu_sample.composite_time)), + origin + vec2i(0, current_y), + false, + ); + current_y += LINE_HEIGHT; + self.ui_presenter.draw_text( + device, + allocator, + &format!("GPU Other: {:.3} ms", duration_to_ms(mean_gpu_sample.other_time)), + origin + vec2i(0, current_y), + false, + ); + current_y += LINE_HEIGHT; + + let mut wallclock_time = match self.renderer_level { + RendererLevel::D3D11 => { + duration_to_ms(mean_cpu_sample.cpu_build_time) + + duration_to_ms(mean_gpu_sample.fill_time) + } + RendererLevel::D3D9 => { + f64::max(duration_to_ms(mean_cpu_sample.cpu_build_time), + duration_to_ms(mean_gpu_sample.fill_time)) + } + }; + wallclock_time += duration_to_ms(mean_gpu_sample.composite_time) + + duration_to_ms(mean_gpu_sample.dice_time) + + duration_to_ms(mean_gpu_sample.bin_time) + + duration_to_ms(mean_gpu_sample.other_time); + self.ui_presenter.draw_text( + device, + allocator, &format!("Wallclock: {:.3} ms", wallclock_time), - origin + vec2i(0, LINE_HEIGHT * 3), + origin + vec2i(0, current_y), false, ); } diff --git a/resources/MANIFEST b/resources/MANIFEST index 85928b7a..40de1616 100644 --- a/resources/MANIFEST +++ b/resources/MANIFEST @@ -7,69 +7,88 @@ shaders/gl3/blit.fs.glsl shaders/gl3/blit.vs.glsl shaders/gl3/clear.fs.glsl shaders/gl3/clear.vs.glsl -shaders/gl3/debug_solid.fs.glsl -shaders/gl3/debug_solid.vs.glsl -shaders/gl3/debug_texture.fs.glsl -shaders/gl3/debug_texture.vs.glsl +shaders/gl3/d3d9/fill.fs.glsl +shaders/gl3/d3d9/fill.vs.glsl +shaders/gl3/d3d9/tile.fs.glsl +shaders/gl3/d3d9/tile.vs.glsl +shaders/gl3/d3d9/tile_clip_combine.fs.glsl +shaders/gl3/d3d9/tile_clip_combine.vs.glsl +shaders/gl3/d3d9/tile_clip_copy.fs.glsl +shaders/gl3/d3d9/tile_clip_copy.vs.glsl +shaders/gl3/d3d9/tile_copy.fs.glsl +shaders/gl3/d3d9/tile_copy.vs.glsl +shaders/gl3/debug/solid.fs.glsl +shaders/gl3/debug/solid.vs.glsl +shaders/gl3/debug/texture.fs.glsl +shaders/gl3/debug/texture.vs.glsl shaders/gl3/demo_ground.fs.glsl shaders/gl3/demo_ground.vs.glsl -shaders/gl3/fill.fs.glsl -shaders/gl3/fill.vs.glsl shaders/gl3/reproject.fs.glsl shaders/gl3/reproject.vs.glsl shaders/gl3/stencil.fs.glsl shaders/gl3/stencil.vs.glsl -shaders/gl3/tile.fs.glsl -shaders/gl3/tile.vs.glsl -shaders/gl3/tile_clip.fs.glsl -shaders/gl3/tile_clip.vs.glsl -shaders/gl3/tile_copy.fs.glsl -shaders/gl3/tile_copy.vs.glsl shaders/gl4/blit.fs.glsl shaders/gl4/blit.vs.glsl shaders/gl4/clear.fs.glsl shaders/gl4/clear.vs.glsl -shaders/gl4/debug_solid.fs.glsl -shaders/gl4/debug_solid.vs.glsl -shaders/gl4/debug_texture.fs.glsl -shaders/gl4/debug_texture.vs.glsl +shaders/gl4/d3d11/bin.cs.glsl +shaders/gl4/d3d11/bound.cs.glsl +shaders/gl4/d3d11/dice.cs.glsl +shaders/gl4/d3d11/fill.cs.glsl +shaders/gl4/d3d11/propagate.cs.glsl +shaders/gl4/d3d11/sort.cs.glsl +shaders/gl4/d3d11/tile.cs.glsl +shaders/gl4/d3d9/fill.fs.glsl +shaders/gl4/d3d9/fill.vs.glsl +shaders/gl4/d3d9/tile.fs.glsl +shaders/gl4/d3d9/tile.vs.glsl +shaders/gl4/d3d9/tile_clip_combine.fs.glsl +shaders/gl4/d3d9/tile_clip_combine.vs.glsl +shaders/gl4/d3d9/tile_clip_copy.fs.glsl +shaders/gl4/d3d9/tile_clip_copy.vs.glsl +shaders/gl4/d3d9/tile_copy.fs.glsl +shaders/gl4/d3d9/tile_copy.vs.glsl +shaders/gl4/debug/solid.fs.glsl +shaders/gl4/debug/solid.vs.glsl +shaders/gl4/debug/texture.fs.glsl +shaders/gl4/debug/texture.vs.glsl shaders/gl4/demo_ground.fs.glsl shaders/gl4/demo_ground.vs.glsl -shaders/gl4/fill.fs.glsl -shaders/gl4/fill.vs.glsl shaders/gl4/reproject.fs.glsl shaders/gl4/reproject.vs.glsl shaders/gl4/stencil.fs.glsl shaders/gl4/stencil.vs.glsl -shaders/gl4/tile.fs.glsl -shaders/gl4/tile.vs.glsl -shaders/gl4/tile_clip.fs.glsl -shaders/gl4/tile_clip.vs.glsl -shaders/gl4/tile_copy.fs.glsl -shaders/gl4/tile_copy.vs.glsl shaders/metal/blit.fs.metal shaders/metal/blit.vs.metal shaders/metal/clear.fs.metal shaders/metal/clear.vs.metal -shaders/metal/debug_solid.fs.metal -shaders/metal/debug_solid.vs.metal -shaders/metal/debug_texture.fs.metal -shaders/metal/debug_texture.vs.metal +shaders/metal/d3d11/bin.cs.metal +shaders/metal/d3d11/bound.cs.metal +shaders/metal/d3d11/dice.cs.metal +shaders/metal/d3d11/fill.cs.metal +shaders/metal/d3d11/propagate.cs.metal +shaders/metal/d3d11/sort.cs.metal +shaders/metal/d3d11/tile.cs.metal +shaders/metal/d3d9/fill.fs.metal +shaders/metal/d3d9/fill.vs.metal +shaders/metal/d3d9/tile.fs.metal +shaders/metal/d3d9/tile.vs.metal +shaders/metal/d3d9/tile_clip_combine.fs.metal +shaders/metal/d3d9/tile_clip_combine.vs.metal +shaders/metal/d3d9/tile_clip_copy.fs.metal +shaders/metal/d3d9/tile_clip_copy.vs.metal +shaders/metal/d3d9/tile_copy.fs.metal +shaders/metal/d3d9/tile_copy.vs.metal +shaders/metal/debug/solid.fs.metal +shaders/metal/debug/solid.vs.metal +shaders/metal/debug/texture.fs.metal +shaders/metal/debug/texture.vs.metal shaders/metal/demo_ground.fs.metal shaders/metal/demo_ground.vs.metal -shaders/metal/fill.cs.metal -shaders/metal/fill.fs.metal -shaders/metal/fill.vs.metal shaders/metal/reproject.fs.metal shaders/metal/reproject.vs.metal shaders/metal/stencil.fs.metal shaders/metal/stencil.vs.metal -shaders/metal/tile.fs.metal -shaders/metal/tile.vs.metal -shaders/metal/tile_clip.fs.metal -shaders/metal/tile_clip.vs.metal -shaders/metal/tile_copy.fs.metal -shaders/metal/tile_copy.vs.metal textures/area-lut.png textures/debug-corner-fill.png textures/debug-corner-outline.png diff --git a/resources/shaders/gl3/debug_solid.fs.glsl b/resources/shaders/gl3/debug/solid.fs.glsl similarity index 100% rename from resources/shaders/gl3/debug_solid.fs.glsl rename to resources/shaders/gl3/debug/solid.fs.glsl diff --git a/resources/shaders/gl3/debug_solid.vs.glsl b/resources/shaders/gl3/debug/solid.vs.glsl similarity index 100% rename from resources/shaders/gl3/debug_solid.vs.glsl rename to resources/shaders/gl3/debug/solid.vs.glsl diff --git a/resources/shaders/gl3/debug_texture.fs.glsl b/resources/shaders/gl3/debug/texture.fs.glsl similarity index 100% rename from resources/shaders/gl3/debug_texture.fs.glsl rename to resources/shaders/gl3/debug/texture.fs.glsl diff --git a/resources/shaders/gl3/debug_texture.vs.glsl b/resources/shaders/gl3/debug/texture.vs.glsl similarity index 100% rename from resources/shaders/gl3/debug_texture.vs.glsl rename to resources/shaders/gl3/debug/texture.vs.glsl diff --git a/resources/shaders/gl4/debug_solid.fs.glsl b/resources/shaders/gl4/debug/solid.fs.glsl similarity index 100% rename from resources/shaders/gl4/debug_solid.fs.glsl rename to resources/shaders/gl4/debug/solid.fs.glsl diff --git a/resources/shaders/gl4/debug_solid.vs.glsl b/resources/shaders/gl4/debug/solid.vs.glsl similarity index 100% rename from resources/shaders/gl4/debug_solid.vs.glsl rename to resources/shaders/gl4/debug/solid.vs.glsl diff --git a/resources/shaders/gl4/debug_texture.fs.glsl b/resources/shaders/gl4/debug/texture.fs.glsl similarity index 100% rename from resources/shaders/gl4/debug_texture.fs.glsl rename to resources/shaders/gl4/debug/texture.fs.glsl diff --git a/resources/shaders/gl4/debug_texture.vs.glsl b/resources/shaders/gl4/debug/texture.vs.glsl similarity index 100% rename from resources/shaders/gl4/debug_texture.vs.glsl rename to resources/shaders/gl4/debug/texture.vs.glsl diff --git a/resources/shaders/metal/debug_solid.fs.metal b/resources/shaders/metal/debug/solid.fs.metal similarity index 100% rename from resources/shaders/metal/debug_solid.fs.metal rename to resources/shaders/metal/debug/solid.fs.metal diff --git a/resources/shaders/metal/debug_solid.vs.metal b/resources/shaders/metal/debug/solid.vs.metal similarity index 100% rename from resources/shaders/metal/debug_solid.vs.metal rename to resources/shaders/metal/debug/solid.vs.metal diff --git a/resources/shaders/metal/debug_texture.fs.metal b/resources/shaders/metal/debug/texture.fs.metal similarity index 100% rename from resources/shaders/metal/debug_texture.fs.metal rename to resources/shaders/metal/debug/texture.fs.metal diff --git a/resources/shaders/metal/debug_texture.vs.metal b/resources/shaders/metal/debug/texture.vs.metal similarity index 100% rename from resources/shaders/metal/debug_texture.vs.metal rename to resources/shaders/metal/debug/texture.vs.metal diff --git a/shaders/Makefile b/shaders/Makefile index c121d3a1..15d8a329 100644 --- a/shaders/Makefile +++ b/shaders/Makefile @@ -3,36 +3,47 @@ TARGET_DIR?=../resources/shaders EMPTY= SHADERS=\ + d3d9/fill.fs.glsl \ + d3d9/fill.vs.glsl \ + d3d9/tile.fs.glsl \ + d3d9/tile.vs.glsl \ + d3d9/tile_clip_combine.fs.glsl \ + d3d9/tile_clip_combine.vs.glsl \ + d3d9/tile_clip_copy.fs.glsl \ + d3d9/tile_clip_copy.vs.glsl \ + d3d9/tile_copy.fs.glsl \ + d3d9/tile_copy.vs.glsl \ + debug/solid.fs.glsl \ + debug/solid.vs.glsl \ + debug/texture.fs.glsl \ + debug/texture.vs.glsl \ blit.fs.glsl \ blit.vs.glsl \ clear.fs.glsl \ clear.vs.glsl \ - debug_solid.fs.glsl \ - debug_solid.vs.glsl \ - debug_texture.fs.glsl \ - debug_texture.vs.glsl \ demo_ground.fs.glsl \ demo_ground.vs.glsl \ - fill.fs.glsl \ - fill.vs.glsl \ reproject.fs.glsl \ reproject.vs.glsl \ stencil.fs.glsl \ stencil.vs.glsl \ - tile.fs.glsl \ - tile.vs.glsl \ - tile_clip.fs.glsl \ - tile_clip.vs.glsl \ - tile_copy.fs.glsl \ - tile_copy.vs.glsl \ $(EMPTY) COMPUTE_SHADERS=\ - fill.cs.glsl \ + d3d11/bin.cs.glsl \ + d3d11/bound.cs.glsl \ + d3d11/dice.cs.glsl \ + d3d11/fill.cs.glsl \ + d3d11/propagate.cs.glsl \ + d3d11/sort.cs.glsl \ + d3d11/tile.cs.glsl \ $(EMPTY) INCLUDES=\ - fill.inc.glsl \ + d3d11/fill_compute.inc.glsl \ + fill_area.inc.glsl \ + tile_fragment.inc.glsl \ + tile_vertex.inc.glsl \ $(EMPTY) OUT=\ @@ -58,6 +69,10 @@ HEADER="// Automatically generated from files in pathfinder/shaders/. Do not edi GLSL_SED_ARGS=-e "s/\#version .*//" -e "s/\#line.*$$//" +GLSL_SHADER_TYPE.fs=frag +GLSL_SHADER_TYPE.vs=vert +GLSL_SHADER_TYPE.cs=comp + all: $(OUT) .PHONY: clean @@ -65,29 +80,14 @@ all: $(OUT) clean: rm -f $(OUT) -build/metal/%.fs.spv: %.fs.glsl $(INCLUDES) - mkdir -p build/metal && glslangValidator $(GLSLANGFLAGS_METAL) -G$(GLSL_VERSION) -S frag -o $@ $< +build/metal/%.spv: %.glsl $(INCLUDES) + mkdir -p $(dir $@) && glslangValidator $(GLSLANGFLAGS_METAL) -G$(GLSL_VERSION) -S $(GLSL_SHADER_TYPE$(suffix $(basename $(notdir $<)))) -o $@ $< -$(TARGET_DIR)/gl3/%.fs.glsl: %.fs.glsl $(INCLUDES) - mkdir -p $(TARGET_DIR)/gl3 && echo $(GLSL_VERSION_HEADER) > $@ && echo $(HEADER) >> $@ && ( glslangValidator $(GLSLANGFLAGS) -S frag -E $< | sed $(GLSL_SED_ARGS) >> $@ ) || ( rm $@ && exit 1 ) +$(TARGET_DIR)/gl3/%.glsl: %.glsl $(INCLUDES) + mkdir -p $(dir $@) && echo $(GLSL_VERSION_HEADER) > $@ && echo $(HEADER) >> $@ && ( glslangValidator $(GLSLANGFLAGS) -S $(GLSL_SHADER_TYPE$(suffix $(basename $(notdir $<)))) -E $< | sed $(GLSL_SED_ARGS) >> $@ ) || ( rm $@ && exit 1 ) -$(TARGET_DIR)/gl4/%.fs.glsl: %.fs.glsl $(INCLUDES) - mkdir -p $(TARGET_DIR)/gl4 && echo $(GLSL_VERSION_HEADER) > $@ && echo $(HEADER) >> $@ && ( glslangValidator $(GLSLANGFLAGS) -S frag -E $< | sed $(GLSL_SED_ARGS) >> $@ ) || ( rm $@ && exit 1 ) +$(TARGET_DIR)/gl4/%.glsl: %.glsl $(INCLUDES) + mkdir -p $(dir $@) && echo $(GLSL_VERSION_HEADER) > $@ && echo $(HEADER) >> $@ && ( glslangValidator $(GLSLANGFLAGS) -S $(GLSL_SHADER_TYPE$(suffix $(basename $(notdir $<)))) -E $< | sed $(GLSL_SED_ARGS) >> $@ ) || ( rm $@ && exit 1 ) -build/metal/%.vs.spv: %.vs.glsl $(INCLUDES) - mkdir -p build/metal && glslangValidator $(GLSLANGFLAGS_METAL) -G$(GLSL_VERSION) -S vert -o $@ $< - -$(TARGET_DIR)/gl3/%.vs.glsl: %.vs.glsl $(INCLUDES) - mkdir -p $(TARGET_DIR)/gl3 && echo $(GLSL_VERSION_HEADER) > $@ && echo $(HEADER) >> $@ && ( glslangValidator $(GLSLANGFLAGS) -S vert -E $< | sed $(GLSL_SED_ARGS) >> $@ ) || ( rm $@ && exit 1 ) - -$(TARGET_DIR)/gl4/%.vs.glsl: %.vs.glsl $(INCLUDES) - mkdir -p $(TARGET_DIR)/gl3 && echo $(GLSL_VERSION_HEADER) > $@ && echo $(HEADER) >> $@ && ( glslangValidator $(GLSLANGFLAGS) -S vert -E $< | sed $(GLSL_SED_ARGS) >> $@ ) || ( rm $@ && exit 1 ) - -build/metal/%.cs.spv: %.cs.glsl $(INCLUDES) - mkdir -p build/metal && glslangValidator $(GLSLANGFLAGS_METAL) -G$(GLSL_COMPUTE_VERSION) -S comp -o $@ $< - -$(TARGET_DIR)/gl4/%.cs.glsl: %.cs.glsl $(INCLUDES) - mkdir -p $(TARGET_DIR)/gl4 && echo $(GLSL_VERSION_HEADER) > $@ && echo $(HEADER) >> $@ && ( glslangValidator $(GLSLANGFLAGS) -S vert -E $< | sed $(GLSL_SED_ARGS) >> $@ ) || ( rm $@ && exit 1 ) - -$(TARGET_DIR)/metal/%.metal: build/metal/%.spv - mkdir -p $(TARGET_DIR)/metal && echo $(HEADER) > $@ && ( $(SPIRVCROSS) $(SPIRVCROSSFLAGS) $< >> $@ ) || ( rm $@ && exit 1 ) +$(TARGET_DIR)/metal/%.metal: build/metal/%.spv + mkdir -p $(dir $@) && echo $(HEADER) > $@ && ( $(SPIRVCROSS) $(SPIRVCROSSFLAGS) $< >> $@ ) || ( rm $@ && exit 1 ) diff --git a/shaders/debug_solid.fs.glsl b/shaders/debug/solid.fs.glsl similarity index 93% rename from shaders/debug_solid.fs.glsl rename to shaders/debug/solid.fs.glsl index 5ceb65f9..8dacbc8e 100644 --- a/shaders/debug_solid.fs.glsl +++ b/shaders/debug/solid.fs.glsl @@ -1,6 +1,6 @@ #version 330 -// pathfinder/shaders/debug_solid.fs.glsl +// pathfinder/shaders/debug/solid.fs.glsl // // Copyright © 2019 The Pathfinder Project Developers. // diff --git a/shaders/debug_solid.vs.glsl b/shaders/debug/solid.vs.glsl similarity index 93% rename from shaders/debug_solid.vs.glsl rename to shaders/debug/solid.vs.glsl index b10dde44..eb71b1a6 100644 --- a/shaders/debug_solid.vs.glsl +++ b/shaders/debug/solid.vs.glsl @@ -1,6 +1,6 @@ #version 330 -// pathfinder/shaders/debug_solid.vs.glsl +// pathfinder/shaders/debug/solid.vs.glsl // // Copyright © 2019 The Pathfinder Project Developers. // diff --git a/shaders/debug_texture.fs.glsl b/shaders/debug/texture.fs.glsl similarity index 93% rename from shaders/debug_texture.fs.glsl rename to shaders/debug/texture.fs.glsl index c01d386a..67e8f979 100644 --- a/shaders/debug_texture.fs.glsl +++ b/shaders/debug/texture.fs.glsl @@ -1,6 +1,6 @@ #version 330 -// pathfinder/shaders/debug_texture.fs.glsl +// pathfinder/shaders/debug/texture.fs.glsl // // Copyright © 2019 The Pathfinder Project Developers. // diff --git a/shaders/debug_texture.vs.glsl b/shaders/debug/texture.vs.glsl similarity index 94% rename from shaders/debug_texture.vs.glsl rename to shaders/debug/texture.vs.glsl index 2f918e29..6477ca4e 100644 --- a/shaders/debug_texture.vs.glsl +++ b/shaders/debug/texture.vs.glsl @@ -1,6 +1,6 @@ #version 330 -// pathfinder/shaders/debug_texture.vs.glsl +// pathfinder/shaders/debug/texture.vs.glsl // // Copyright © 2019 The Pathfinder Project Developers. // diff --git a/ui/src/lib.rs b/ui/src/lib.rs index 775032db..c9558cb5 100644 --- a/ui/src/lib.rs +++ b/ui/src/lib.rs @@ -20,9 +20,10 @@ use hashbrown::HashMap; use pathfinder_color::ColorU; use pathfinder_geometry::rect::RectI; use pathfinder_geometry::vector::{Vector2F, Vector2I, vec2i}; -use pathfinder_gpu::{BlendFactor, BlendState, BufferData, BufferTarget, BufferUploadMode, Device}; -use pathfinder_gpu::{Primitive, RenderOptions, RenderState, RenderTarget, TextureFormat}; -use pathfinder_gpu::{UniformData, VertexAttrClass, VertexAttrDescriptor, VertexAttrType}; +use pathfinder_gpu::allocator::{BufferTag, GPUMemoryAllocator}; +use pathfinder_gpu::{BlendFactor, BlendState, BufferTarget, Device, Primitive, RenderOptions}; +use pathfinder_gpu::{RenderState, RenderTarget, TextureFormat, UniformData, VertexAttrClass}; +use pathfinder_gpu::{VertexAttrDescriptor, VertexAttrType}; use pathfinder_resources::ResourceLoader; use pathfinder_simd::default::F32x4; use serde_json; @@ -71,9 +72,7 @@ pub struct UIPresenter where D: Device { framebuffer_size: Vector2I, texture_program: DebugTextureProgram, - texture_vertex_array: DebugTextureVertexArray, solid_program: DebugSolidProgram, - solid_vertex_array: DebugSolidVertexArray, font: DebugFont, font_texture: D::Texture, @@ -85,11 +84,9 @@ impl UIPresenter where D: Device { pub fn new(device: &D, resources: &dyn ResourceLoader, framebuffer_size: Vector2I) -> UIPresenter { let texture_program = DebugTextureProgram::new(device, resources); - let texture_vertex_array = DebugTextureVertexArray::new(device, &texture_program); let font = DebugFont::load(resources); let solid_program = DebugSolidProgram::new(device, resources); - let solid_vertex_array = DebugSolidVertexArray::new(device, &solid_program); let font_texture = device.create_texture_from_png(resources, FONT_PNG_NAME, @@ -108,10 +105,8 @@ impl UIPresenter where D: Device { framebuffer_size, texture_program, - texture_vertex_array, font, solid_program, - solid_vertex_array, font_texture, corner_fill_texture, @@ -128,16 +123,25 @@ impl UIPresenter where D: Device { } - pub fn draw_solid_rect(&self, device: &D, rect: RectI, color: ColorU) { - self.draw_rect(device, rect, color, true); + pub fn draw_solid_rect(&self, + device: &D, + allocator: &mut GPUMemoryAllocator, + rect: RectI, + color: ColorU) { + self.draw_rect(device, allocator, rect, color, true); } - pub fn draw_rect_outline(&self, device: &D, rect: RectI, color: ColorU) { - self.draw_rect(device, rect, color, false); + pub fn draw_rect_outline(&self, + device: &D, + allocator: &mut GPUMemoryAllocator, + rect: RectI, + color: ColorU) { + self.draw_rect(device, allocator, rect, color, false); } fn draw_rect(&self, device: &D, + allocator: &mut GPUMemoryAllocator, rect: RectI, color: ColorU, filled: bool) { @@ -150,12 +154,14 @@ impl UIPresenter where D: Device { if filled { self.draw_solid_rects_with_vertex_data(device, + allocator, &vertex_data, &QUAD_INDICES, color, true); } else { self.draw_solid_rects_with_vertex_data(device, + allocator, &vertex_data, &RECT_LINE_INDICES, color, @@ -165,39 +171,60 @@ impl UIPresenter where D: Device { fn draw_solid_rects_with_vertex_data(&self, device: &D, + allocator: &mut GPUMemoryAllocator, vertex_data: &[DebugSolidVertex], index_data: &[u32], color: ColorU, filled: bool) { - device.allocate_buffer(&self.solid_vertex_array.vertex_buffer, - BufferData::Memory(vertex_data), - BufferTarget::Vertex); - device.allocate_buffer(&self.solid_vertex_array.index_buffer, - BufferData::Memory(index_data), - BufferTarget::Index); + let vertex_buffer_id = + allocator.allocate_buffer::(device, + vertex_data.len() as u64, + BufferTag("SolidVertexDebug")); + let index_buffer_id = allocator.allocate_buffer::(device, + index_data.len() as u64, + BufferTag("SolidIndexDebug")); + { + let vertex_buffer = allocator.get_buffer(vertex_buffer_id); + let index_buffer = allocator.get_buffer(index_buffer_id); + device.upload_to_buffer(&vertex_buffer, 0, vertex_data, BufferTarget::Vertex); + device.upload_to_buffer(&index_buffer, 0, index_data, BufferTarget::Index); + let solid_vertex_array = DebugSolidVertexArray::new(device, + &self.solid_program, + vertex_buffer, + index_buffer); - let primitive = if filled { Primitive::Triangles } else { Primitive::Lines }; - device.draw_elements(index_data.len() as u32, &RenderState { - target: &RenderTarget::Default, - program: &self.solid_program.program, - vertex_array: &self.solid_vertex_array.vertex_array, - primitive, - uniforms: &[ - (&self.solid_program.framebuffer_size_uniform, - UniformData::Vec2(self.framebuffer_size.0.to_f32x2())), - (&self.solid_program.color_uniform, get_color_uniform(color)), - ], - textures: &[], - images: &[], - viewport: RectI::new(Vector2I::default(), self.framebuffer_size), - options: RenderOptions { - blend: Some(alpha_blend_state()), - ..RenderOptions::default() - }, - }); + let primitive = if filled { Primitive::Triangles } else { Primitive::Lines }; + device.draw_elements(index_data.len() as u32, &RenderState { + target: &RenderTarget::Default, + program: &self.solid_program.program, + vertex_array: &solid_vertex_array.vertex_array, + primitive, + uniforms: &[ + (&self.solid_program.framebuffer_size_uniform, + UniformData::Vec2(self.framebuffer_size.0.to_f32x2())), + (&self.solid_program.color_uniform, get_color_uniform(color)), + ], + textures: &[], + images: &[], + storage_buffers: &[], + viewport: RectI::new(Vector2I::default(), self.framebuffer_size), + options: RenderOptions { + blend: Some(alpha_blend_state()), + ..RenderOptions::default() + }, + }); + } + + allocator.free_buffer(index_buffer_id); + allocator.free_buffer(vertex_buffer_id); } - pub fn draw_text(&self, device: &D, string: &str, origin: Vector2I, invert: bool) { + pub fn draw_text(&self, + device: &D, + allocator: &mut GPUMemoryAllocator, + string: &str, + origin: Vector2I, + invert: bool) { let mut next = origin; let char_count = string.chars().count(); let mut vertex_data = Vec::with_capacity(char_count * 4); @@ -227,6 +254,7 @@ impl UIPresenter where D: Device { let color = if invert { INVERTED_TEXT_COLOR } else { TEXT_COLOR }; self.draw_texture_with_vertex_data(device, + allocator, &vertex_data, &index_data, &self.font_texture, @@ -235,6 +263,7 @@ impl UIPresenter where D: Device { pub fn draw_texture(&self, device: &D, + allocator: &mut GPUMemoryAllocator, origin: Vector2I, texture: &D::Texture, color: ColorU) { @@ -247,7 +276,12 @@ impl UIPresenter where D: Device { DebugTextureVertex::new(position_rect.lower_left(), tex_coord_rect.lower_left()), ]; - self.draw_texture_with_vertex_data(device, &vertex_data, &QUAD_INDICES, texture, color); + self.draw_texture_with_vertex_data(device, + allocator, + &vertex_data, + &QUAD_INDICES, + texture, + color); } pub fn measure_text(&self, string: &str) -> i32 { @@ -268,10 +302,14 @@ impl UIPresenter where D: Device { SEGMENT_SIZE * segment_count as i32 + (segment_count - 1) as i32 } - pub fn draw_solid_rounded_rect(&self, device: &D, rect: RectI, color: ColorU) { + pub fn draw_solid_rounded_rect(&self, + device: &D, + allocator: &mut GPUMemoryAllocator, + rect: RectI, + color: ColorU) { let corner_texture = self.corner_texture(true); let corner_rects = CornerRects::new(device, rect, corner_texture); - self.draw_rounded_rect_corners(device, color, corner_texture, &corner_rects); + self.draw_rounded_rect_corners(device, allocator, color, corner_texture, &corner_rects); let solid_rect_mid = RectI::from_points(corner_rects.upper_left.upper_right(), corner_rects.lower_right.lower_left()); @@ -302,16 +340,21 @@ impl UIPresenter where D: Device { index_data.extend(QUAD_INDICES.iter().map(|&index| index + 8)); self.draw_solid_rects_with_vertex_data(device, + allocator, &vertex_data, &index_data[0..18], color, true); } - pub fn draw_rounded_rect_outline(&self, device: &D, rect: RectI, color: ColorU) { + pub fn draw_rounded_rect_outline(&self, + device: &D, + allocator: &mut GPUMemoryAllocator, + rect: RectI, + color: ColorU) { let corner_texture = self.corner_texture(false); let corner_rects = CornerRects::new(device, rect, corner_texture); - self.draw_rounded_rect_corners(device, color, corner_texture, &corner_rects); + self.draw_rounded_rect_corners(device, allocator, color, corner_texture, &corner_rects); let vertex_data = vec![ DebugSolidVertex::new(corner_rects.upper_left.upper_right()), @@ -325,18 +368,34 @@ impl UIPresenter where D: Device { ]; let index_data = &OUTLINE_RECT_LINE_INDICES; - self.draw_solid_rects_with_vertex_data(device, &vertex_data, index_data, color, false); + self.draw_solid_rects_with_vertex_data(device, + allocator, + &vertex_data, + index_data, + color, + false); } // TODO(pcwalton): `LineSegment2I`. - fn draw_line(&self, device: &D, from: Vector2I, to: Vector2I, color: ColorU) { + fn draw_line(&self, + device: &D, + allocator: &mut GPUMemoryAllocator, + from: Vector2I, + to: Vector2I, + color: ColorU) { let vertex_data = vec![DebugSolidVertex::new(from), DebugSolidVertex::new(to)]; - self.draw_solid_rects_with_vertex_data(device, &vertex_data, &[0, 1], color, false); + self.draw_solid_rects_with_vertex_data(device, + allocator, + &vertex_data, + &[0, 1], + color, + false); } fn draw_rounded_rect_corners(&self, device: &D, + allocator: &mut GPUMemoryAllocator, color: ColorU, texture: &D::Texture, corner_rects: &CornerRects) { @@ -387,7 +446,12 @@ impl UIPresenter where D: Device { index_data.extend(QUAD_INDICES.iter().map(|&index| index + 8)); index_data.extend(QUAD_INDICES.iter().map(|&index| index + 12)); - self.draw_texture_with_vertex_data(device, &vertex_data, &index_data, texture, color); + self.draw_texture_with_vertex_data(device, + allocator, + &vertex_data, + &index_data, + texture, + color); } fn corner_texture(&self, filled: bool) -> &D::Texture { @@ -396,44 +460,66 @@ impl UIPresenter where D: Device { fn draw_texture_with_vertex_data(&self, device: &D, + allocator: &mut GPUMemoryAllocator, vertex_data: &[DebugTextureVertex], index_data: &[u32], texture: &D::Texture, color: ColorU) { - device.allocate_buffer(&self.texture_vertex_array.vertex_buffer, - BufferData::Memory(vertex_data), - BufferTarget::Vertex); - device.allocate_buffer(&self.texture_vertex_array.index_buffer, - BufferData::Memory(index_data), - BufferTarget::Index); + let vertex_buffer_id = + allocator.allocate_buffer::(device, + vertex_data.len() as u64, + BufferTag("TextureVertexDebug")); + let index_buffer_id = allocator.allocate_buffer::(device, + index_data.len() as u64, + BufferTag("TextureIndexDebug")); + { + let vertex_buffer = allocator.get_buffer(vertex_buffer_id); + let index_buffer = allocator.get_buffer(index_buffer_id); + device.upload_to_buffer(&vertex_buffer, 0, vertex_data, BufferTarget::Vertex); + device.upload_to_buffer(&index_buffer, 0, index_data, BufferTarget::Index); - device.draw_elements(index_data.len() as u32, &RenderState { - target: &RenderTarget::Default, - program: &self.texture_program.program, - vertex_array: &self.texture_vertex_array.vertex_array, - primitive: Primitive::Triangles, - textures: &[(&self.texture_program.texture, &texture)], - images: &[], - uniforms: &[ - (&self.texture_program.framebuffer_size_uniform, - UniformData::Vec2(self.framebuffer_size.0.to_f32x2())), - (&self.texture_program.color_uniform, get_color_uniform(color)), - (&self.texture_program.texture_size_uniform, - UniformData::Vec2(device.texture_size(&texture).0.to_f32x2())) - ], - viewport: RectI::new(Vector2I::default(), self.framebuffer_size), - options: RenderOptions { - blend: Some(alpha_blend_state()), - ..RenderOptions::default() - }, - }); + let texture_vertex_array = DebugTextureVertexArray::new(device, + &self.texture_program, + vertex_buffer, + index_buffer); + + device.draw_elements(index_data.len() as u32, &RenderState { + target: &RenderTarget::Default, + program: &self.texture_program.program, + vertex_array: &texture_vertex_array.vertex_array, + primitive: Primitive::Triangles, + textures: &[(&self.texture_program.texture, &texture)], + images: &[], + storage_buffers: &[], + uniforms: &[ + (&self.texture_program.framebuffer_size_uniform, + UniformData::Vec2(self.framebuffer_size.0.to_f32x2())), + (&self.texture_program.color_uniform, get_color_uniform(color)), + (&self.texture_program.texture_size_uniform, + UniformData::Vec2(device.texture_size(&texture).0.to_f32x2())) + ], + viewport: RectI::new(Vector2I::default(), self.framebuffer_size), + options: RenderOptions { + blend: Some(alpha_blend_state()), + ..RenderOptions::default() + }, + }); + } + + allocator.free_buffer(index_buffer_id); + allocator.free_buffer(vertex_buffer_id); } - pub fn draw_button(&mut self, device: &D, origin: Vector2I, texture: &D::Texture) -> bool { + pub fn draw_button(&mut self, + device: &D, + allocator: &mut GPUMemoryAllocator, + origin: Vector2I, + texture: &D::Texture) -> bool { let button_rect = RectI::new(origin, vec2i(BUTTON_WIDTH, BUTTON_HEIGHT)); - self.draw_solid_rounded_rect(device, button_rect, WINDOW_COLOR); - self.draw_rounded_rect_outline(device, button_rect, OUTLINE_COLOR); + self.draw_solid_rounded_rect(device, allocator, button_rect, WINDOW_COLOR); + self.draw_rounded_rect_outline(device, allocator, button_rect, OUTLINE_COLOR); self.draw_texture(device, + allocator, origin + vec2i(PADDING, PADDING), texture, BUTTON_ICON_COLOR); @@ -442,11 +528,13 @@ impl UIPresenter where D: Device { pub fn draw_text_switch(&mut self, device: &D, + allocator: &mut GPUMemoryAllocator, mut origin: Vector2I, segment_labels: &[&str], mut value: u8) -> u8 { if let Some(new_value) = self.draw_segmented_control(device, + allocator, origin, Some(value), segment_labels.len() as u8) { @@ -458,6 +546,7 @@ impl UIPresenter where D: Device { let label_width = self.measure_text(segment_label); let offset = SEGMENT_SIZE / 2 - label_width / 2; self.draw_text(device, + allocator, segment_label, origin + vec2i(offset, 0), segment_index as u8 == value); @@ -469,12 +558,14 @@ impl UIPresenter where D: Device { pub fn draw_image_segmented_control(&mut self, device: &D, + allocator: &mut GPUMemoryAllocator, mut origin: Vector2I, segment_textures: &[&D::Texture], mut value: Option) -> Option { let mut clicked_segment = None; if let Some(segment_index) = self.draw_segmented_control(device, + allocator, origin, value, segment_textures.len() as u8) { @@ -493,7 +584,7 @@ impl UIPresenter where D: Device { TEXT_COLOR }; - self.draw_texture(device, origin + offset, segment_texture, color); + self.draw_texture(device, allocator, origin + offset, segment_texture, color); origin += vec2i(SEGMENT_SIZE + 1, 0); } @@ -502,6 +593,7 @@ impl UIPresenter where D: Device { fn draw_segmented_control(&mut self, device: &D, + allocator: &mut GPUMemoryAllocator, origin: Vector2I, mut value: Option, segment_count: u8) @@ -518,13 +610,14 @@ impl UIPresenter where D: Device { clicked_segment = Some(segment); } - self.draw_solid_rounded_rect(device, widget_rect, WINDOW_COLOR); - self.draw_rounded_rect_outline(device, widget_rect, OUTLINE_COLOR); + self.draw_solid_rounded_rect(device, allocator, widget_rect, WINDOW_COLOR); + self.draw_rounded_rect_outline(device, allocator, widget_rect, OUTLINE_COLOR); if let Some(value) = value { let highlight_size = vec2i(SEGMENT_SIZE, BUTTON_HEIGHT); let x_offset = value as i32 * SEGMENT_SIZE + (value as i32 - 1); self.draw_solid_rounded_rect(device, + allocator, RectI::new(origin + vec2i(x_offset, 0), highlight_size), TEXT_COLOR); } @@ -536,6 +629,7 @@ impl UIPresenter where D: Device { Some(value) if value == prev_segment_index || value == next_segment_index => {} _ => { self.draw_line(device, + allocator, segment_origin, segment_origin + vec2i(0, BUTTON_HEIGHT), TEXT_COLOR); @@ -547,7 +641,11 @@ impl UIPresenter where D: Device { clicked_segment } - pub fn draw_tooltip(&self, device: &D, string: &str, rect: RectI) { + pub fn draw_tooltip(&self, + device: &D, + allocator: &mut GPUMemoryAllocator, + string: &str, + rect: RectI) { if !rect.to_f32().contains_point(self.mouse_position) { return; } @@ -556,8 +654,15 @@ impl UIPresenter where D: Device { let window_size = vec2i(text_size + PADDING * 2, TOOLTIP_HEIGHT); let origin = rect.origin() - vec2i(0, window_size.y() + PADDING); - self.draw_solid_rounded_rect(device, RectI::new(origin, window_size), WINDOW_COLOR); - self.draw_text(device, string, origin + vec2i(PADDING, PADDING + FONT_ASCENT), false); + self.draw_solid_rounded_rect(device, + allocator, + RectI::new(origin, window_size), + WINDOW_COLOR); + self.draw_text(device, + allocator, + string, + origin + vec2i(PADDING, PADDING + FONT_ASCENT), + false); } } @@ -571,7 +676,7 @@ struct DebugTextureProgram where D: Device { impl DebugTextureProgram where D: Device { fn new(device: &D, resources: &dyn ResourceLoader) -> DebugTextureProgram { - let program = device.create_raster_program(resources, "debug_texture"); + let program = device.create_raster_program(resources, "debug/texture"); let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize"); let texture_size_uniform = device.get_uniform(&program, "TextureSize"); let color_uniform = device.get_uniform(&program, "Color"); @@ -588,15 +693,14 @@ impl DebugTextureProgram where D: Device { struct DebugTextureVertexArray where D: Device { vertex_array: D::VertexArray, - vertex_buffer: D::Buffer, - index_buffer: D::Buffer, } impl DebugTextureVertexArray where D: Device { - fn new(device: &D, debug_texture_program: &DebugTextureProgram) + fn new(device: &D, + debug_texture_program: &DebugTextureProgram, + vertex_buffer: &D::Buffer, + index_buffer: &D::Buffer) -> DebugTextureVertexArray { - let vertex_buffer = device.create_buffer(BufferUploadMode::Dynamic); - let index_buffer = device.create_buffer(BufferUploadMode::Dynamic); let vertex_array = device.create_vertex_array(); let position_attr = device.get_vertex_attr(&debug_texture_program.program, "Position") @@ -604,8 +708,8 @@ impl DebugTextureVertexArray where D: Device { let tex_coord_attr = device.get_vertex_attr(&debug_texture_program.program, "TexCoord") .unwrap(); - device.bind_buffer(&vertex_array, &vertex_buffer, BufferTarget::Vertex); - device.bind_buffer(&vertex_array, &index_buffer, BufferTarget::Index); + device.bind_buffer(&vertex_array, vertex_buffer, BufferTarget::Vertex); + device.bind_buffer(&vertex_array, index_buffer, BufferTarget::Index); device.configure_vertex_attr(&vertex_array, &position_attr, &VertexAttrDescriptor { size: 2, class: VertexAttrClass::Int, @@ -625,20 +729,20 @@ impl DebugTextureVertexArray where D: Device { buffer_index: 0, }); - DebugTextureVertexArray { vertex_array, vertex_buffer, index_buffer } + DebugTextureVertexArray { vertex_array } } } struct DebugSolidVertexArray where D: Device { vertex_array: D::VertexArray, - vertex_buffer: D::Buffer, - index_buffer: D::Buffer, } impl DebugSolidVertexArray where D: Device { - fn new(device: &D, debug_solid_program: &DebugSolidProgram) -> DebugSolidVertexArray { - let vertex_buffer = device.create_buffer(BufferUploadMode::Dynamic); - let index_buffer = device.create_buffer(BufferUploadMode::Dynamic); + fn new(device: &D, + debug_solid_program: &DebugSolidProgram, + vertex_buffer: &D::Buffer, + index_buffer: &D::Buffer) + -> DebugSolidVertexArray { let vertex_array = device.create_vertex_array(); let position_attr = @@ -655,7 +759,7 @@ impl DebugSolidVertexArray where D: Device { buffer_index: 0, }); - DebugSolidVertexArray { vertex_array, vertex_buffer, index_buffer } + DebugSolidVertexArray { vertex_array } } } @@ -667,7 +771,7 @@ struct DebugSolidProgram where D: Device { impl DebugSolidProgram where D: Device { fn new(device: &D, resources: &dyn ResourceLoader) -> DebugSolidProgram { - let program = device.create_raster_program(resources, "debug_solid"); + let program = device.create_raster_program(resources, "debug/solid"); let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize"); let color_uniform = device.get_uniform(&program, "Color"); DebugSolidProgram { program, framebuffer_size_uniform, color_uniform }