1
0
Fork 0
forked from wry/wry

vulkan: split renderer paint regions

This commit is contained in:
kossLAN 2026-05-29 21:09:25 -04:00
parent 8c61a3150b
commit 959f23f61b
No known key found for this signature in database
2 changed files with 123 additions and 117 deletions

View file

@ -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<DeviceSize>,
}
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<VulkanRenderer>,
@ -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<T>(fb: &VulkanImage, rect: &Rect<T>) -> 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])
}

View file

@ -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<T>(fb: &VulkanImage, rect: &Rect<T>) -> 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])
}