Allow any texture format to be uploaded; fix Metal compilation on newer rustcs
This commit is contained in:
parent
7c655246ae
commit
0662f6433f
|
@ -179,7 +179,7 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gl 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gl 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"metal 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"metal 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"objc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"objc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pathfinder_canvas 0.1.0",
|
"pathfinder_canvas 0.1.0",
|
||||||
"pathfinder_content 0.1.0",
|
"pathfinder_content 0.1.0",
|
||||||
|
@ -530,7 +530,7 @@ dependencies = [
|
||||||
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gl 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gl 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"jemallocator 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"jemallocator 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"metal 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"metal 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"nfd 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"nfd 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pathfinder_demo 0.1.0",
|
"pathfinder_demo 0.1.0",
|
||||||
"pathfinder_geometry 0.3.0",
|
"pathfinder_geometry 0.3.0",
|
||||||
|
@ -1257,23 +1257,6 @@ dependencies = [
|
||||||
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "metal"
|
|
||||||
version = "0.14.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"cocoa 0.18.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"core-graphics 0.17.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"objc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"objc-foundation 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"objc_id 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "metal"
|
name = "metal"
|
||||||
version = "0.17.1"
|
version = "0.17.1"
|
||||||
|
@ -1406,16 +1389,6 @@ dependencies = [
|
||||||
"objc_exception 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"objc_exception 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "objc-foundation"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"objc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"objc_id 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "objc_exception"
|
name = "objc_exception"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
|
@ -1424,14 +1397,6 @@ dependencies = [
|
||||||
"gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "objc_id"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"objc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ordered-float"
|
name = "ordered-float"
|
||||||
version = "1.0.2"
|
version = "1.0.2"
|
||||||
|
@ -1524,7 +1489,7 @@ dependencies = [
|
||||||
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gl 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gl 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"metal 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"metal 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pathfinder_canvas 0.1.0",
|
"pathfinder_canvas 0.1.0",
|
||||||
"pathfinder_content 0.1.0",
|
"pathfinder_content 0.1.0",
|
||||||
"pathfinder_geometry 0.3.0",
|
"pathfinder_geometry 0.3.0",
|
||||||
|
@ -1567,7 +1532,7 @@ dependencies = [
|
||||||
"gl 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gl 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"image 0.21.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"image 0.21.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"metal 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"metal 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pathfinder_content 0.1.0",
|
"pathfinder_content 0.1.0",
|
||||||
"pathfinder_export 0.1.0",
|
"pathfinder_export 0.1.0",
|
||||||
"pathfinder_geometry 0.3.0",
|
"pathfinder_geometry 0.3.0",
|
||||||
|
@ -1605,6 +1570,7 @@ name = "pathfinder_gl"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gl 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gl 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"half 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pathfinder_geometry 0.3.0",
|
"pathfinder_geometry 0.3.0",
|
||||||
"pathfinder_gpu 0.1.0",
|
"pathfinder_gpu 0.1.0",
|
||||||
|
@ -1615,6 +1581,7 @@ dependencies = [
|
||||||
name = "pathfinder_gpu"
|
name = "pathfinder_gpu"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"half 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"image 0.21.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"image 0.21.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pathfinder_content 0.1.0",
|
"pathfinder_content 0.1.0",
|
||||||
"pathfinder_geometry 0.3.0",
|
"pathfinder_geometry 0.3.0",
|
||||||
|
@ -1662,6 +1629,7 @@ dependencies = [
|
||||||
"cocoa 0.19.1 (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)",
|
"core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"foreign-types 0.3.2 (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.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"metal 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"metal 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"objc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"objc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pathfinder_geometry 0.3.0",
|
"pathfinder_geometry 0.3.0",
|
||||||
|
@ -2919,7 +2887,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
|
"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
|
||||||
"checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b"
|
"checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b"
|
||||||
"checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9"
|
"checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9"
|
||||||
"checksum metal 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cd3f21d259068945192293b7a98b1c6844af9eb7602e393c405198b229efc157"
|
|
||||||
"checksum metal 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f83c7dcc2038e12f68493fa3de44235df27b2497178e257185b4b5b5d028a1e4"
|
"checksum metal 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f83c7dcc2038e12f68493fa3de44235df27b2497178e257185b4b5b5d028a1e4"
|
||||||
"checksum nfd 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8e752e3c216bc8a491c5b59fa46da10f1379ae450b19ac688e07f4bb55042e98"
|
"checksum nfd 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8e752e3c216bc8a491c5b59fa46da10f1379ae450b19ac688e07f4bb55042e98"
|
||||||
"checksum nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce"
|
"checksum nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce"
|
||||||
|
@ -2934,9 +2901,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"checksum num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "443c53b3c3531dfcbfa499d8893944db78474ad7a1d87fa2d94d1a2231693ac6"
|
"checksum num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "443c53b3c3531dfcbfa499d8893944db78474ad7a1d87fa2d94d1a2231693ac6"
|
||||||
"checksum num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76dac5ed2a876980778b8b85f75a71b6cbf0db0b1232ee12f826bccb00d09d72"
|
"checksum num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76dac5ed2a876980778b8b85f75a71b6cbf0db0b1232ee12f826bccb00d09d72"
|
||||||
"checksum objc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1"
|
"checksum objc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1"
|
||||||
"checksum objc-foundation 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9"
|
|
||||||
"checksum objc_exception 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "098cd29a2fa3c230d3463ae069cecccc3fdfd64c0d2496ab5b96f82dab6a00dc"
|
"checksum objc_exception 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "098cd29a2fa3c230d3463ae069cecccc3fdfd64c0d2496ab5b96f82dab6a00dc"
|
||||||
"checksum objc_id 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b"
|
|
||||||
"checksum ordered-float 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "18869315e81473c951eb56ad5558bbc56978562d3ecfb87abb7a1e944cea4518"
|
"checksum ordered-float 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "18869315e81473c951eb56ad5558bbc56978562d3ecfb87abb7a1e944cea4518"
|
||||||
"checksum osmesa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88cfece6e95d2e717e0872a7f53a8684712ad13822a7979bc760b9c77ec0013b"
|
"checksum osmesa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88cfece6e95d2e717e0872a7f53a8684712ad13822a7979bc760b9c77ec0013b"
|
||||||
"checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13"
|
"checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13"
|
||||||
|
|
|
@ -37,7 +37,7 @@ path = "../renderer"
|
||||||
path = "../simd"
|
path = "../simd"
|
||||||
|
|
||||||
[target.'cfg(target_os = "macos")'.dependencies]
|
[target.'cfg(target_os = "macos")'.dependencies]
|
||||||
metal = "0.14"
|
metal = "0.17"
|
||||||
|
|
||||||
[target.'cfg(target_os = "macos")'.dependencies.pathfinder_metal]
|
[target.'cfg(target_os = "macos")'.dependencies.pathfinder_metal]
|
||||||
path = "../metal"
|
path = "../metal"
|
||||||
|
|
|
@ -50,7 +50,7 @@ path = "../../svg"
|
||||||
path = "../../ui"
|
path = "../../ui"
|
||||||
|
|
||||||
[target.'cfg(target_os = "macos")'.dependencies]
|
[target.'cfg(target_os = "macos")'.dependencies]
|
||||||
metal = "0.14"
|
metal = "0.17"
|
||||||
|
|
||||||
[target.'cfg(target_os = "macos")'.dependencies.pathfinder_metal]
|
[target.'cfg(target_os = "macos")'.dependencies.pathfinder_metal]
|
||||||
path = "../../metal"
|
path = "../../metal"
|
||||||
|
|
|
@ -298,7 +298,7 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
let viewport = RectI::new(Vector2I::default(), drawable_size);
|
let viewport = RectI::new(Vector2I::default(), drawable_size);
|
||||||
let pixels = match self.renderer.device.read_pixels(&RenderTarget::Default, viewport) {
|
let pixels = match self.renderer.device.read_pixels(&RenderTarget::Default, viewport) {
|
||||||
TextureData::U8(pixels) => pixels,
|
TextureData::U8(pixels) => pixels,
|
||||||
TextureData::U16(_) => panic!("Unexpected pixel format for default framebuffer!"),
|
_ => panic!("Unexpected pixel format for default framebuffer!"),
|
||||||
};
|
};
|
||||||
image::save_buffer(
|
image::save_buffer(
|
||||||
path,
|
path,
|
||||||
|
|
|
@ -33,7 +33,7 @@ path = "../../simd"
|
||||||
|
|
||||||
[target.'cfg(target_os = "macos")'.dependencies]
|
[target.'cfg(target_os = "macos")'.dependencies]
|
||||||
foreign-types = "0.3"
|
foreign-types = "0.3"
|
||||||
metal = "0.14"
|
metal = "0.17"
|
||||||
|
|
||||||
[target.'cfg(target_os = "macos")'.dependencies.pathfinder_metal]
|
[target.'cfg(target_os = "macos")'.dependencies.pathfinder_metal]
|
||||||
path = "../../metal"
|
path = "../../metal"
|
||||||
|
|
|
@ -7,7 +7,7 @@ edition = "2018"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
foreign-types = "0.3"
|
foreign-types = "0.3"
|
||||||
gl = "0.6"
|
gl = "0.6"
|
||||||
metal = "0.14"
|
metal = "0.17"
|
||||||
objc = "0.2"
|
objc = "0.2"
|
||||||
sdl2 = "0.32"
|
sdl2 = "0.32"
|
||||||
sdl2-sys = "0.32"
|
sdl2-sys = "0.32"
|
||||||
|
|
|
@ -9,6 +9,7 @@ crate-type = ["rlib", "staticlib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
gl = "0.6"
|
gl = "0.6"
|
||||||
|
half = "1.4"
|
||||||
|
|
||||||
[dependencies.log]
|
[dependencies.log]
|
||||||
version = "0.4"
|
version = "0.4"
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
|
||||||
use gl::types::{GLboolean, GLchar, GLenum, GLfloat, GLint, GLsizei, GLsizeiptr, GLuint, GLvoid};
|
use gl::types::{GLboolean, GLchar, GLenum, GLfloat, GLint, GLsizei, GLsizeiptr, GLuint, GLvoid};
|
||||||
|
use half::f16;
|
||||||
use pathfinder_geometry::rect::RectI;
|
use pathfinder_geometry::rect::RectI;
|
||||||
use pathfinder_geometry::vector::Vector2I;
|
use pathfinder_geometry::vector::Vector2I;
|
||||||
use pathfinder_gpu::resources::ResourceLoader;
|
use pathfinder_gpu::resources::ResourceLoader;
|
||||||
|
@ -256,25 +257,7 @@ impl Device for GLDevice {
|
||||||
|
|
||||||
fn create_texture_from_data(&self, format: TextureFormat, size: Vector2I, data: TextureDataRef)
|
fn create_texture_from_data(&self, format: TextureFormat, size: Vector2I, data: TextureDataRef)
|
||||||
-> GLTexture {
|
-> GLTexture {
|
||||||
let channels = match (format, data) {
|
let data_ptr = data.check_and_extract_data_ptr(size, format);
|
||||||
(TextureFormat::R8, TextureDataRef::U8(_)) => 1,
|
|
||||||
(TextureFormat::RGBA8, TextureDataRef::U8(_)) => 4,
|
|
||||||
(TextureFormat::RGBA32F, TextureDataRef::F32(_)) => 4,
|
|
||||||
_ => panic!("Unimplemented texture format in `create_texture_from_data`!"),
|
|
||||||
};
|
|
||||||
|
|
||||||
let area = size.x() as usize * size.y() as usize;
|
|
||||||
let data_ptr = match data {
|
|
||||||
TextureDataRef::U8(data) => {
|
|
||||||
assert!(data.len() >= area * channels);
|
|
||||||
data.as_ptr() as *const GLvoid
|
|
||||||
}
|
|
||||||
TextureDataRef::F32(data) => {
|
|
||||||
assert!(data.len() >= area * channels);
|
|
||||||
data.as_ptr() as *const GLvoid
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut texture = GLTexture { gl_texture: 0, size, format: TextureFormat::R8 };
|
let mut texture = GLTexture { gl_texture: 0, size, format: TextureFormat::R8 };
|
||||||
unsafe {
|
unsafe {
|
||||||
gl::GenTextures(1, &mut texture.gl_texture); ck();
|
gl::GenTextures(1, &mut texture.gl_texture); ck();
|
||||||
|
@ -489,20 +472,37 @@ impl Device for GLDevice {
|
||||||
texture.size
|
texture.size
|
||||||
}
|
}
|
||||||
|
|
||||||
fn upload_to_texture(&self, texture: &Self::Texture, size: Vector2I, data: &[u8]) {
|
fn upload_to_texture(&self, texture: &Self::Texture, rect: RectI, data: TextureDataRef) {
|
||||||
// FIXME(pcwalton): Fix size issues!!
|
let data_ptr = data.check_and_extract_data_ptr(rect.size(), texture.format);
|
||||||
assert!(data.len() >= size.x() as usize * size.y() as usize * 4);
|
|
||||||
|
assert!(rect.size().x() >= 0);
|
||||||
|
assert!(rect.size().y() >= 0);
|
||||||
|
assert!(rect.max_x() <= texture.size.x());
|
||||||
|
assert!(rect.max_y() <= texture.size.y());
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
self.bind_texture(texture, 0);
|
self.bind_texture(texture, 0);
|
||||||
|
if rect.origin() == Vector2I::default() && rect.size() == texture.size {
|
||||||
gl::TexImage2D(gl::TEXTURE_2D,
|
gl::TexImage2D(gl::TEXTURE_2D,
|
||||||
0,
|
0,
|
||||||
texture.format.gl_internal_format(),
|
texture.format.gl_internal_format(),
|
||||||
size.x() as GLsizei,
|
texture.size.x() as GLsizei,
|
||||||
size.y() as GLsizei,
|
texture.size.y() as GLsizei,
|
||||||
0,
|
0,
|
||||||
texture.format.gl_format(),
|
texture.format.gl_format(),
|
||||||
texture.format.gl_type(),
|
texture.format.gl_type(),
|
||||||
data.as_ptr() as *const GLvoid); ck();
|
data_ptr); ck();
|
||||||
|
} else {
|
||||||
|
gl::TexSubImage2D(gl::TEXTURE_2D,
|
||||||
|
0,
|
||||||
|
rect.origin().x(),
|
||||||
|
rect.origin().y(),
|
||||||
|
rect.size().x() as GLsizei,
|
||||||
|
rect.size().y() as GLsizei,
|
||||||
|
texture.format.gl_format(),
|
||||||
|
texture.format.gl_type(),
|
||||||
|
data_ptr); ck();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.set_texture_parameters(texture);
|
self.set_texture_parameters(texture);
|
||||||
|
@ -529,8 +529,10 @@ impl Device for GLDevice {
|
||||||
flip_y(&mut pixels, size, channels);
|
flip_y(&mut pixels, size, channels);
|
||||||
TextureData::U8(pixels)
|
TextureData::U8(pixels)
|
||||||
}
|
}
|
||||||
TextureFormat::R16F => {
|
TextureFormat::R16F | TextureFormat::RGBA16F => {
|
||||||
let mut pixels = vec![0; size.x() as usize * size.y() as usize];
|
let channels = format.channels();
|
||||||
|
let mut pixels =
|
||||||
|
vec![f16::default(); size.x() as usize * size.y() as usize * channels];
|
||||||
unsafe {
|
unsafe {
|
||||||
gl::ReadPixels(origin.x(),
|
gl::ReadPixels(origin.x(),
|
||||||
origin.y(),
|
origin.y(),
|
||||||
|
@ -540,8 +542,8 @@ impl Device for GLDevice {
|
||||||
format.gl_type(),
|
format.gl_type(),
|
||||||
pixels.as_mut_ptr() as *mut GLvoid); ck();
|
pixels.as_mut_ptr() as *mut GLvoid); ck();
|
||||||
}
|
}
|
||||||
flip_y(&mut pixels, size, 1);
|
flip_y(&mut pixels, size, channels);
|
||||||
TextureData::U16(pixels)
|
TextureData::F16(pixels)
|
||||||
}
|
}
|
||||||
TextureFormat::RGBA32F => {
|
TextureFormat::RGBA32F => {
|
||||||
let channels = format.channels();
|
let channels = format.channels();
|
||||||
|
@ -991,6 +993,7 @@ impl TextureFormatExt for TextureFormat {
|
||||||
TextureFormat::R8 => gl::R8 as GLint,
|
TextureFormat::R8 => gl::R8 as GLint,
|
||||||
TextureFormat::R16F => gl::R16F as GLint,
|
TextureFormat::R16F => gl::R16F as GLint,
|
||||||
TextureFormat::RGBA8 => gl::RGBA as GLint,
|
TextureFormat::RGBA8 => gl::RGBA as GLint,
|
||||||
|
TextureFormat::RGBA16F => gl::RGBA16F as GLint,
|
||||||
TextureFormat::RGBA32F => gl::RGBA32F as GLint,
|
TextureFormat::RGBA32F => gl::RGBA32F as GLint,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -998,14 +1001,14 @@ impl TextureFormatExt for TextureFormat {
|
||||||
fn gl_format(self) -> GLuint {
|
fn gl_format(self) -> GLuint {
|
||||||
match self {
|
match self {
|
||||||
TextureFormat::R8 | TextureFormat::R16F => gl::RED,
|
TextureFormat::R8 | TextureFormat::R16F => gl::RED,
|
||||||
TextureFormat::RGBA8 | TextureFormat::RGBA32F => gl::RGBA,
|
TextureFormat::RGBA8 | TextureFormat::RGBA16F | TextureFormat::RGBA32F => gl::RGBA,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gl_type(self) -> GLuint {
|
fn gl_type(self) -> GLuint {
|
||||||
match self {
|
match self {
|
||||||
TextureFormat::R8 | TextureFormat::RGBA8 => gl::UNSIGNED_BYTE,
|
TextureFormat::R8 | TextureFormat::RGBA8 => gl::UNSIGNED_BYTE,
|
||||||
TextureFormat::R16F => gl::HALF_FLOAT,
|
TextureFormat::R16F | TextureFormat::RGBA16F => gl::HALF_FLOAT,
|
||||||
TextureFormat::RGBA32F => gl::FLOAT,
|
TextureFormat::RGBA32F => gl::FLOAT,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ authors = ["Patrick Walton <pcwalton@mimiga.net>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
half = "1.4"
|
||||||
|
|
||||||
[dependencies.image]
|
[dependencies.image]
|
||||||
version = "0.21"
|
version = "0.21"
|
||||||
|
|
|
@ -11,12 +11,14 @@
|
||||||
//! Minimal abstractions over GPU device capabilities.
|
//! Minimal abstractions over GPU device capabilities.
|
||||||
|
|
||||||
use crate::resources::ResourceLoader;
|
use crate::resources::ResourceLoader;
|
||||||
|
use half::f16;
|
||||||
use image::ImageFormat;
|
use image::ImageFormat;
|
||||||
use pathfinder_content::color::ColorF;
|
use pathfinder_content::color::ColorF;
|
||||||
use pathfinder_geometry::rect::RectI;
|
use pathfinder_geometry::rect::RectI;
|
||||||
use pathfinder_geometry::transform3d::Transform4F;
|
use pathfinder_geometry::transform3d::Transform4F;
|
||||||
use pathfinder_geometry::vector::Vector2I;
|
use pathfinder_geometry::vector::Vector2I;
|
||||||
use pathfinder_simd::default::{F32x2, F32x4};
|
use pathfinder_simd::default::{F32x2, F32x4};
|
||||||
|
use std::os::raw::c_void;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
pub mod resources;
|
pub mod resources;
|
||||||
|
@ -68,7 +70,7 @@ pub trait Device: Sized {
|
||||||
);
|
);
|
||||||
fn framebuffer_texture<'f>(&self, framebuffer: &'f Self::Framebuffer) -> &'f Self::Texture;
|
fn framebuffer_texture<'f>(&self, framebuffer: &'f Self::Framebuffer) -> &'f Self::Texture;
|
||||||
fn texture_size(&self, texture: &Self::Texture) -> Vector2I;
|
fn texture_size(&self, texture: &Self::Texture) -> Vector2I;
|
||||||
fn upload_to_texture(&self, texture: &Self::Texture, size: Vector2I, data: &[u8]);
|
fn upload_to_texture(&self, texture: &Self::Texture, rect: RectI, data: TextureDataRef);
|
||||||
fn read_pixels(&self, target: &RenderTarget<Self>, viewport: RectI) -> TextureData;
|
fn read_pixels(&self, target: &RenderTarget<Self>, viewport: RectI) -> TextureData;
|
||||||
fn begin_commands(&self);
|
fn begin_commands(&self);
|
||||||
fn end_commands(&self);
|
fn end_commands(&self);
|
||||||
|
@ -115,6 +117,7 @@ pub enum TextureFormat {
|
||||||
R8,
|
R8,
|
||||||
R16F,
|
R16F,
|
||||||
RGBA8,
|
RGBA8,
|
||||||
|
RGBA16F,
|
||||||
RGBA32F,
|
RGBA32F,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,12 +307,14 @@ impl Default for StencilFunc {
|
||||||
pub enum TextureData {
|
pub enum TextureData {
|
||||||
U8(Vec<u8>),
|
U8(Vec<u8>),
|
||||||
U16(Vec<u16>),
|
U16(Vec<u16>),
|
||||||
|
F16(Vec<f16>),
|
||||||
F32(Vec<f32>),
|
F32(Vec<f32>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub enum TextureDataRef<'a> {
|
pub enum TextureDataRef<'a> {
|
||||||
U8(&'a [u8]),
|
U8(&'a [u8]),
|
||||||
|
F16(&'a [f16]),
|
||||||
F32(&'a [f32]),
|
F32(&'a [f32]),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,7 +348,18 @@ impl TextureFormat {
|
||||||
pub fn channels(self) -> usize {
|
pub fn channels(self) -> usize {
|
||||||
match self {
|
match self {
|
||||||
TextureFormat::R8 | TextureFormat::R16F => 1,
|
TextureFormat::R8 | TextureFormat::R16F => 1,
|
||||||
TextureFormat::RGBA8 | TextureFormat::RGBA32F => 4,
|
TextureFormat::RGBA8 | TextureFormat::RGBA16F | TextureFormat::RGBA32F => 4,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn bytes_per_pixel(self) -> usize {
|
||||||
|
match self {
|
||||||
|
TextureFormat::R8 => 1,
|
||||||
|
TextureFormat::R16F => 2,
|
||||||
|
TextureFormat::RGBA8 => 4,
|
||||||
|
TextureFormat::RGBA16F => 8,
|
||||||
|
TextureFormat::RGBA32F => 16,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -354,3 +370,34 @@ impl ClearOps {
|
||||||
self.color.is_some() || self.depth.is_some() || self.stencil.is_some()
|
self.color.is_some() || self.depth.is_some() || self.stencil.is_some()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> TextureDataRef<'a> {
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub fn check_and_extract_data_ptr(self, minimum_size: Vector2I, format: TextureFormat)
|
||||||
|
-> *const c_void {
|
||||||
|
let channels = match (format, self) {
|
||||||
|
(TextureFormat::R8, TextureDataRef::U8(_)) => 1,
|
||||||
|
(TextureFormat::RGBA8, TextureDataRef::U8(_)) => 4,
|
||||||
|
(TextureFormat::RGBA16F, TextureDataRef::F16(_)) => 4,
|
||||||
|
(TextureFormat::RGBA32F, TextureDataRef::F32(_)) => 4,
|
||||||
|
_ => panic!("Unimplemented texture format!"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let area = minimum_size.x() as usize * minimum_size.y() as usize;
|
||||||
|
|
||||||
|
match self {
|
||||||
|
TextureDataRef::U8(data) => {
|
||||||
|
assert!(data.len() >= area * channels);
|
||||||
|
data.as_ptr() as *const c_void
|
||||||
|
}
|
||||||
|
TextureDataRef::F16(data) => {
|
||||||
|
assert!(data.len() >= area * channels);
|
||||||
|
data.as_ptr() as *const c_void
|
||||||
|
}
|
||||||
|
TextureDataRef::F32(data) => {
|
||||||
|
assert!(data.len() >= area * channels);
|
||||||
|
data.as_ptr() as *const c_void
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ block = "0.1"
|
||||||
cocoa = "0.19"
|
cocoa = "0.19"
|
||||||
core-foundation = "0.6"
|
core-foundation = "0.6"
|
||||||
foreign-types = "0.3"
|
foreign-types = "0.3"
|
||||||
|
half = "1.4"
|
||||||
metal = "0.17"
|
metal = "0.17"
|
||||||
objc = "0.2"
|
objc = "0.2"
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ use cocoa::foundation::{NSRange, NSUInteger};
|
||||||
use core_foundation::base::TCFType;
|
use core_foundation::base::TCFType;
|
||||||
use core_foundation::string::{CFString, CFStringRef};
|
use core_foundation::string::{CFString, CFStringRef};
|
||||||
use foreign_types::{ForeignType, ForeignTypeRef};
|
use foreign_types::{ForeignType, ForeignTypeRef};
|
||||||
|
use half::f16;
|
||||||
use metal::{self, Argument, ArgumentEncoder, Buffer, CommandBuffer, CommandBufferRef};
|
use metal::{self, Argument, ArgumentEncoder, Buffer, CommandBuffer, CommandBufferRef};
|
||||||
use metal::{CommandQueue, CompileOptions, CoreAnimationDrawable, CoreAnimationDrawableRef};
|
use metal::{CommandQueue, CompileOptions, CoreAnimationDrawable, CoreAnimationDrawableRef};
|
||||||
use metal::{CoreAnimationLayer, CoreAnimationLayerRef, DepthStencilDescriptor, Function, Library};
|
use metal::{CoreAnimationLayer, CoreAnimationLayerRef, DepthStencilDescriptor, Function, Library};
|
||||||
|
@ -196,6 +197,7 @@ impl Device for MetalDevice {
|
||||||
TextureFormat::R8 => descriptor.set_pixel_format(MTLPixelFormat::R8Unorm),
|
TextureFormat::R8 => descriptor.set_pixel_format(MTLPixelFormat::R8Unorm),
|
||||||
TextureFormat::R16F => descriptor.set_pixel_format(MTLPixelFormat::R16Float),
|
TextureFormat::R16F => descriptor.set_pixel_format(MTLPixelFormat::R16Float),
|
||||||
TextureFormat::RGBA8 => descriptor.set_pixel_format(MTLPixelFormat::RGBA8Unorm),
|
TextureFormat::RGBA8 => descriptor.set_pixel_format(MTLPixelFormat::RGBA8Unorm),
|
||||||
|
TextureFormat::RGBA16F => descriptor.set_pixel_format(MTLPixelFormat::RGBA16Float),
|
||||||
TextureFormat::RGBA32F => descriptor.set_pixel_format(MTLPixelFormat::RGBA32Float),
|
TextureFormat::RGBA32F => descriptor.set_pixel_format(MTLPixelFormat::RGBA32Float),
|
||||||
}
|
}
|
||||||
descriptor.set_width(size.x() as u64);
|
descriptor.set_width(size.x() as u64);
|
||||||
|
@ -207,17 +209,10 @@ impl Device for MetalDevice {
|
||||||
|
|
||||||
fn create_texture_from_data(&self, format: TextureFormat, size: Vector2I, data: TextureDataRef)
|
fn create_texture_from_data(&self, format: TextureFormat, size: Vector2I, data: TextureDataRef)
|
||||||
-> MetalTexture {
|
-> MetalTexture {
|
||||||
match (format, data) {
|
let texture = self.create_texture(format, size);
|
||||||
(TextureFormat::R8, TextureDataRef::U8(data)) => {
|
self.upload_to_texture(&texture, RectI::new(Vector2I::default(), size), data);
|
||||||
assert!(data.len() >= size.x() as usize * size.y() as usize);
|
|
||||||
let texture = self.create_texture(TextureFormat::R8, size);
|
|
||||||
self.upload_to_texture(&texture, size, data);
|
|
||||||
texture
|
texture
|
||||||
}
|
}
|
||||||
_ => panic!("Unimplemented texture format in `create_texture_from_data`!"),
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_shader_from_source(&self, _: &str, source: &[u8], _: ShaderKind) -> MetalShader {
|
fn create_shader_from_source(&self, _: &str, source: &[u8], _: ShaderKind) -> MetalShader {
|
||||||
let source = String::from_utf8(source.to_vec()).expect("Source wasn't valid UTF-8!");
|
let source = String::from_utf8(source.to_vec()).expect("Source wasn't valid UTF-8!");
|
||||||
|
@ -421,16 +416,25 @@ impl Device for MetalDevice {
|
||||||
Vector2I::new(texture.texture.width() as i32, texture.texture.height() as i32)
|
Vector2I::new(texture.texture.width() as i32, texture.texture.height() as i32)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn upload_to_texture(&self, texture: &MetalTexture, size: Vector2I, data: &[u8]) {
|
fn upload_to_texture(&self, texture: &MetalTexture, rect: RectI, data: TextureDataRef) {
|
||||||
assert!(data.len() >= size.x() as usize * size.y() as usize);
|
let texture_size = self.texture_size(texture);
|
||||||
let format = self.texture_format(&texture.texture).expect("Unexpected texture format!");
|
assert!(rect.size().x() >= 0);
|
||||||
assert!(format == TextureFormat::R8 || format == TextureFormat::RGBA8);
|
assert!(rect.size().y() >= 0);
|
||||||
|
assert!(rect.max_x() <= texture_size.x());
|
||||||
|
assert!(rect.max_y() <= texture_size.y());
|
||||||
|
|
||||||
let origin = MTLOrigin { x: 0, y: 0, z: 0 };
|
let format = self.texture_format(&texture.texture).expect("Unexpected texture format!");
|
||||||
let size = MTLSize { width: size.x() as u64, height: size.y() as u64, depth: 1 };
|
let data_ptr = data.check_and_extract_data_ptr(rect.size(), format);
|
||||||
|
|
||||||
|
let origin = MTLOrigin { x: rect.origin().x() as u64, y: rect.origin().y() as u64, z: 0 };
|
||||||
|
let size = MTLSize {
|
||||||
|
width: rect.size().x() as u64,
|
||||||
|
height: rect.size().y() as u64,
|
||||||
|
depth: 1,
|
||||||
|
};
|
||||||
let region = MTLRegion { origin, size };
|
let region = MTLRegion { origin, size };
|
||||||
let stride = size.width * format.channels() as u64;
|
let stride = format.bytes_per_pixel() as u64 * size.width;
|
||||||
texture.texture.replace_region(region, 0, stride, data.as_ptr() as *const _);
|
texture.texture.replace_region(region, 0, stride, data_ptr);
|
||||||
|
|
||||||
texture.dirty.set(true);
|
texture.dirty.set(true);
|
||||||
}
|
}
|
||||||
|
@ -454,14 +458,15 @@ impl Device for MetalDevice {
|
||||||
texture.get_bytes(pixels.as_mut_ptr() as *mut _, metal_region, 0, stride as u64);
|
texture.get_bytes(pixels.as_mut_ptr() as *mut _, metal_region, 0, stride as u64);
|
||||||
TextureData::U8(pixels)
|
TextureData::U8(pixels)
|
||||||
}
|
}
|
||||||
TextureFormat::R16F => {
|
TextureFormat::R16F | TextureFormat::RGBA16F => {
|
||||||
let stride = size.x() as usize;
|
let channels = format.channels();
|
||||||
let mut pixels = vec![0; stride * size.y() as usize];
|
let stride = size.x() as usize * channels;
|
||||||
|
let mut pixels = vec![f16::default(); stride * size.y() as usize];
|
||||||
texture.get_bytes(pixels.as_mut_ptr() as *mut _,
|
texture.get_bytes(pixels.as_mut_ptr() as *mut _,
|
||||||
metal_region,
|
metal_region,
|
||||||
0,
|
0,
|
||||||
stride as u64 * 2);
|
stride as u64 * 2);
|
||||||
TextureData::U16(pixels)
|
TextureData::F16(pixels)
|
||||||
}
|
}
|
||||||
TextureFormat::RGBA32F => {
|
TextureFormat::RGBA32F => {
|
||||||
let channels = format.channels();
|
let channels = format.channels();
|
||||||
|
|
|
@ -21,8 +21,8 @@ use pathfinder_content::color::ColorF;
|
||||||
use pathfinder_gpu::resources::ResourceLoader;
|
use pathfinder_gpu::resources::ResourceLoader;
|
||||||
use pathfinder_gpu::{BlendFunc, BlendState, BufferData, BufferTarget, BufferUploadMode, ClearOps};
|
use pathfinder_gpu::{BlendFunc, BlendState, BufferData, BufferTarget, BufferUploadMode, ClearOps};
|
||||||
use pathfinder_gpu::{DepthFunc, DepthState, Device, Primitive, RenderOptions, RenderState};
|
use pathfinder_gpu::{DepthFunc, DepthState, Device, Primitive, RenderOptions, RenderState};
|
||||||
use pathfinder_gpu::{RenderTarget, StencilFunc, StencilState, TextureFormat, UniformData};
|
use pathfinder_gpu::{RenderTarget, StencilFunc, StencilState, TextureDataRef, TextureFormat};
|
||||||
use pathfinder_gpu::{VertexAttrClass, VertexAttrDescriptor, VertexAttrType};
|
use pathfinder_gpu::{UniformData, VertexAttrClass, VertexAttrDescriptor, VertexAttrType};
|
||||||
use pathfinder_simd::default::{F32x2, F32x4};
|
use pathfinder_simd::default::{F32x2, F32x4};
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
@ -378,8 +378,8 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
self.device.upload_to_texture(self.paint_texture.as_ref().unwrap(),
|
self.device.upload_to_texture(self.paint_texture.as_ref().unwrap(),
|
||||||
paint_data.size,
|
RectI::new(Vector2I::default(), paint_data.size),
|
||||||
&paint_data.texels);
|
TextureDataRef::U8(&paint_data.texels));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn upload_solid_tiles(&mut self, solid_tiles: &[SolidTileBatchPrimitive]) {
|
fn upload_solid_tiles(&mut self, solid_tiles: &[SolidTileBatchPrimitive]) {
|
||||||
|
|
Loading…
Reference in New Issue