From 959f23f61b4f72f17a2266522102e6275184ecdf Mon Sep 17 00:00:00 2001 From: kossLAN Date: Fri, 29 May 2026 21:09:25 -0400 Subject: [PATCH] vulkan: split renderer paint regions --- src/gfx_apis/vulkan/renderer.rs | 119 +----------------- src/gfx_apis/vulkan/renderer/paint_region.rs | 121 +++++++++++++++++++ 2 files changed, 123 insertions(+), 117 deletions(-) create mode 100644 src/gfx_apis/vulkan/renderer/paint_region.rs diff --git a/src/gfx_apis/vulkan/renderer.rs b/src/gfx_apis/vulkan/renderer.rs index a736a79b..76dddb39 100644 --- a/src/gfx_apis/vulkan/renderer.rs +++ b/src/gfx_apis/vulkan/renderer.rs @@ -1,7 +1,9 @@ mod color; +mod paint_region; use { color::{ColorTransforms, EotfArgsCache}, + paint_region::{PaintRegion, Point, constrain_to_fb}, crate::{ async_engine::{AsyncEngine, SpawnedFuture}, cmm::{ @@ -69,7 +71,6 @@ use { }, }, isnt::std_1::{collections::IsntHashMapExt, primitive::IsntSliceExt}, - jay_algorithms::rect::Tag, linearize::{Linearize, LinearizeExt, StaticMap, static_map}, std::{ any::Any, @@ -209,8 +210,6 @@ pub(super) struct Memory { fb_inv_eotf_args_address: Option, } -type Point = [[f32; 2]; 4]; - enum VulkanOp { Fill(VulkanFillOp), Tex(VulkanTexOp), @@ -285,14 +284,6 @@ pub(super) enum RenderPass { FrameBuffer, } -#[derive(Copy, Clone)] -struct PaintRegion { - x1: f32, - y1: f32, - x2: f32, - y2: f32, -} - pub(super) struct PendingFrame { point: u64, renderer: Rc, @@ -2722,109 +2713,3 @@ async fn await_release( } renderer.pending_frames.remove(&frame.point); } - -impl PaintRegion { - fn intersects(&self, pos: &Point) -> bool { - let mut p = *pos; - for [x, y] in &mut p { - *x = x.clamp(self.x1, self.x2); - *y = y.clamp(self.y1, self.y2); - } - if p[0] == p[1] && p[2] == p[3] { - return false; - } - if p[0] == p[2] && p[1] == p[3] { - return false; - } - true - } - - fn union(&self, other: &Self) -> Self { - Self { - x1: self.x1.min(other.x1), - y1: self.y1.min(other.y1), - x2: self.x2.max(other.x2), - y2: self.y2.max(other.y2), - } - } - - fn to_scissor(&self, target: &VulkanImage) -> Rect2D { - let from_norm = |c: f32, max: u32| ((c + 1.0) * 0.5 * max as f32).round() as i32; - let x1 = from_norm(self.x1, target.width).max(0); - let y1 = from_norm(self.y1, target.height).max(0); - let x2 = from_norm(self.x2, target.width).min(target.width as i32); - let y2 = from_norm(self.y2, target.height).min(target.height as i32); - Rect2D { - offset: Offset2D { x: x1, y: y1 }, - extent: Extent2D { - width: (x2 - x1).max(0) as u32, - height: (y2 - y1).max(0) as u32, - }, - } - } - - fn constrain(&self, pos: &mut Point, tex_pos: Option<&mut Point>) -> bool { - zone!("constrain"); - let mut npos = *pos; - for [x, y] in &mut npos { - *x = x.clamp(self.x1, self.x2); - *y = y.clamp(self.y1, self.y2); - } - if npos == *pos { - return true; - } - if npos[0] == npos[1] && npos[2] == npos[3] { - return false; - } - if npos[0] == npos[2] && npos[1] == npos[3] { - return false; - } - if let Some(tp) = tex_pos { - let mut ntp = *tp; - for i in 0..4 { - if npos[i] == pos[i] { - continue; - } - macro_rules! sub { - ($l:expr, $r:expr) => { - [$l[0] - $r[0], $l[1] - $r[1]] - }; - } - let dx = sub!(npos[i], pos[i]); - let dy = sub!(pos[(i + 1) & 3], pos[i]); - let dz = sub!(pos[(i + 2) & 3], pos[i]); - let det = 1.0 / (dy[0] * dz[1] - dy[1] * dz[0]); - let alpha = [ - (dx[0] * dz[1] - dx[1] * dz[0]) * det, - (dx[1] * dy[0] - dx[0] * dy[1]) * det, - ]; - let dy = sub!(tp[(i + 1) & 3], tp[i]); - let dz = sub!(tp[(i + 2) & 3], tp[i]); - ntp[i][0] += alpha[0] * dy[0] + alpha[1] * dz[0]; - ntp[i][1] += alpha[0] * dy[1] + alpha[1] * dz[1]; - } - *tp = ntp; - } - *pos = npos; - true - } -} - -fn constrain_to_fb(fb: &VulkanImage, rect: &Rect) -> Option<[i32; 4]> -where - T: Tag, -{ - let x1 = rect.x1().max(0); - let y1 = rect.y1().max(0); - let x2 = rect.x2(); - let y2 = rect.y2(); - if x1 as u32 > fb.width || y1 as u32 > fb.height || x2 <= 0 || y2 <= 0 { - return None; - } - let x2 = x2.min(fb.width as i32); - let y2 = y2.min(fb.height as i32); - if x1 == x2 || y1 == y2 { - return None; - } - Some([x1, y1, x2, y2]) -} diff --git a/src/gfx_apis/vulkan/renderer/paint_region.rs b/src/gfx_apis/vulkan/renderer/paint_region.rs new file mode 100644 index 00000000..9f3cf42d --- /dev/null +++ b/src/gfx_apis/vulkan/renderer/paint_region.rs @@ -0,0 +1,121 @@ +use { + crate::{gfx_apis::vulkan::image::VulkanImage, rect::Rect}, + ash::vk::{Extent2D, Offset2D, Rect2D}, + jay_algorithms::rect::Tag, +}; + +pub(super) type Point = [[f32; 2]; 4]; + +#[derive(Copy, Clone)] +pub(super) struct PaintRegion { + pub(super) x1: f32, + pub(super) y1: f32, + pub(super) x2: f32, + pub(super) y2: f32, +} + +impl PaintRegion { + pub(super) fn intersects(&self, pos: &Point) -> bool { + let mut p = *pos; + for [x, y] in &mut p { + *x = x.clamp(self.x1, self.x2); + *y = y.clamp(self.y1, self.y2); + } + if p[0] == p[1] && p[2] == p[3] { + return false; + } + if p[0] == p[2] && p[1] == p[3] { + return false; + } + true + } + + pub(super) fn union(&self, other: &Self) -> Self { + Self { + x1: self.x1.min(other.x1), + y1: self.y1.min(other.y1), + x2: self.x2.max(other.x2), + y2: self.y2.max(other.y2), + } + } + + pub(super) fn to_scissor(&self, target: &VulkanImage) -> Rect2D { + let from_norm = |c: f32, max: u32| ((c + 1.0) * 0.5 * max as f32).round() as i32; + let x1 = from_norm(self.x1, target.width).max(0); + let y1 = from_norm(self.y1, target.height).max(0); + let x2 = from_norm(self.x2, target.width).min(target.width as i32); + let y2 = from_norm(self.y2, target.height).min(target.height as i32); + Rect2D { + offset: Offset2D { x: x1, y: y1 }, + extent: Extent2D { + width: (x2 - x1).max(0) as u32, + height: (y2 - y1).max(0) as u32, + }, + } + } + + pub(super) fn constrain(&self, pos: &mut Point, tex_pos: Option<&mut Point>) -> bool { + zone!("constrain"); + let mut npos = *pos; + for [x, y] in &mut npos { + *x = x.clamp(self.x1, self.x2); + *y = y.clamp(self.y1, self.y2); + } + if npos == *pos { + return true; + } + if npos[0] == npos[1] && npos[2] == npos[3] { + return false; + } + if npos[0] == npos[2] && npos[1] == npos[3] { + return false; + } + if let Some(tp) = tex_pos { + let mut ntp = *tp; + for i in 0..4 { + if npos[i] == pos[i] { + continue; + } + macro_rules! sub { + ($l:expr, $r:expr) => { + [$l[0] - $r[0], $l[1] - $r[1]] + }; + } + let dx = sub!(npos[i], pos[i]); + let dy = sub!(pos[(i + 1) & 3], pos[i]); + let dz = sub!(pos[(i + 2) & 3], pos[i]); + let det = 1.0 / (dy[0] * dz[1] - dy[1] * dz[0]); + let alpha = [ + (dx[0] * dz[1] - dx[1] * dz[0]) * det, + (dx[1] * dy[0] - dx[0] * dy[1]) * det, + ]; + let dy = sub!(tp[(i + 1) & 3], tp[i]); + let dz = sub!(tp[(i + 2) & 3], tp[i]); + ntp[i][0] += alpha[0] * dy[0] + alpha[1] * dz[0]; + ntp[i][1] += alpha[0] * dy[1] + alpha[1] * dz[1]; + } + *tp = ntp; + } + *pos = npos; + true + } +} + +pub(super) fn constrain_to_fb(fb: &VulkanImage, rect: &Rect) -> Option<[i32; 4]> +where + T: Tag, +{ + let x1 = rect.x1().max(0); + let y1 = rect.y1().max(0); + let x2 = rect.x2(); + let y2 = rect.y2(); + if x1 as u32 > fb.width || y1 as u32 > fb.height || x2 <= 0 || y2 <= 0 { + return None; + } + let x2 = x2.min(fb.width as i32); + let y2 = y2.min(fb.height as i32); + if x1 == x2 || y1 == y2 { + return None; + } + Some([x1, y1, x2, y2]) +}