vulkan: split renderer paint regions
This commit is contained in:
parent
8c61a3150b
commit
959f23f61b
2 changed files with 123 additions and 117 deletions
|
|
@ -1,7 +1,9 @@
|
||||||
mod color;
|
mod color;
|
||||||
|
mod paint_region;
|
||||||
|
|
||||||
use {
|
use {
|
||||||
color::{ColorTransforms, EotfArgsCache},
|
color::{ColorTransforms, EotfArgsCache},
|
||||||
|
paint_region::{PaintRegion, Point, constrain_to_fb},
|
||||||
crate::{
|
crate::{
|
||||||
async_engine::{AsyncEngine, SpawnedFuture},
|
async_engine::{AsyncEngine, SpawnedFuture},
|
||||||
cmm::{
|
cmm::{
|
||||||
|
|
@ -69,7 +71,6 @@ use {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
isnt::std_1::{collections::IsntHashMapExt, primitive::IsntSliceExt},
|
isnt::std_1::{collections::IsntHashMapExt, primitive::IsntSliceExt},
|
||||||
jay_algorithms::rect::Tag,
|
|
||||||
linearize::{Linearize, LinearizeExt, StaticMap, static_map},
|
linearize::{Linearize, LinearizeExt, StaticMap, static_map},
|
||||||
std::{
|
std::{
|
||||||
any::Any,
|
any::Any,
|
||||||
|
|
@ -209,8 +210,6 @@ pub(super) struct Memory {
|
||||||
fb_inv_eotf_args_address: Option<DeviceSize>,
|
fb_inv_eotf_args_address: Option<DeviceSize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
type Point = [[f32; 2]; 4];
|
|
||||||
|
|
||||||
enum VulkanOp {
|
enum VulkanOp {
|
||||||
Fill(VulkanFillOp),
|
Fill(VulkanFillOp),
|
||||||
Tex(VulkanTexOp),
|
Tex(VulkanTexOp),
|
||||||
|
|
@ -285,14 +284,6 @@ pub(super) enum RenderPass {
|
||||||
FrameBuffer,
|
FrameBuffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
struct PaintRegion {
|
|
||||||
x1: f32,
|
|
||||||
y1: f32,
|
|
||||||
x2: f32,
|
|
||||||
y2: f32,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) struct PendingFrame {
|
pub(super) struct PendingFrame {
|
||||||
point: u64,
|
point: u64,
|
||||||
renderer: Rc<VulkanRenderer>,
|
renderer: Rc<VulkanRenderer>,
|
||||||
|
|
@ -2722,109 +2713,3 @@ async fn await_release(
|
||||||
}
|
}
|
||||||
renderer.pending_frames.remove(&frame.point);
|
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])
|
|
||||||
}
|
|
||||||
|
|
|
||||||
121
src/gfx_apis/vulkan/renderer/paint_region.rs
Normal file
121
src/gfx_apis/vulkan/renderer/paint_region.rs
Normal 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])
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue