amethyst / rendy Goto Github PK
View Code? Open in Web Editor NEWState of the art "build your own engine" kit powered by gfx-hal
License: Other
State of the art "build your own engine" kit powered by gfx-hal
License: Other
What is the relationship between the queues of the passes?
I'm trying to create a mesh that is used in multiple passes, but mesh build requires a QueueId.
In the example node_queue is used to get this id.
As I understand each node has it's own queue, so how can I share the resources between the passes ?
Or is it enough to create my own "queue" for the same QueueFamily, but how, I couldn't find the function for this. An in this case how can I handle the synchronization between uploads and uses ?
A Layout
takes a vec of push constant descriptions, which include the size of the push constant. However, it appears that no check is done to make sure the size of the data given to encoder.push_constants()
is actually this size, and the validation layer didn't catch it for me either. (It also didn't catch that the size of the data I was trying to give it was several times larger than maxPushConstantsSize
.) Do we want to add a debug-mode-only bounds check for this?
I believe this would only require configuration of the rasterizer field in the GraphicsPipelineDesc
passed to create_graphics_pipelines
.
Edit: Also note that front-face culling is a good technique for avoiding shadow-acne while rendering shadow maps.
Screen clears red.
Screen clears blue.
let color = graph_builder.create_image(
surface.kind(),
1,
gfx_hal::format::Format::Rgba8Srgb,
MemoryUsageValue::Data,
Some(gfx_hal::command::ClearValue::Color(gfx_hal::command::ClearColor::Float([1.0, 0.0, 0.0, 1.0]))),
);
You also need a device that would choose Bgra8Srgb as the swapchain format or I guess anything other than what is set in create_image.
DX11 and OpenGL backends are not supported even though they are supported by gfx_hal
. I had a quick try implementing them today, but ran into issues with how OpenGL initialises surfaces (you have to create a surface before you ask for the adapters, which is the opposite of what rendy_factory
does). I also had an issue with DX11 at runtime but I suspect that can be fixed with some further investigation.
Is there any interest in implementing them in the future?
I'm trying out the examples for rendy and I've come across an interesting issue that seems to happen for all examples. The application itself seems to run at 60 fps as expected, however when I try to move the window it moves in a very laggy way. Perhaps at 5 fps.
I also tried to move other windows and they move smoothly as long as they are not overlapping the rendy window. If the windows overlap (even just their shadows) then the movement starts to lag.
This seems to indicate that there's some synchronization with the window manager that is causing this. My first thought was that window events were not polled often enough, but since they seem to be polled at 60 fps I don't think it is that.
I'm running this on Ubuntu 18.04.2 using an i7-4790K CPU and a GTX 970 graphics card.
Does anyone else see this?
Creating a new lib via cargo, adding rendy as dependency and building(with the nightly version) it gives me the following error while compiling rendy-resource: E0308
expected type &<B as gfx_hal::Backend>::Device
found type &impl gfx_hal::Device<B>
I am pretty new to rust and rendy, so it may just be a stupid mistake on my side.
In wgpu, we want to test out some of the features that landed after gfx-0.3. Namely, the new swapchain model. Would it be possible to get Rendy master
to depend on gfx-rs from a recent git revision (instead of crates.io)?
To reproduce, edit the triangle example and remove the implementation of TriangleRenderPipelineDesc::vertices
(so that the default implementation is used).
The example still compiles, runs and issues no warnings, but does not render the triangle. Because no vertex format has been specified, the shader fails to pull any data from the vertex buffer.
This should probably at least be checked in debug builds, and documented for this and any other descriptor method(s) that might be susceptible to the same problem.
In particular, the meshes
and source_shader
examples do this.
Windows 10 build 1809 (64-bit)
Intel Iris Plus Graphics 640
cargo run --example triangle --features dx12
fails with the following stacktrace:
WARN 2019-04-05T01:35:04Z: rendy_factory::factory: Slow safety checks are enabled! Disable them in production by enabling the 'no-slow-safety-checks' feature!
thread 'main' panicked at 'assertion failed: `(left == right)`
left: `Secondary`,
right: `Primary`', C:\Users\bgour\.cargo\registry\src\github.com-1ecc6299db9ec823\gfx-backend-dx12-0.1.1\src\pool.rs:91:9
stack backtrace:
0: std::sys::windows::backtrace::set_frames
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\sys\windows\backtrace\mod.rs:94
1: std::sys::windows::backtrace::unwind_backtrace
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\sys\windows\backtrace\mod.rs:81
2: std::sys_common::backtrace::_print
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\sys_common\backtrace.rs:70
3: std::sys_common::backtrace::print
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\sys_common\backtrace.rs:58
4: std::panicking::default_hook::{{closure}}
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\panicking.rs:200
5: std::panicking::default_hook
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\panicking.rs:215
6: std::panicking::rust_panic_with_hook
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\panicking.rs:478
7: std::panicking::continue_panic_fmt
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\panicking.rs:385
8: std::panicking::begin_panic_fmt
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\panicking.rs:340
9: gfx_backend_dx12::pool::{{impl}}::allocate_one
at C:\Users\bgour\.cargo\registry\src\github.com-1ecc6299db9ec823\gfx-backend-dx12-0.1.1\src\pool.rs:91
10: gfx_hal::pool::RawCommandPool::allocate_vec::{{closure}}<gfx_backend_dx12::pool::RawCommandPool,gfx_backend_dx12::Backend>
at C:\Users\bgour\.cargo\registry\src\github.com-1ecc6299db9ec823\gfx-hal-0.1.0\src\pool.rs:38
11: core::iter::{{impl}}::fold::{{closure}}<gfx_backend_dx12::command::CommandBuffer,core::ops::range::Range<usize>,closure,(),closure>
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\libcore\iter\mod.rs:1447
12: core::iter::iterator::Iterator::fold::{{closure}}<core::ops::range::Range<usize>,(),closure>
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\libcore\iter\iterator.rs:1687
13: core::iter::iterator::Iterator::try_fold<core::ops::range::Range<usize>,(),closure,core::result::Result<(), !>>
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\libcore\iter\iterator.rs:1575
14: core::iter::iterator::Iterator::fold<core::ops::range::Range<usize>,(),closure>
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\libcore\iter\iterator.rs:1687
15: core::iter::{{impl}}::fold<gfx_backend_dx12::command::CommandBuffer,core::ops::range::Range<usize>,closure,(),closure>
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\libcore\iter\mod.rs:1447
16: core::iter::iterator::Iterator::for_each<core::iter::Map<core::ops::range::Range<usize>, closure>,closure>
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\libcore\iter\iterator.rs:606
17: alloc::vec::{{impl}}::spec_extend<gfx_backend_dx12::command::CommandBuffer,core::iter::Map<core::ops::range::Range<usize>, closure>>
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\liballoc\vec.rs:1856
18: alloc::vec::{{impl}}::from_iter<gfx_backend_dx12::command::CommandBuffer,core::iter::Map<core::ops::range::Range<usize>, closure>>
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\liballoc\vec.rs:1839
19: alloc::vec::{{impl}}::from_iter<gfx_backend_dx12::command::CommandBuffer,core::iter::Map<core::ops::range::Range<usize>, closure>>
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\liballoc\vec.rs:1725
20: core::iter::iterator::Iterator::collect<core::iter::Map<core::ops::range::Range<usize>, closure>,alloc::vec::Vec<gfx_backend_dx12::command::CommandBuffer>>
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\libcore\iter\iterator.rs:1468
21: gfx_hal::pool::RawCommandPool::allocate_vec<gfx_backend_dx12::pool::RawCommandPool,gfx_backend_dx12::Backend>
at C:\Users\bgour\.cargo\registry\src\github.com-1ecc6299db9ec823\gfx-hal-0.1.0\src\pool.rs:38
22: rendy_command::pool::CommandPool<gfx_backend_dx12::Backend, rendy_command::capability::Graphics, rendy_command::buffer::reset::IndividualReset>::allocate_buffers<gfx_backend_dx12::Backend,rendy_command::capability::Graphics,rendy_command::buffer::reset::IndividualReset,rendy_command::buffer::level::SecondaryLevel>
at C:\Users\bgour\Repos\rendy\command\src\pool.rs:54
23: rendy_graph::node::render::pass::{{impl}}::build<gfx_backend_dx12::Backend,()>
at C:\Users\bgour\Repos\rendy\graph\src\node\render\pass.rs:460
24: rendy_graph::graph::build_node<gfx_backend_dx12::Backend,()>
at C:\Users\bgour\Repos\rendy\graph\src\graph\mod.rs:507
25: rendy_graph::graph::GraphBuilder<gfx_backend_dx12::Backend, ()>::build<gfx_backend_dx12::Backend,()>
at C:\Users\bgour\Repos\rendy\graph\src\graph\mod.rs:383
26: triangle::main
at .\examples\triangle\main.rs:278
27: std::rt::lang_start::{{closure}}<()>
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\libstd\rt.rs:64
28: std::rt::lang_start_internal::{{closure}}
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\rt.rs:49
29: std::panicking::try::do_call<closure,i32>
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\panicking.rs:297
30: panic_unwind::__rust_maybe_catch_panic
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libpanic_unwind\lib.rs:92
31: std::panicking::try
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\panicking.rs:276
32: std::panic::catch_unwind
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\panic.rs:388
33: std::rt::lang_start_internal
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\rt.rs:48
34: std::rt::lang_start<()>
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\libstd\rt.rs:64
35: main
36: invoke_main
at d:\agent\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:78
37: __scrt_common_main_seh
at d:\agent\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288
38: BaseThreadInitThunk
39: RtlUserThreadStart
ERROR 2019-04-05T01:35:05Z: relevant: Values of this type can't be dropped!. Trace: stack backtrace:
0: backtrace::backtrace::trace_unsynchronized<closure> (0x7ff79af9ce42)
at C:\Users\bgour\.cargo\registry\src\github.com-1ecc6299db9ec823\backtrace-0.3.14\src\backtrace\mod.rs:57
1: backtrace::capture::Backtrace::create (0x7ff79af8d4a3)
at C:\Users\bgour\.cargo\registry\src\github.com-1ecc6299db9ec823\backtrace-0.3.14\src\capture.rs:105
2: backtrace::capture::Backtrace::new (0x7ff79af8d334)
at C:\Users\bgour\.cargo\registry\src\github.com-1ecc6299db9ec823\backtrace-0.3.14\src\capture.rs:72
3: relevant::whine (0x7ff79af5be41)
at C:\Users\bgour\.cargo\registry\src\github.com-1ecc6299db9ec823\relevant-0.4.0\src\lib.rs:72
4: relevant::{{impl}}::drop (0x7ff79af5bdbe)
at C:\Users\bgour\.cargo\registry\src\github.com-1ecc6299db9ec823\relevant-0.4.0\src\lib.rs:41
5: core::ptr::real_drop_in_place<relevant::Relevant> (0x7ff79aa7c4a3)
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\libcore\ptr.rs:193
6: core::ptr::real_drop_in_place<rendy_command::pool::CommandPool<gfx_backend_dx12::Backend, rendy_command::capability::Graphics, rendy_command::buffer::reset::IndividualReset>> (0x7ff79aa79cad)
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\libcore\ptr.rs:193
7: rendy_graph::node::render::pass::{{impl}}::build<gfx_backend_dx12::Backend,()> (0x7ff79ab8f1d5)
at C:\Users\bgour\Repos\rendy\graph\src\node\render\pass.rs:586
8: _C_specific_handler (0x7ffef376c0b0)
9: _TypeMatch (0x7ffef3761d6e)
10: _unDNameEx (0x7ffef376b7fb)
11: _BuildCatchObject (0x7ffef37623e3)
12: _CxxFrameHandler3 (0x7ffef376b882)
13: _chkstk (0x7fff0bf2470f)
14: RtlUnwindEx (0x7fff0be8600c)
15: FindAndUnlinkFrame (0x7ffef376bbd1)
16: _BuildCatchObject (0x7ffef3762f61)
17: _BuildCatchObject (0x7ffef3762ce9)
18: _BuildCatchObject (0x7ffef37624de)
19: _CxxFrameHandler3 (0x7ffef376b882)
20: _chkstk (0x7fff0bf2468f)
21: RtlWalkFrameChain (0x7fff0be84bef)
22: RtlRaiseException (0x7fff0be889e6)
23: RaiseException (0x7fff08c19149)
24: CxxThrowException (0x7ffef37642cd)
25: panic_unwind::__rust_start_panic (0x7ff79afc04d8)
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libpanic_unwind\lib.rs:109
26: std::panicking::rust_panic (0x7ff79afbd128)
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\panicking.rs:527
27: std::panicking::rust_panic_with_hook (0x7ff79afbcffe)
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\panicking.rs:498
28: std::panicking::continue_panic_fmt (0x7ff79afbca84)
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\panicking.rs:385
29: std::panicking::begin_panic_fmt (0x7ff79afbc9d2)
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\panicking.rs:340
30: gfx_backend_dx12::pool::{{impl}}::allocate_one (0x7ff79ae263aa)
at C:\Users\bgour\.cargo\registry\src\github.com-1ecc6299db9ec823\gfx-backend-dx12-0.1.1\src\pool.rs:91
31: gfx_hal::pool::RawCommandPool::allocate_vec::{{closure}}<gfx_backend_dx12::pool::RawCommandPool,gfx_backend_dx12::Backend> (0x7ff79aadb0d9)
at C:\Users\bgour\.cargo\registry\src\github.com-1ecc6299db9ec823\gfx-hal-0.1.0\src\pool.rs:38
32: core::iter::{{impl}}::fold::{{closure}}<gfx_backend_dx12::command::CommandBuffer,core::ops::range::Range<usize>,closure,(),closure> (0x7ff79a9fc1a8)
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\libcore\iter\mod.rs:1447
33: core::iter::iterator::Iterator::fold::{{closure}}<core::ops::range::Range<usize>,(),closure> (0x7ff79aa17c57)
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\libcore\iter\iterator.rs:1687
34: core::iter::iterator::Iterator::try_fold<core::ops::range::Range<usize>,(),closure,core::result::Result<(), !>> (0x7ff79ab85568)
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\libcore\iter\iterator.rs:1575
35: core::iter::iterator::Iterator::fold<core::ops::range::Range<usize>,(),closure> (0x7ff79ab85150)
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\libcore\iter\iterator.rs:1687
36: core::iter::{{impl}}::fold<gfx_backend_dx12::command::CommandBuffer,core::ops::range::Range<usize>,closure,(),closure> (0x7ff79a9fb502)
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\libcore\iter\mod.rs:1448
37: core::iter::iterator::Iterator::for_each<core::iter::Map<core::ops::range::Range<usize>, closure>,closure> (0x7ff79a9f41b0)
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\libcore\iter\iterator.rs:607
38: alloc::vec::{{impl}}::spec_extend<gfx_backend_dx12::command::CommandBuffer,core::iter::Map<core::ops::range::Range<usize>, closure>> (0x7ff79a9b0224)
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\liballoc\vec.rs:1856
39: alloc::vec::{{impl}}::from_iter<gfx_backend_dx12::command::CommandBuffer,core::iter::Map<core::ops::range::Range<usize>, closure>> (0x7ff79a9b9231)
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\liballoc\vec.rs:1839
40: alloc::vec::{{impl}}::from_iter<gfx_backend_dx12::command::CommandBuffer,core::iter::Map<core::ops::range::Range<usize>, closure>> (0x7ff79a9c0055)
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\liballoc\vec.rs:1726
41: core::iter::iterator::Iterator::collect<core::iter::Map<core::ops::range::Range<usize>, closure>,alloc::vec::Vec<gfx_backend_dx12::command::CommandBuffer>> (0x7ff79a9f3029)
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\libcore\iter\iterator.rs:1469
42: gfx_hal::pool::RawCommandPool::allocate_vec<gfx_backend_dx12::pool::RawCommandPool,gfx_backend_dx12::Backend> (0x7ff79a9ea035)
at C:\Users\bgour\.cargo\registry\src\github.com-1ecc6299db9ec823\gfx-hal-0.1.0\src\pool.rs:39
43: rendy_command::pool::CommandPool<gfx_backend_dx12::Backend, rendy_command::capability::Graphics, rendy_command::buffer::reset::IndividualReset>::allocate_buffers<gfx_backend_dx12::Backend,rendy_command::capability::Graphics,rendy_command::buffer::reset::I (0x7ff79ab0ffd2)
at C:\Users\bgour\Repos\rendy\command\src\pool.rs:56
44: rendy_graph::node::render::pass::{{impl}}::build<gfx_backend_dx12::Backend,()> (0x7ff79ab8dc1d)
at C:\Users\bgour\Repos\rendy\graph\src\node\render\pass.rs:460
45: rendy_graph::graph::build_node<gfx_backend_dx12::Backend,()> (0x7ff79aa22118)
at C:\Users\bgour\Repos\rendy\graph\src\graph\mod.rs:507
46: rendy_graph::graph::GraphBuilder<gfx_backend_dx12::Backend, ()>::build<gfx_backend_dx12::Backend,()> (0x7ff79aa27835)
at C:\Users\bgour\Repos\rendy\graph\src\graph\mod.rs:383
47: triangle::main (0x7ff79aa1b3f4)
at C:\Users\bgour\Repos\rendy\rendy\examples\triangle\main.rs:278
48: std::rt::lang_start::{{closure}}<()> (0x7ff79aa0dbe0)
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\libstd\rt.rs:64
49: std::panicking::try::do_call<closure,i32> (0x7ff79afbc8c7)
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\panicking.rs:297
50: panic_unwind::__rust_maybe_catch_panic (0x7ff79afc03f2)
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libpanic_unwind\lib.rs:92
51: std::rt::lang_start_internal (0x7ff79afbd292)
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\rt.rs:48
52: std::rt::lang_start<()> (0x7ff79aa0dbbb)
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\libstd\rt.rs:64
53: main (0x7ff79aa1b820)
54: __scrt_common_main_seh (0x7ff79b3d6964)
at d:\agent\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288
55: BaseThreadInitThunk (0x7fff097b81f4)
error: process didn't exit successfully: `C:\Users\bgour\Repos\rendy\target\debug\examples\triangle.exe` (exit code: 101)
Process finished with exit code 101
This issue shall discuss which backend(s) rendy is going to use.
Discussion so far:
What's the reasoning behind "Abandon hal for now."?
@omni-viral
@kvark without reinventing the wheel (abstraction layer over ash and hal) I'm way more productive.
Instead of providing own abstractions I believe it is better to implement ash::DeviceV* etc traits for hal. I heard that someone already suggesting to do so (or even started).
Then to work over hal rendy would only need to parametrize Factory type.
To the reader: please note that "dropping hal" does not mean that hal will not have anything to do with rendy. Viral is focusing on ash right now as it is closer to Vulkan so easier to use for him, but when all of this is done rendy is made in such a way that it will be "easy" to implement the hal backend. It's just to not have to implement two backends at once.
@Moxinilian thank you for clarification. I don't see the story the same way. gfx-hal is already pretty much Vulkan, just a bit rustier (borrowing, move semantics, and references instead of pointers and opaque handles). You could just have used gfx-hal and have access to all platforms, while benefiting gfx-rs community with your feedback.
Truth is that @omni-viral found gfx-hal inconvenient for their needs, hence the departure. I don't see it temporary. The expressed solution (in #12 (comment)) is basically - solve it on the Ash level, so that Amethyst wouldn't care about gfx-rs APIs.
Tight Ash (and Vulkano) integration is certainly one of our goals, but it's not going to be the most performant path at the end of the day, so we'd like Rust projects which really need performance (like Amethyst and WebRender) to work with gfx-hal directly.
There is enough motivation within the Amethyst team to make sure hal will be supported by rendy, most notably in the perspective of WebGL (and eventually WebGPU). From what has been discussed on Discord, it seems like first class hal is planned in the future.
If I misunderstood, then this is going to be a much larger issue considering Amethyst's next step after mobile support will be web technologies, in which gfx-hal would help in a significant way.
@Moxinilian FYI, this is a very poor communication on the Amethyst side. Your team discussed something on discord (which we don't even have any visibility into, since we use Gitter) and decided to drop gfx-hal without any heads up to our team, without even bothering to explain this in PR description... We hope that in the future, if there is any news of that scale, we'd know about it from you.
Yes, I agree. If I recall correctly, an issue is being written to be posted on the gfx issue tracker regarding the reasons for such a decision. I still believe that supporting hal from the ground up would have been better, but I am not involved enough in rendering to have a meaningful opinion.
We handled this very poorly, and apologize to the entire gfx-hal team. It was inexcusable, and we will take steps internally to ensure it doesn't happen again. We would like to re-open a dialog on this with the gfx-hal team, if they are ok with it.
@omni-viral
@kvark Sorry I didn't explained in detail why I abandoned hal in this PR. I also sad for that I didn't state my opinion clearly in gfx-rs/gfx#2206 ๐ญ
Correct me if I'm wrong.
As I understand it the main idea of hal API to stay is that it is rustier and reduces boxing overhead over non-Vulkan backends. But I also see calling overhead in hal's API for Vulkan backend which you underestimate (I think). Hence I'd really like to see ash's API implemented for hal's backends (notably metal backend which is awesome ๐).Sorry. It's hard for me to express sophisticated stuff in language I barely know. It took me 15 minutes to write this comment ๐
Also pinging:
(please ignore if you're not interested)
Coming in cold to graphics programming and looking into rendy I was curious to what exactly VMA is as opposed to the Heaps
that it implements.
The name is a bit hard to google, it'd be nice for there to be some hyperlinks or a short explanation.
I am attempting to run the pong tutorial in the amethyst book and get the following error. I am using the vulkan backend in a wayland session in linux.
[WARN][rendy_wsi] Image count not supported. Supported: 4..4294967295, requested: 3
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: ErrorMessage { msg: "Image count not supported." }
I believe I have tracked the source of the issue to line 443 in graph/src/node/render/pass.rs where a hardcoded 3 is passed as the image_count parameter to rendy_factory::factory::Factory::create_target
. This should be changed to use the smaller of 3 and the minimum image count in the surface capabilities (which on my system is 4).
Not sure if this is intentional or not, but rendy::graph::DescBuilder
has no public fields and no methods that can construct it. It's exposed as the return type of RenderGroupDesc::builder()
which has a default impl, I'm just not (yet) sure whether I'm supposed to be able to override that method in my own implementation of RenderGroupDesc
or whether the default impl always does the right thing.
I'll open this issue to be aware when you have time to add an example of mesh usage, I'm looking forward on using it.
You can check my early attempt to use it :)
Regards
Line 153 in c384196
This happens on the first attempt at drawing a frame in my application that runs perfectly on Mac/Metal.
Hi all!
Recently I've been trying to use Rendy in my little project (master thesis) and got some problems.
Once I try to use two images in my SimpleGraphicsPipeline implementation I've got panic during graph building in:
if !link.access().exclusive() {
unimplemented!("This case is unimplemented");
}
in chain/src/sync.rs: line 421
What I'm trying to achieve: render two images and then combine them in third pass.
let pass3 = graph_builder.add_node(
desc3.builder()
.with_image(image1)
.with_image(image2) // Once I add second image unimplemeted! is triggered
.into_subpass()
.with_dependency(pass1)
.with_dependency(pass2)
.with_color(final_output)
.into_pass()
);
Is there a way to work around this?
If anyone is willing to explain what the problem seems to be I can dig into Rendy and help implement missing functionality.
I couldn't find any example using more than one image used; if there is one I would love to see it.
Edit:
Actually this error was rather due to the fact that I wanted to use not written to image as an input image.
When actually using code I presented above I get different panic:
thread 'main' panicked at 'Transient image wasn't provided
in
node/render/pass.rs: 730.
let images: Vec<_> = group
.images()
.into_iter()
.map(|(id, _)| {
images
.find(|i| i.id == id)
.expect(format!("Transient image wasn't provided for {}", id))
.clone()
})
.collect();
It looks like it can't find input image in map of all images. I'm investigating further.
if the size is 0, this will abort on a sub overflow in debug mode.
fn alloc(
&mut self,
device: &B::Device,
size: u64,
align: u64,
) -> Result<(DynamicBlock<B>, u64), gfx_hal::device::AllocationError> {
debug_assert!(size <= self.max_allocation());
debug_assert!(align.is_power_of_two());
let aligned_size = ((size - 1) | (align - 1) | (self.block_size_granularity - 1)) + 1;
Hello there!
It seems that there is a problem compiling the project on Windows. It looks like Shaderc doesn't have a cmake configuration for windows, even though shaderc crate mentions Windows support.
It appears to be the number of vertices that will be drawn in a mesh. So for a mesh with indices, this is the number of indices, and in a mesh without indices, this is the number of vertices. I think.
For drawing this is generally the value we want, but it's kinda weird that it measure the length of two different things depending on context. Does anyone think it might be nicer to have verts_len()
and indices_len()
be separate things or such? Or should we just update the docs to make it more clear what it's actually measuring?
All of the examples excluding triangle
and init
segfault while trying to run the framegraph. I want to say this is caused by PresentNode
given that the triangle example doesn't use it and is also the only substantial example that works, but I haven't actually tested to see if that's the case.
Tested with:
Linux 5.1.5
NVIDIA driver 430.26
rustc 1.35.0
It's two extra letters to type, but it makes it more obvious that this is a noun and not a verb. "Render" in english can't really become an object on its own, it is always an action. A Renderer would be a thing that performs rendering, which is more precisely what the type is. This would also affect RenderBuilder which would become RendererBuilder.
Hi, this is not so much of an issue as it is a question.
In the mesh example here you use nalgebra
to create a perspective projection matrix. Looking at the nalgebra code here though, it seems like this is creating a matrix for OpenGL NDC (depth -1 to 1), not Vulkan NDC (depth 0 to 1) and I thought gfx-hal
was based on Vulkan conventions. Am I missing something here or how does this work? It seems like it would map objects on the near plane to -1 in clip space?
I have noticed that here is no dynamic allocation, because the max_block_size function of DynamicAllocator
always returns zero, since self.sizes
is created as an empty HashMap
. This max_block_size
is used to decide if we want allocate using a DynamicAllocator
here, but this will be always false due to the returning zero value.
I tought adding the max_block_size
limit from DynamicConfig
as a field to the DynamicAllocator
and using it in the above mentioned function would fix this, but now when I run the quads
example there is a panic:
TRACE 2019-03-28T08:03:55Z: rendy_memory::allocator::dynamic: Allocate block. type: 1, size: 32000000
TRACE 2019-03-28T08:03:55Z: rendy_memory::allocator::dynamic: Allocate new chunk: size: 2048000000
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: AllocationError(OutOfMemory(OutOfDeviceMemory))', src/libcore/result.rs:997:5
As I can see the following happens: We try to allocate with DynamicAllocator
and creating a new chunk, but the size exceeds the max_block_size
limit and we fallback to dedicated allocation. This allocation fails because we run out of memory.
I have lowered the max_block_size
limit in BasicHeapsConfigure to 8 MB to see if we don't run out of memory. Now the quad example runs, and it tries to allocate with DynamicAllocator, but what really happens is alloc_from_chunk and alloc_chunk calls each other recursively until we reach the max_block_size limit and we fallback to the dedicated memory allocation again. Here is a part of my trace log which demonstrates well the recursive calls, and the dedicated allocation in the end (Map new memory object
).
TRACE 2019-03-28T08:27:58Z: rendy_memory::allocator::dynamic: Allocate block. type: 1, size: 512
TRACE 2019-03-28T08:27:58Z: rendy_memory::allocator::dynamic: Allocate new chunk: size: 32768
TRACE 2019-03-28T08:27:58Z: rendy_memory::allocator::dynamic: Allocate block. type: 1, size: 32768
TRACE 2019-03-28T08:27:58Z: rendy_memory::allocator::dynamic: Allocate new chunk: size: 2097152
TRACE 2019-03-28T08:27:58Z: rendy_memory::allocator::dynamic: Allocate block. type: 1, size: 2097152
TRACE 2019-03-28T08:27:58Z: rendy_memory::allocator::dynamic: Allocate new chunk: size: 134217728
TRACE 2019-03-28T08:27:58Z: rendy_memory::allocator::dynamic: Map new memory object
The full log is here : https://gist.github.com/zakorgy/fffa38cac7c9805484dd9d9a059c9646
I have two mapped buffer memory ranges, both have CPU_CACHED memory. I use the read and write functions of MappedRange
to read the content of the first buffer and write it to the second on the CPU side in this function: https://github.com/szeged/webrender/blob/rendy-memory-segf/webrender/src/device/gfx/device.rs#L2293
When running tests this causes a segfault after a certain time.
However if I use the raw pointer from the mapped range and the size to create slices without the read/write functions the issue is absent: https://github.com/szeged/webrender/blob/rendy-memory-segf/webrender/src/device/gfx/device.rs#L2274
The code: https://github.com/szeged/webrender/tree/rendy-memory-segf
platform: Ubuntu 18.04.2 LTS
rust version: rustc 1.35.0 (3c235d560 2019-05-20)
Steps to reproduce:
cd wrench
cargo run --features=vulkan reftest
It will take a time until the segfault happens
The backtrace with gdb --args ../target/debug/wrench reftest
running from the wrench
directory:
Thread 1 "wrench" received signal SIGSEGV, Segmentation fault.
__memmove_avx_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:249
249 ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S: No such file or directory.
(gdb) bt
#0 __memmove_avx_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:249
#1 0x0000555556fa4bfb in core::intrinsics::copy_nonoverlapping (src=0x7fffe8722000, dst=0x7fffea3c0000, count=327680)
at /rustc/3c235d5600393dfe6c36eeed34042efad8d4f26e/src/libcore/intrinsics.rs:1422
#2 0x000055555681587f in core::slice::<impl [T]>::copy_from_slice (self=..., src=...)
at /rustc/3c235d5600393dfe6c36eeed34042efad8d4f26e/src/libcore/slice/mod.rs:2118
#3 0x0000555555acac70 in webrender::device::gfx::device::Device<B>::copy_cache_buffer (self=0x7fffffff6e00,
dst=0x7ffffffed638, src=0x7ffffffed6a0) at /home/zakorgy/Work/webrender_szeged/webrender/src/device/gfx/device.rs:2304
#4 0x0000555555826086 in webrender::renderer::GpuCacheTexture<B>::ensure_texture (self=0x7fffffff8ca0,
device=0x7fffffff6e00, height=40) at /home/zakorgy/Work/webrender_szeged/webrender/src/renderer.rs:769
#5 0x000055555582642a in webrender::renderer::GpuCacheTexture<B>::prepare_for_updates (self=0x7fffffff8ca0,
device=0x7fffffff6e00, _total_block_count=15406, max_height=40)
at /home/zakorgy/Work/webrender_szeged/webrender/src/renderer.rs:893
#6 0x000055555580b1ac in webrender::renderer::Renderer<B>::update_gpu_cache (self=0x7fffffff6d88)
at /home/zakorgy/Work/webrender_szeged/webrender/src/renderer.rs:2551
#7 0x000055555580f825 in webrender::renderer::Renderer<B>::prepare_gpu_cache (self=0x7fffffff6d88, frame=0x555558d0c108)
at /home/zakorgy/Work/webrender_szeged/webrender/src/renderer.rs:2597
#8 0x00005555557ff3d8 in webrender::renderer::Renderer<B>::render_impl::{{closure}} ()
at /home/zakorgy/Work/webrender_szeged/webrender/src/renderer.rs:2390
#9 0x0000555555dc6397 in webrender::profiler::TimeProfileCounter::profile (self=0x7ffffffee848, callback=...)
at /home/zakorgy/Work/webrender_szeged/webrender/src/profiler.rs:190
#10 0x00005555557fdfb3 in webrender::renderer::Renderer<B>::render_impl (self=0x7fffffff6d88, framebuffer_size=...)
at /home/zakorgy/Work/webrender_szeged/webrender/src/renderer.rs:2348
#11 0x00005555558239bb in webrender::renderer::Renderer<B>::render (self=0x7fffffff6d88, framebuffer_size=...)
at /home/zakorgy/Work/webrender_szeged/webrender/src/renderer.rs:2279
#12 0x0000555555e0dd5f in wrench::wrench::Wrench::render (self=0x7fffffff6d88) at wrench/src/wrench.rs:572
#13 0x0000555555a78a34 in wrench::reftest::ReftestHarness::render_yaml (self=0x7fffffff01f8, filename=0x555558d0cd50,
size=..., font_render_mode=..., allow_mipmaps=false) at wrench/src/reftest.rs:496
#14 0x0000555555a77609 in wrench::reftest::ReftestHarness::run_reftest (self=0x7fffffff01f8, t=0x555558d1f8f0)
at wrench/src/reftest.rs:379
#15 0x0000555555a76bc3 in wrench::reftest::ReftestHarness::run (self=..., base_manifest=0x555557b676e0, reftests=...,
options=0x7fffffff01b0) at wrench/src/reftest.rs:317
#16 0x00005555559737b5 in wrench::reftest (wrench=..., window=0x7fffffff33d8, subargs=0x5555585f9528, rx=...)
at wrench/src/main.rs:503
#17 0x00005555559752fd in wrench::main () at wrench/src/main.rs:664
In order to make rendy work it is necessary to implement traits for gfx-hal
.
The main trait to implement is Device
. Few crates defines Device
trait that extends another one.
Currently, all the provided examples fail to handle resizing or recreation of the Window. It would be useful to have an example that shows the proper way of recreating the swapchain.
Removing failure
and derivative
should be a solid step in this direction. See gfx-rs/gfx#2970 and also #198
Given:
rendy
at the same timeThen sometimes one thread's resource cleanup interferes with the other thread's usage.
This crate just has 100 test functions with an empty GraphBuilder
git clone [email protected]:azriel91/amethyst_rendy_test.git
cd amethyst_rendy_test
cargo update # in case you already had it
cargo test -- --nocapture
# should segfault, if not run it again
# proof that it doesn't segfault with 1 thread:
cargo test -- --nocapture --test-threads 1
Multiple threads share a common "memory space" (? I don't understand rendy
enough). When one is cleaning up, another might be setting up, causing Terminal
to be disposed while some Escape
values are created.
Note:
When run single threaded (cargo test -- --test-threads 1
) with the empty graph, it doesn't segfault.
Further evidence that rendy is correctly disposing in the correct order if you follow the serial control flow.
When run single threaded with RenderTestBundle
, which has the sprites and PresentNode
in the graph, it does segfault.
...
[ERROR][rendy_resource::escape] Terminal must be dropped after all `Escape`s
[ERROR][rendy_resource::escape] Terminal must be dropped after all `Escape`s
[ERROR][rendy_memory::allocator::dynamic] Memory leak: SizeEntry(8192) is still used
[ERROR][rendy_memory::allocator::dynamic] Memory leak: SizeEntry(1024) is still used
[ERROR][rendy_memory::allocator::dynamic] Memory leak: SizeEntry(65536) is still used
[ERROR][rendy_memory::allocator::dynamic] Memory leak: SizeEntry(524288) is still used
[ERROR][rendy_memory::allocator::dynamic] Memory leak: SizeEntry(4194304) is still used
[ERROR][rendy_resource::escape] `Escape` was dropped after a `Terminal`?
...
master
Need to be able to specify levels
in ImageInfo
. Currently the TextureBuilder
doesn't have this information.
My use case requires the wayland layer shell protocol. Winit only works when you are building a standard xdg shell application.
The only reason winit is needed is to get the window size and hidpi scale factor, it should be possible to provide this information as a size: (u32, u32)
when calling into_target
and creating a new surface by providing a raw gfx_hal::Backend::Surface
. The Factory
should then either expose the Instance
or take a closure that takes an Instance
and returns a gfx_hal::Backend::Surface
.
It might be nice to expose the spirv_reflect
crate as well as make this field public so there can be flexibility in extracting more information than what Rendy provides currently. This is in response to writing this to get the names of the uniform variables from both shaders (in the PR PistonDevelopers/turbine#89). Thanks.
The triangle example causes a lot of validation errors.
The quads example causes a lot of validation errors + crashes with Present node dispose not implemented.
texture::image::load_from_image
returns a TextureBuilder
which according to the vulkan validation has unsupported parameters for some source images.
See textured cubes for alle 3 textures in resources.
Both not_working pngs are black in rendy.
using not_working.png:
ERROR 2019-03-20T20:47:02Z: gfx_backend_vulkan: [Validation] [ VUID_Undefined ] Object: VK_NULL_HANDLE (Type = 0) | vkCreateIm
age(): Format VK_FORMAT_R8G8B8_SRGB is not supported for this combination of parameters.
ERROR 2019-03-20T20:47:02Z: gfx_backend_vulkan: [Validation] [ VUID-VkImageViewCreateInfo-None-02273 ] Object: 0x1d (Type = 10
) | vkCreateImageView(): pCreateInfo->format VK_FORMAT_R8G8B8_SRGB with tiling VK_IMAGE_TILING_OPTIMAL has no supported format
features on this physical device. The Vulkan spec states: The format features of the resultant image view must contain at least
one bit. (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkImageViewCreateInfo-None-02273)
Windows 10 64bit
AMD R9 390 Driver 19.2.3
For reproduction purpose I added amethyst-like image loading code to an updated version of learn-rendy.
The working original learn-rendy code uses image::load_from_memory
and to_rgba
but is not optimal for all texture assets.
It looks like the only built-in way to compile a shader is from a file with a path: https://github.com/amethyst/rendy/blob/master/shader/src/shaderc.rs#L57
Can we have a way to just have it take Into<&str>
or something instead, and load the shader source from that string instead of opening the file itself? That would make it possible for things like ggez
to use it without jumping through hoops to mess with file paths, and I expect would be necessary for using on the web where you have no file access to begin with.
Hi,
I'm using rustc 1.33.0-nightly (a2b0f247b 2018-12-30)
. My graphics chipset is Intelยฎ HD Graphics 5500 (Broadwell GT2)
.
When running cargo run --example triangle --features vulkan
, I get the following output (the window opens briefly before crashing with the following - I assume this isn't intended):
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: OutOfDate', src/libcore/result.rs:999:5
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
thread 'main' panicked at 'assertion failed: `(left == right)`
left: `3883100`,
right: `0`', memory/src/allocator/dedicated.rs:174:9
stack backtrace:
0: 0x556040c8c583 - std::sys::unix::backtrace::tracing::imp::unwind_backtrace::h94831b6369ea0bc6
at src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:39
1: 0x556040c87ff8 - std::sys_common::backtrace::_print::h3eadd3a681120c3a
at src/libstd/sys_common/backtrace.rs:70
2: 0x556040c8b032 - std::panicking::default_hook::{{closure}}::h51e50ca514fa5358
at src/libstd/sys_common/backtrace.rs:58
at src/libstd/panicking.rs:200
3: 0x556040c8ada4 - std::panicking::default_hook::h6a9922be127f81dc
at src/libstd/panicking.rs:215
4: 0x556040c8b740 - std::panicking::rust_panic_with_hook::heaf7eac5e1d620dd
at src/libstd/panicking.rs:478
5: 0x556040c8b2c1 - std::panicking::continue_panic_fmt::ha149b879e772ad0e
at src/libstd/panicking.rs:385
6: 0x556040c8b20e - std::panicking::begin_panic_fmt::h812c97985775db0f
at src/libstd/panicking.rs:340
7: 0x556040c1a8f4 - <rendy_memory::allocator::dedicated::DedicatedAllocator as core::ops::drop::Drop>::drop::h47f43e0f59d656d7
at memory/src/allocator/dedicated.rs:174
8: 0x55604014525e - core::ptr::real_drop_in_place::hc26a230528cc21d8
at /rustc/a2b0f247bf741a1a9729363dda8628a938f1fe58/src/libcore/ptr.rs:193
9: 0x556040141d34 - core::ptr::real_drop_in_place::h91ad602ba8cb2a89
at /rustc/a2b0f247bf741a1a9729363dda8628a938f1fe58/src/libcore/ptr.rs:193
10: 0x556040139ee7 - core::ptr::real_drop_in_place::h265e56aad1f8d811
at /rustc/a2b0f247bf741a1a9729363dda8628a938f1fe58/src/libcore/ptr.rs:193
11: 0x5560402cc06f - <alloc::vec::Vec<T> as core::ops::drop::Drop>::drop::hc5eb4ae77e5b587d
at /rustc/a2b0f247bf741a1a9729363dda8628a938f1fe58/src/libcore/ptr.rs:183
at /rustc/a2b0f247bf741a1a9729363dda8628a938f1fe58/src/liballoc/vec.rs:2102
12: 0x556040145df0 - core::ptr::real_drop_in_place::hcb5a6f737adcab4d
at /rustc/a2b0f247bf741a1a9729363dda8628a938f1fe58/src/libcore/ptr.rs:193
13: 0x556040143e50 - core::ptr::real_drop_in_place::hb1b10c9c2cc0f9a5
at /rustc/a2b0f247bf741a1a9729363dda8628a938f1fe58/src/libcore/ptr.rs:193
14: 0x55604013c1ed - core::ptr::real_drop_in_place::h42bfb6595f5c433a
at /rustc/a2b0f247bf741a1a9729363dda8628a938f1fe58/src/libcore/ptr.rs:193
15: 0x556040147931 - core::ptr::real_drop_in_place::he126503329dbd7e6
at /rustc/a2b0f247bf741a1a9729363dda8628a938f1fe58/src/libcore/ptr.rs:193
16: 0x556040145b11 - core::ptr::real_drop_in_place::hc8f176a163ac04fa
at /rustc/a2b0f247bf741a1a9729363dda8628a938f1fe58/src/libcore/ptr.rs:193
17: 0x556040259326 - triangle::main::h5e41d72835494097
at rendy/examples/triangle/main.rs:263
18: 0x55604027e03f - std::rt::lang_start::{{closure}}::hde7abb7342b4a879
at /rustc/a2b0f247bf741a1a9729363dda8628a938f1fe58/src/libstd/rt.rs:64
19: 0x556040c8b142 - std::panicking::try::do_call::hceb5c183e4871fb5
at src/libstd/rt.rs:49
at src/libstd/panicking.rs:297
20: 0x556040c8ffe9 - __rust_maybe_catch_panic
at src/libpanic_unwind/lib.rs:92
21: 0x556040c8bd55 - std::rt::lang_start_internal::h20dfa5ca4123c042
at src/libstd/panicking.rs:276
at src/libstd/panic.rs:388
at src/libstd/rt.rs:48
22: 0x55604027e018 - std::rt::lang_start::h8fe3e3c3beba6449
at /rustc/a2b0f247bf741a1a9729363dda8628a938f1fe58/src/libstd/rt.rs:64
23: 0x5560402595a9 - main
24: 0x7f24ae143222 - __libc_start_main
25: 0x55604005c99d - _start
26: 0x0 - <unknown>
thread panicked while panicking. aborting.
[1] 18130 illegal hardware instruction (core dumped) cargo run --example triangle --features vulkan
The SimpleGraphicsPipeline
trait has a method that returns failure::Error
: https://docs.rs/rendy/0.1.1/rendy/graph/render/trait.SimpleGraphicsPipeline.html#tymethod.build
This seems unnecessary since it looks like it could be easy to replace with an associated Error
type, but if we want to use failure
we should at least re-export it similar to how gfx_hal
is re-exported. That way if users have a version clash somehow, they at least have a convenient reference to the version of failure
we are using. This honestly isn't likely, given how stable failure
is, but I find it to be a useful policy.
From Discord conversation regarding alternative destinations (image, video, memory buffer) for rendy graphs, we need an example of rendering screenshots through rendy.
This way finding examples which match a specific version is easier -- https://github.com/Lokathor/learn-gfx-hal/issues/67
I just ran into an issue where I was accidentally uploading some references to the GPU - passing in &[some_ref]
to upload_visible_buffer
. The 'static
bound would have prevented that error.
On the 4th of July, the hashbrown
implementation for HashMap
will be stabilized, thus fxhash
and fnv
can be replaced with std
.
As I see the provided aux type is never used by the graph.
Can we make it more general to let the client decide if it is &mut T, or &T or a "moved" T object ?
In other word make the &mut part of the generic argument:
Graph<Backend, &mut World> instead of Graph<Backend, World>
or Graph<Backend, &World> instead of Graph<Backend, World>
build(aux: T) instead of build(aux: &mut T)
Impl Default
for SamplerInfo
and the types it contains. ViewKind
as well? MipLevel
? Look at TextureBuilder::new()
for preferred values.
Refactor sprite
example to have a separate method for creating textures?
Can Mesh
and Image
be Clone
?
Things that need docs: resource::Kind
,
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.