mirror of
https://github.com/italicsjenga/vello.git
synced 2025-01-10 12:41:30 +11:00
Expose path rendering in C API
* capi: Add PathIter type and support for encoding fills * capi: Minimal support for brushes (solid color only) * Add flush method to command buffers * Better initial heuristic for memory buffer size based on target dimensions
This commit is contained in:
parent
2e8be24fc9
commit
5a127e09a5
|
@ -6,6 +6,23 @@
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <new>
|
#include <new>
|
||||||
|
|
||||||
|
enum class PgpuBrushKind {
|
||||||
|
Solid = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class PgpuFill {
|
||||||
|
NonZero = 0,
|
||||||
|
EvenOdd = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class PgpuPathVerb {
|
||||||
|
MoveTo = 0,
|
||||||
|
LineTo = 1,
|
||||||
|
QuadTo = 2,
|
||||||
|
CurveTo = 3,
|
||||||
|
Close = 4,
|
||||||
|
};
|
||||||
|
|
||||||
/// Encoded (possibly color) outline for a glyph.
|
/// Encoded (possibly color) outline for a glyph.
|
||||||
struct PgpuGlyph;
|
struct PgpuGlyph;
|
||||||
|
|
||||||
|
@ -24,6 +41,50 @@ struct PgpuScene;
|
||||||
/// Builder for constructing an encoded scene.
|
/// Builder for constructing an encoded scene.
|
||||||
struct PgpuSceneBuilder;
|
struct PgpuSceneBuilder;
|
||||||
|
|
||||||
|
/// Encoded streams and resources describing a vector graphics scene fragment.
|
||||||
|
struct PgpuSceneFragment;
|
||||||
|
|
||||||
|
/// Affine transformation matrix.
|
||||||
|
struct PgpuTransform {
|
||||||
|
float xx;
|
||||||
|
float yx;
|
||||||
|
float xy;
|
||||||
|
float yy;
|
||||||
|
float dx;
|
||||||
|
float dy;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PgpuColor {
|
||||||
|
uint8_t r;
|
||||||
|
uint8_t g;
|
||||||
|
uint8_t b;
|
||||||
|
uint8_t a;
|
||||||
|
};
|
||||||
|
|
||||||
|
union PgpuBrushData {
|
||||||
|
PgpuColor solid;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PgpuBrush {
|
||||||
|
PgpuBrushKind kind;
|
||||||
|
PgpuBrushData data;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PgpuPoint {
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PgpuPathElement {
|
||||||
|
PgpuPathVerb verb;
|
||||||
|
PgpuPoint points[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PgpuPathIter {
|
||||||
|
void *context;
|
||||||
|
bool (*next_element)(void*, PgpuPathElement*);
|
||||||
|
};
|
||||||
|
|
||||||
/// Tag and value for a font variation axis.
|
/// Tag and value for a font variation axis.
|
||||||
struct PgpuFontVariation {
|
struct PgpuFontVariation {
|
||||||
/// Tag that specifies the axis.
|
/// Tag that specifies the axis.
|
||||||
|
@ -98,14 +159,45 @@ PgpuScene *pgpu_scene_new();
|
||||||
/// Destroys the piet-gpu scene.
|
/// Destroys the piet-gpu scene.
|
||||||
void pgpu_scene_destroy(PgpuScene *scene);
|
void pgpu_scene_destroy(PgpuScene *scene);
|
||||||
|
|
||||||
|
/// Creates a new, empty piet-gpu scene fragment.
|
||||||
|
PgpuSceneFragment *pgpu_scene_fragment_new();
|
||||||
|
|
||||||
|
/// Destroys the piet-gpu scene fragment.
|
||||||
|
void pgpu_scene_fragment_destroy(PgpuSceneFragment *fragment);
|
||||||
|
|
||||||
/// Creates a new builder for filling a piet-gpu scene. The specified scene
|
/// Creates a new builder for filling a piet-gpu scene. The specified scene
|
||||||
/// should not be accessed while the builder is live.
|
/// should not be accessed while the builder is live.
|
||||||
PgpuSceneBuilder *pgpu_scene_builder_new(PgpuScene *scene);
|
PgpuSceneBuilder *pgpu_scene_builder_for_scene(PgpuScene *scene);
|
||||||
|
|
||||||
|
/// Creates a new builder for filling a piet-gpu scene fragment. The specified
|
||||||
|
/// scene fragment should not be accessed while the builder is live.
|
||||||
|
PgpuSceneBuilder *pgpu_scene_builder_for_fragment(PgpuSceneFragment *fragment);
|
||||||
|
|
||||||
/// Adds a glyph with the specified transform to the underlying scene.
|
/// Adds a glyph with the specified transform to the underlying scene.
|
||||||
void pgpu_scene_builder_add_glyph(PgpuSceneBuilder *builder,
|
void pgpu_scene_builder_add_glyph(PgpuSceneBuilder *builder,
|
||||||
const PgpuGlyph *glyph,
|
const PgpuGlyph *glyph,
|
||||||
const float (*transform)[6]);
|
const PgpuTransform *transform);
|
||||||
|
|
||||||
|
/// Sets the current absolute transform for the scene builder.
|
||||||
|
void pgpu_scene_builder_transform(PgpuSceneBuilder *builder, const PgpuTransform *transform);
|
||||||
|
|
||||||
|
/// Fills a path using the specified fill style and brush. If the brush
|
||||||
|
/// parameter is nullptr, a solid color white brush will be used. The
|
||||||
|
/// brush_transform may be nullptr.
|
||||||
|
void pgpu_scene_builder_fill_path(PgpuSceneBuilder *builder,
|
||||||
|
PgpuFill fill,
|
||||||
|
const PgpuBrush *brush,
|
||||||
|
const PgpuTransform *brush_transform,
|
||||||
|
PgpuPathIter *path);
|
||||||
|
|
||||||
|
/// Appends a scene fragment to the underlying scene or fragment. The
|
||||||
|
/// transform parameter represents an absolute transform to apply to
|
||||||
|
/// the fragment. If it is nullptr, the fragment will be appended to
|
||||||
|
/// the scene with an assumed identity transform regardless of the
|
||||||
|
/// current transform state.
|
||||||
|
void pgpu_scene_builder_append_fragment(PgpuSceneBuilder *builder,
|
||||||
|
const PgpuSceneFragment *fragment,
|
||||||
|
const PgpuTransform *transform);
|
||||||
|
|
||||||
/// Finalizes the scene builder, making the underlying scene ready for
|
/// Finalizes the scene builder, making the underlying scene ready for
|
||||||
/// rendering. This takes ownership and consumes the builder.
|
/// rendering. This takes ownership and consumes the builder.
|
||||||
|
|
|
@ -26,6 +26,9 @@
|
||||||
|
|
||||||
mod render;
|
mod render;
|
||||||
|
|
||||||
|
use piet_scene::brush::{Brush, Color};
|
||||||
|
use piet_scene::path::Element;
|
||||||
|
use piet_scene::scene::Fill;
|
||||||
use render::*;
|
use render::*;
|
||||||
use std::ffi::c_void;
|
use std::ffi::c_void;
|
||||||
use std::mem::transmute;
|
use std::mem::transmute;
|
||||||
|
@ -98,13 +101,135 @@ pub unsafe extern "C" fn pgpu_scene_destroy(scene: *mut PgpuScene) {
|
||||||
Box::from_raw(scene);
|
Box::from_raw(scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a new, empty piet-gpu scene fragment.
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn pgpu_scene_fragment_new() -> *mut PgpuSceneFragment {
|
||||||
|
Box::into_raw(Box::new(PgpuSceneFragment::new()))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Destroys the piet-gpu scene fragment.
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn pgpu_scene_fragment_destroy(fragment: *mut PgpuSceneFragment) {
|
||||||
|
Box::from_raw(fragment);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub enum PgpuPathVerb {
|
||||||
|
MoveTo = 0,
|
||||||
|
LineTo = 1,
|
||||||
|
QuadTo = 2,
|
||||||
|
CurveTo = 3,
|
||||||
|
Close = 4,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Default, Debug)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct PgpuPoint {
|
||||||
|
pub x: f32,
|
||||||
|
pub y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Rectangle defined by minimum and maximum points.
|
||||||
|
#[derive(Copy, Clone, Default)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct PgpuRect {
|
||||||
|
pub x0: f32,
|
||||||
|
pub y0: f32,
|
||||||
|
pub x1: f32,
|
||||||
|
pub y1: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct PgpuPathElement {
|
||||||
|
pub verb: PgpuPathVerb,
|
||||||
|
pub points: [PgpuPoint; 3],
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct PgpuPathIter {
|
||||||
|
pub context: *mut c_void,
|
||||||
|
pub next_element: extern "C" fn(*mut c_void, *mut PgpuPathElement) -> bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub enum PgpuFill {
|
||||||
|
NonZero = 0,
|
||||||
|
EvenOdd = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub enum PgpuBrushKind {
|
||||||
|
Solid = 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct PgpuColor {
|
||||||
|
pub r: u8,
|
||||||
|
pub g: u8,
|
||||||
|
pub b: u8,
|
||||||
|
pub a: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
pub union PgpuBrushData {
|
||||||
|
pub solid: PgpuColor,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct PgpuBrush {
|
||||||
|
pub kind: PgpuBrushKind,
|
||||||
|
pub data: PgpuBrushData,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Affine transformation matrix.
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct PgpuTransform {
|
||||||
|
pub xx: f32,
|
||||||
|
pub yx: f32,
|
||||||
|
pub xy: f32,
|
||||||
|
pub yy: f32,
|
||||||
|
pub dx: f32,
|
||||||
|
pub dy: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<PgpuTransform> for PgpuAffine {
|
||||||
|
fn from(xform: PgpuTransform) -> Self {
|
||||||
|
Self {
|
||||||
|
xx: xform.xx,
|
||||||
|
yx: xform.yx,
|
||||||
|
xy: xform.xy,
|
||||||
|
yy: xform.yy,
|
||||||
|
dx: xform.dx,
|
||||||
|
dy: xform.dy,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type PgpuAffine = piet_scene::geometry::Affine;
|
||||||
|
|
||||||
/// Creates a new builder for filling a piet-gpu scene. The specified scene
|
/// Creates a new builder for filling a piet-gpu scene. The specified scene
|
||||||
/// should not be accessed while the builder is live.
|
/// should not be accessed while the builder is live.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn pgpu_scene_builder_new(
|
pub unsafe extern "C" fn pgpu_scene_builder_for_scene(
|
||||||
scene: *mut PgpuScene,
|
scene: *mut PgpuScene,
|
||||||
) -> *mut PgpuSceneBuilder<'static> {
|
) -> *mut PgpuSceneBuilder<'static> {
|
||||||
Box::into_raw(Box::new((*scene).build()))
|
Box::into_raw(Box::new((*scene).builder()))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a new builder for filling a piet-gpu scene fragment. The specified
|
||||||
|
/// scene fragment should not be accessed while the builder is live.
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn pgpu_scene_builder_for_fragment(
|
||||||
|
fragment: *mut PgpuSceneFragment,
|
||||||
|
) -> *mut PgpuSceneBuilder<'static> {
|
||||||
|
Box::into_raw(Box::new((*fragment).builder()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds a glyph with the specified transform to the underlying scene.
|
/// Adds a glyph with the specified transform to the underlying scene.
|
||||||
|
@ -112,10 +237,103 @@ pub unsafe extern "C" fn pgpu_scene_builder_new(
|
||||||
pub unsafe extern "C" fn pgpu_scene_builder_add_glyph(
|
pub unsafe extern "C" fn pgpu_scene_builder_add_glyph(
|
||||||
builder: *mut PgpuSceneBuilder<'static>,
|
builder: *mut PgpuSceneBuilder<'static>,
|
||||||
glyph: *const PgpuGlyph,
|
glyph: *const PgpuGlyph,
|
||||||
transform: &[f32; 6],
|
transform: *const PgpuTransform,
|
||||||
) {
|
) {
|
||||||
let transform = piet_scene::geometry::Affine::new(transform);
|
(*builder).add_glyph(&*glyph, &(*transform).into());
|
||||||
(*builder).add_glyph(&*glyph, &transform);
|
}
|
||||||
|
|
||||||
|
impl Iterator for PgpuPathIter {
|
||||||
|
type Item = piet_scene::path::Element;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
let mut el = PgpuPathElement {
|
||||||
|
verb: PgpuPathVerb::MoveTo,
|
||||||
|
points: [PgpuPoint::default(); 3],
|
||||||
|
};
|
||||||
|
if (self.next_element)(self.context, &mut el as _) {
|
||||||
|
let p = &el.points;
|
||||||
|
Some(match el.verb {
|
||||||
|
PgpuPathVerb::MoveTo => Element::MoveTo((p[0].x, p[0].y).into()),
|
||||||
|
PgpuPathVerb::LineTo => Element::LineTo((p[0].x, p[0].y).into()),
|
||||||
|
PgpuPathVerb::QuadTo => {
|
||||||
|
Element::QuadTo((p[0].x, p[0].y).into(), (p[1].x, p[1].y).into())
|
||||||
|
}
|
||||||
|
PgpuPathVerb::CurveTo => Element::CurveTo(
|
||||||
|
(p[0].x, p[0].y).into(),
|
||||||
|
(p[1].x, p[1].y).into(),
|
||||||
|
(p[2].x, p[2].y).into(),
|
||||||
|
),
|
||||||
|
PgpuPathVerb::Close => Element::Close,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the current absolute transform for the scene builder.
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn pgpu_scene_builder_transform(
|
||||||
|
builder: *mut PgpuSceneBuilder<'static>,
|
||||||
|
transform: *const PgpuTransform,
|
||||||
|
) {
|
||||||
|
if !transform.is_null() {
|
||||||
|
(*builder).0.transform((*transform).into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Fills a path using the specified fill style and brush. If the brush
|
||||||
|
/// parameter is nullptr, a solid color white brush will be used. The
|
||||||
|
/// brush_transform may be nullptr.
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn pgpu_scene_builder_fill_path(
|
||||||
|
builder: *mut PgpuSceneBuilder<'static>,
|
||||||
|
fill: PgpuFill,
|
||||||
|
brush: *const PgpuBrush,
|
||||||
|
brush_transform: *const PgpuTransform,
|
||||||
|
path: *mut PgpuPathIter,
|
||||||
|
) {
|
||||||
|
let fill = match fill {
|
||||||
|
PgpuFill::NonZero => Fill::NonZero,
|
||||||
|
PgpuFill::EvenOdd => Fill::EvenOdd,
|
||||||
|
};
|
||||||
|
let brush = if brush.is_null() {
|
||||||
|
Brush::Solid(Color::rgb8(255, 255, 255))
|
||||||
|
} else {
|
||||||
|
match (*brush).kind {
|
||||||
|
PgpuBrushKind::Solid => {
|
||||||
|
let color = &(*brush).data.solid;
|
||||||
|
Brush::Solid(Color::rgba8(color.r, color.g, color.b, color.a))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let brush_transform = if brush_transform.is_null() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some((*brush_transform).into())
|
||||||
|
};
|
||||||
|
(*builder)
|
||||||
|
.0
|
||||||
|
.fill(fill, &brush, brush_transform, (*path).clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Appends a scene fragment to the underlying scene or fragment. The
|
||||||
|
/// transform parameter represents an absolute transform to apply to
|
||||||
|
/// the fragment. If it is nullptr, the fragment will be appended to
|
||||||
|
/// the scene with an assumed identity transform regardless of the
|
||||||
|
/// current transform state.
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn pgpu_scene_builder_append_fragment(
|
||||||
|
builder: *mut PgpuSceneBuilder<'static>,
|
||||||
|
fragment: *const PgpuSceneFragment,
|
||||||
|
transform: *const PgpuTransform,
|
||||||
|
) {
|
||||||
|
let transform = if transform.is_null() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some((*transform).into())
|
||||||
|
};
|
||||||
|
(*builder).0.append(&(*fragment).0, transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finalizes the scene builder, making the underlying scene ready for
|
/// Finalizes the scene builder, making the underlying scene ready for
|
||||||
|
@ -220,16 +438,6 @@ pub unsafe extern "C" fn pgpu_glyph_provider_destroy(provider: *mut PgpuGlyphPro
|
||||||
Box::from_raw(provider);
|
Box::from_raw(provider);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rectangle defined by minimum and maximum points.
|
|
||||||
#[derive(Copy, Clone, Default)]
|
|
||||||
#[repr(C)]
|
|
||||||
pub struct PgpuRect {
|
|
||||||
pub x0: f32,
|
|
||||||
pub y0: f32,
|
|
||||||
pub x1: f32,
|
|
||||||
pub y1: f32,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Computes the bounding box for the glyph after applying the specified
|
/// Computes the bounding box for the glyph after applying the specified
|
||||||
/// transform.
|
/// transform.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
|
|
@ -61,7 +61,7 @@ impl PgpuRenderer {
|
||||||
cmdbuf: &metal::CommandBufferRef,
|
cmdbuf: &metal::CommandBufferRef,
|
||||||
target: &metal::TextureRef,
|
target: &metal::TextureRef,
|
||||||
) -> u32 {
|
) -> u32 {
|
||||||
let is_color = target.pixel_format() != metal::MTLPixelFormat::A8Unorm;
|
let is_color = target.pixel_format() != metal::MTLPixelFormat::R8Unorm;
|
||||||
let width = target.width() as u32;
|
let width = target.width() as u32;
|
||||||
let height = target.height() as u32;
|
let height = target.height() as u32;
|
||||||
if self.pgpu_renderer.is_none()
|
if self.pgpu_renderer.is_none()
|
||||||
|
@ -93,6 +93,7 @@ impl PgpuRenderer {
|
||||||
renderer.record(&mut cmd_buf, &self.query_pool, 0);
|
renderer.record(&mut cmd_buf, &self.query_pool, 0);
|
||||||
// TODO later: we can bind the destination image and avoid the copy.
|
// TODO later: we can bind the destination image and avoid the copy.
|
||||||
cmd_buf.blit_image(&renderer.image_dev, &dst_image);
|
cmd_buf.blit_image(&renderer.image_dev, &dst_image);
|
||||||
|
cmd_buf.flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
0
|
0
|
||||||
|
@ -117,7 +118,7 @@ impl PgpuScene {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(&mut self) -> PgpuSceneBuilder {
|
pub fn builder(&mut self) -> PgpuSceneBuilder {
|
||||||
self.rcx.advance();
|
self.rcx.advance();
|
||||||
PgpuSceneBuilder(piet_scene::scene::build_scene(
|
PgpuSceneBuilder(piet_scene::scene::build_scene(
|
||||||
&mut self.scene,
|
&mut self.scene,
|
||||||
|
@ -142,8 +143,21 @@ impl PgpuScene {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Encoded streams and resources describing a vector graphics scene fragment.
|
||||||
|
pub struct PgpuSceneFragment(pub Fragment);
|
||||||
|
|
||||||
|
impl PgpuSceneFragment {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self(Fragment::default())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn builder(&mut self) -> PgpuSceneBuilder {
|
||||||
|
PgpuSceneBuilder(piet_scene::scene::build_fragment(&mut self.0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Builder for constructing an encoded scene.
|
/// Builder for constructing an encoded scene.
|
||||||
pub struct PgpuSceneBuilder<'a>(piet_scene::scene::Builder<'a>);
|
pub struct PgpuSceneBuilder<'a>(pub piet_scene::scene::Builder<'a>);
|
||||||
|
|
||||||
impl<'a> PgpuSceneBuilder<'a> {
|
impl<'a> PgpuSceneBuilder<'a> {
|
||||||
pub fn add_glyph(&mut self, glyph: &PgpuGlyph, transform: &piet_scene::geometry::Affine) {
|
pub fn add_glyph(&mut self, glyph: &PgpuGlyph, transform: &piet_scene::geometry::Affine) {
|
||||||
|
|
|
@ -205,6 +205,9 @@ pub trait CmdBuf<D: Device> {
|
||||||
/// State: ready -> finished
|
/// State: ready -> finished
|
||||||
unsafe fn finish(&mut self);
|
unsafe fn finish(&mut self);
|
||||||
|
|
||||||
|
/// Commits any open command encoder.
|
||||||
|
unsafe fn flush(&mut self);
|
||||||
|
|
||||||
/// Return true if the command buffer is suitable for reuse.
|
/// Return true if the command buffer is suitable for reuse.
|
||||||
unsafe fn reset(&mut self) -> bool;
|
unsafe fn reset(&mut self) -> bool;
|
||||||
|
|
||||||
|
|
|
@ -631,6 +631,8 @@ impl crate::backend::CmdBuf<Dx12Device> for CmdBuf {
|
||||||
self.needs_reset = true;
|
self.needs_reset = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe fn flush(&mut self) {}
|
||||||
|
|
||||||
unsafe fn reset(&mut self) -> bool {
|
unsafe fn reset(&mut self) -> bool {
|
||||||
self.allocator.reset().is_ok() && self.c.reset(&self.allocator, None).is_ok()
|
self.allocator.reset().is_ok() && self.c.reset(&self.allocator, None).is_ok()
|
||||||
}
|
}
|
||||||
|
|
|
@ -509,6 +509,11 @@ impl CmdBuf {
|
||||||
self.cmd_buf().finish();
|
self.cmd_buf().finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Commits any open command encoder.
|
||||||
|
pub unsafe fn flush(&mut self) {
|
||||||
|
self.cmd_buf().flush();
|
||||||
|
}
|
||||||
|
|
||||||
/// Begin a compute pass.
|
/// Begin a compute pass.
|
||||||
pub unsafe fn begin_compute_pass(&mut self, desc: &ComputePassDescriptor) -> ComputePass {
|
pub unsafe fn begin_compute_pass(&mut self, desc: &ComputePassDescriptor) -> ComputePass {
|
||||||
self.cmd_buf().begin_compute_pass(desc);
|
self.cmd_buf().begin_compute_pass(desc);
|
||||||
|
|
|
@ -590,6 +590,10 @@ impl crate::backend::CmdBuf<MtlDevice> for CmdBuf {
|
||||||
self.flush_encoder();
|
self.flush_encoder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe fn flush(&mut self) {
|
||||||
|
self.flush_encoder();
|
||||||
|
}
|
||||||
|
|
||||||
unsafe fn reset(&mut self) -> bool {
|
unsafe fn reset(&mut self) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
|
@ -675,6 +675,14 @@ impl CmdBuf {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub unsafe fn flush(&mut self) {
|
||||||
|
mux_match! { self;
|
||||||
|
CmdBuf::Vk(c) => c.flush(),
|
||||||
|
CmdBuf::Dx12(c) => c.flush(),
|
||||||
|
CmdBuf::Mtl(c) => c.flush(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub unsafe fn finish(&mut self) {
|
pub unsafe fn finish(&mut self) {
|
||||||
mux_match! { self;
|
mux_match! { self;
|
||||||
CmdBuf::Vk(c) => c.finish(),
|
CmdBuf::Vk(c) => c.finish(),
|
||||||
|
|
|
@ -967,6 +967,8 @@ impl crate::backend::CmdBuf<VkDevice> for CmdBuf {
|
||||||
self.device.device.end_command_buffer(self.cmd_buf).unwrap();
|
self.device.device.end_command_buffer(self.cmd_buf).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe fn flush(&mut self) {}
|
||||||
|
|
||||||
unsafe fn reset(&mut self) -> bool {
|
unsafe fn reset(&mut self) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
|
@ -243,7 +243,10 @@ impl Renderer {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
let memory_buf_dev = session.create_buffer(16 * 1024 * 1024, usage_mem_dev)?;
|
let target_dependent_size =
|
||||||
|
(width / TILE_W) as u64 * (height / TILE_H) as u64 * PTCL_INITIAL_ALLOC as u64;
|
||||||
|
let memory_buf_dev =
|
||||||
|
session.create_buffer(target_dependent_size + 8 * 1024 * 1024, usage_mem_dev)?;
|
||||||
let memory_buf_readback =
|
let memory_buf_readback =
|
||||||
session.create_buffer(std::mem::size_of::<MemoryHeader>() as u64, usage_readback)?;
|
session.create_buffer(std::mem::size_of::<MemoryHeader>() as u64, usage_readback)?;
|
||||||
let blend_buf = session.create_buffer(16 * 1024 * 1024, usage_blend)?;
|
let blend_buf = session.create_buffer(16 * 1024 * 1024, usage_blend)?;
|
||||||
|
|
Loading…
Reference in a new issue