diff --git a/.travis.yml b/.travis.yml index 25b231ea..f156164e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,16 +1,40 @@ language: rust -rust: - - stable - - beta - - nightly +cache: + cargo: true + directories: + - $HOME/deps + +compiler: clang + matrix: - allow_failures: - - rust: nightly - fast_finish: true -script: - - cargo test --verbose --all + include: + # Linux 64bit + - os: linux + rust: stable + - os: linux + rust: nightly + + # macOS 64bit + - env: MACOSX_DEPLOYMENT_TARGET=10.9 + os: osx + rust: stable + osx_image: xcode9 + - env: MACOSX_DEPLOYMENT_TARGET=10.9 + os: osx + rust: nightly + osx_image: xcode9 + + # iPhoneOS 64bit + - env: TARGET=aarch64-apple-ios + os: osx + osx_image: xcode9 + rust: nightly + branches: only: - staging - trying - master + +script: + - make diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..0e96e26d --- /dev/null +++ b/Makefile @@ -0,0 +1,20 @@ +RUST_BACKTRACE:=1 +RENDY_FEATURES:= + +ifeq ($(OS),Windows_NT) + RENDY_FEATURES=dx12 +else + UNAME_S:=$(shell uname -s) + ifeq ($(UNAME_S),Linux) + RENDY_FEATURES=vulkan + endif + ifeq ($(UNAME_S),Darwin) + RENDY_FEATURES=metal + endif +endif + +test: + cd rendy && cargo test --all --features $(RENDY_FEATURES) + +doc: + cargo doc diff --git a/factory/Cargo.toml b/factory/Cargo.toml index 18f5cc6a..0f0c2d4b 100644 --- a/factory/Cargo.toml +++ b/factory/Cargo.toml @@ -4,6 +4,7 @@ version = "0.1.0" authors = ["omni-viral "] [features] +empty = ["gfx-backend-empty", "rendy-wsi/gfx-backend-empty"] dx12 = ["gfx-backend-dx12", "rendy-wsi/gfx-backend-dx12"] metal = ["gfx-backend-metal", "rendy-wsi/gfx-backend-metal"] vulkan = ["gfx-backend-vulkan", "rendy-wsi/gfx-backend-vulkan"] @@ -11,6 +12,7 @@ vulkan = ["gfx-backend-vulkan", "rendy-wsi/gfx-backend-vulkan"] [dependencies] derivative = "1.0" failure = "0.1" +gfx-backend-empty = { git = "https://github.com/gfx-rs/gfx", optional = true } gfx-backend-dx12 = { git = "https://github.com/gfx-rs/gfx", optional = true } gfx-backend-metal = { git = "https://github.com/gfx-rs/gfx", optional = true } gfx-backend-vulkan = { git = "https://github.com/gfx-rs/gfx", optional = true } diff --git a/factory/src/factory.rs b/factory/src/factory.rs index e6738dfb..a7b56811 100644 --- a/factory/src/factory.rs +++ b/factory/src/factory.rs @@ -374,6 +374,7 @@ macro_rules! init_factory_for_backend { ($target:ident, $config:ident) => {{ init_factory_for_backend!(match $target, $config + | gfx_backend_empty @ cfg(feature = "empty") | gfx_backend_dx12 @ cfg(feature = "dx12") | gfx_backend_metal @ cfg(feature = "metal") | gfx_backend_vulkan @ cfg(feature = "vulkan") diff --git a/rendy/Cargo.toml b/rendy/Cargo.toml index fa4d1d47..bd23b087 100644 --- a/rendy/Cargo.toml +++ b/rendy/Cargo.toml @@ -4,6 +4,7 @@ version = "0.1.0" authors = ["omni-viral "] [features] +empty = ["rendy-factory/empty", "rendy-wsi/empty", "gfx-backend-empty"] dx12 = ["rendy-factory/dx12", "rendy-wsi/dx12", "gfx-backend-dx12"] metal = ["rendy-factory/metal", "rendy-wsi/metal", "gfx-backend-metal"] vulkan = ["rendy-factory/vulkan", "rendy-wsi/vulkan", "gfx-backend-vulkan"] @@ -20,12 +21,13 @@ rendy-renderer = { path = "../renderer" } rendy-resource = { path = "../resource" } rendy-wsi = { path = "../wsi" } +gfx-hal = { git = "https://github.com/gfx-rs/gfx" } +gfx-backend-empty = { git = "https://github.com/gfx-rs/gfx", optional = true } gfx-backend-dx12 = { git = "https://github.com/gfx-rs/gfx", optional = true } gfx-backend-metal = { git = "https://github.com/gfx-rs/gfx", optional = true } gfx-backend-vulkan = { git = "https://github.com/gfx-rs/gfx", optional = true } [dev-dependencies] -gfx-hal = { git = "https://github.com/gfx-rs/gfx" } env_logger = "0.5" failure = "0.1" lazy_static = "1.0" diff --git a/rendy/examples/init.rs b/rendy/examples/init.rs deleted file mode 100644 index a9e2454e..00000000 --- a/rendy/examples/init.rs +++ /dev/null @@ -1,47 +0,0 @@ - -#[cfg(feature = "dx12")] -type Backend = rendy::dx12::Backend; - -#[cfg(feature = "metal")] -type Backend = rendy::metal::Backend; - -#[cfg(feature = "vulkan")] -type Backend = rendy::vulkan::Backend; - -type Factory = rendy::factory::Factory; - -rendy::shader::compile_to_spirv!( - struct ComputeShader { - kind: Compute, - lang: GLSL, - file: "examples/simple.comp", - } - - struct VertexShader { - kind: Vertex, - lang: GLSL, - file: "examples/simple.vert", - } - - struct FragmentShader { - kind: Fragment, - lang: GLSL, - file: "examples/simple.frag", - } -); - -fn main() -> Result<(), failure::Error> { - - env_logger::Builder::from_default_env() - .filter_module("init", log::LevelFilter::Trace) - .init(); - - log::info!("Running 'init' example"); - - let config: rendy::factory::Config = Default::default(); - - let factory: Factory = Factory::new(config)?; - - factory.dispose(); - Ok(()) -} diff --git a/rendy/examples/simple.comp b/rendy/examples/simple.comp deleted file mode 100644 index 90cbb5b7..00000000 --- a/rendy/examples/simple.comp +++ /dev/null @@ -1,31 +0,0 @@ -#version 450 - -layout(local_size_x = 32, local_size_y = 32) in; -layout(set = 0, binding = 1, rgba32f) uniform imageBuffer bunnies; - -layout(push_constant) uniform Push { - float delta_time; -}; - -void main() { - vec4 bunny = imageLoad(bunnies, int(gl_GlobalInvocationID.x)); - vec2 pos = bunny.rg; - vec2 vel = bunny.ba; - - pos += vel + (delta_time * delta_time) / 2; - vel += delta_time; - - float l = sign(pos.x); - float r = sign(1.0 - pos.x); - - pos.x = 2.0 + r * l * pos.x - 2.0 * r; - vel.x = 2.0 + r * l * vel.x - 2.0 * r; - - float b = sign(pos.y); - float t = sign(1.0 - pos.y); - - pos.y = 2.0 + t * b * pos.y - 2.0 * t; - vel.y = 2.0 + t * b * vel.y - 2.0 * t; - - imageStore(bunnies, int(gl_GlobalInvocationID.x), vec4(pos, vel)); -} diff --git a/rendy/examples/simple.frag b/rendy/examples/simple.frag deleted file mode 100644 index 1b566a34..00000000 --- a/rendy/examples/simple.frag +++ /dev/null @@ -1,12 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable - -layout(early_fragment_tests) in; - -layout(location = 0) in vec2 uv; -// layout(set = 0, binding = 0) uniform sampler2D bunny_image; -layout(location = 0) out vec4 outColor; - -void main() { - outColor = vec4(gl_FragCoord.zzz, 1.0); //texture(bunny_image, uv); -} diff --git a/rendy/examples/simple.rs b/rendy/examples/simple.rs deleted file mode 100644 index 4e6dcb97..00000000 --- a/rendy/examples/simple.rs +++ /dev/null @@ -1,635 +0,0 @@ -extern crate ash; -#[macro_use] -extern crate failure; -#[macro_use] -extern crate log; -extern crate rendy; -extern crate winit; - -use ash::{version::DeviceV1_0, vk}; -use std::{ - ffi::CStr, - time::{Duration, Instant}, -}; - -use failure::Error; - -use rendy::{ - command::{ - CommandBuffer, CommandPool, ExecutableState, gfx_hal::queue::QueueFamilyId, Graphics, MultiShot, - NoIndividualReset, OneShot, OwningCommandPool, PendingState, PrimaryLevel, - }, - factory::{Config, Factory}, - memory::usage::{Data, Dynamic}, - mesh::{AsVertex, Mesh, PosColor}, - renderer::{Renderer, RendererBuilder}, - resource::{Buffer, Image}, - shader::compile_to_spirv, - wsi::Target, -}; - -use winit::{EventsLoop, Window, WindowBuilder}; - -struct FramebufferEtc { - depth: Image, - depth_view: vk::ImageView, - color_view: vk::ImageView, - framebuffer: vk::Framebuffer, - acquire: vk::Semaphore, - release: vk::Semaphore, - fence: vk::Fence, - command_pool: CommandPool, - command_buffer: Option>>>, - indirect_buffer: Buffer, - indirect_buffer_dirty: bool, -} - -struct SimpleRenderer { - mesh: Mesh, - // texture: (Image, vk::ImageView), - target: Target, - family_index: gfx_hal::queue::QueueFamilyId, - render_pass: vk::RenderPass, - layout: vk::PipelineLayout, - pipeline: vk::Pipeline, - framebuffers: Vec, - acquire: vk::Semaphore, - count: u32, -} - -struct SimpleRendererBuilder { - window: Window, - vertices: Vec, - count: u32, -} - -impl Renderer<()> for SimpleRenderer { - type Desc = SimpleRendererBuilder; - - fn run(&mut self, factory: &mut Factory, (): &mut ()) { - // trace!("Render frame"); - - let next_image = self.target.next_image(self.acquire).unwrap(); - // trace!("Next image acquired"); - - let index = next_image.indices()[0]; - let ref mut framebuffer = self.framebuffers[index as usize]; - // trace!("Framebuffer picked"); - - let submit = unsafe { - // Waiting for fence before reset. - factory.wait_for_fence(framebuffer.fence); - // trace!("Fence got signaled"); - - let command_buffer = framebuffer.command_buffer.take().unwrap().complete(); - let (submit, command_buffer) = command_buffer.submit(); - framebuffer.command_buffer = Some(command_buffer); - // trace!("Command buffer ready to resubmit"); - submit - }; - - std::mem::swap(&mut self.acquire, &mut framebuffer.acquire); - - unsafe { - if framebuffer.indirect_buffer_dirty { - let command = vk::DrawIndirectCommand::builder() - .vertex_count(6) - .instance_count(self.count) - .build(); - - factory - .upload_visible_buffer(&mut framebuffer.indirect_buffer, 0, unsafe { - std::slice::from_raw_parts( - &command as *const _ as *const u8, - std::mem::size_of_val(&command), - ) - }).unwrap(); - - framebuffer.indirect_buffer_dirty = false; - // trace!("Indirect command updated"); - } - - factory.reset_fence(framebuffer.fence); - // trace!("Fence reset"); - - let mut queue = factory.queue(self.family_index, 0); - queue.submit( - &[vk::SubmitInfo::builder() - .wait_semaphores(&[framebuffer.acquire]) - .wait_dst_stage_mask(&[gfx_hal::pso::PipelineStage::COLOR_ATTACHMENT_OUTPUT]) - .signal_semaphores(&[framebuffer.release]) - .command_buffers(&[submit.raw()]) - .build()], - framebuffer.fence, - ); - // trace!("Command buffer submitted"); - - next_image - .queue_present(queue.raw(), &[framebuffer.release]) - .unwrap(); - // trace!("Next image present queued"); - } - } - - fn dispose(self, factory: &mut Factory, (): &mut ()) { - factory.queue(self.family_index, 0).wait_idle(); - drop(self.mesh); - // trace!("Mesh dropped"); - unsafe { - for mut framebuffer in self.framebuffers { - factory - .device() - .destroy_framebuffer(framebuffer.framebuffer, None); - // trace!("Frambuffer destroyed"); - factory - .device() - .destroy_image_view(framebuffer.color_view, None); - // trace!("Color view destroyed"); - factory - .device() - .destroy_image_view(framebuffer.depth_view, None); - // trace!("Depth view destroyed"); - drop(framebuffer.depth); - // trace!("Depth image destroyed"); - - framebuffer.command_pool.free_buffers( - factory.device(), - framebuffer.command_buffer.map(|cbuf| cbuf.complete()), - ); - framebuffer.command_pool.dispose(factory.device()); - // trace!("CommandPool destroyed"); - } - factory.device().destroy_pipeline(self.pipeline, None); - // trace!("Pipeline destroyed"); - factory.device().destroy_render_pass(self.render_pass, None); - // trace!("Render-pass destroyed"); - } - factory.destroy_target(self.target); - // trace!("Target destroyed"); - } -} - -compile_to_spirv!( - struct ComputeShader { - kind: Compute, - lang: GLSL, - file: "examples/simple.comp", - } - - struct VertexShader { - kind: Vertex, - lang: GLSL, - file: "examples/simple.vert", - } - - struct FragmentShader { - kind: Fragment, - lang: GLSL, - file: "examples/simple.frag", - } -); - -impl RendererBuilder<()> for SimpleRendererBuilder { - type Error = Error; - type Renderer = SimpleRenderer; - - fn build(self, factory: &mut Factory, (): &mut ()) -> Result { - let target = factory.create_target(self.window, 3)?; - - let extent = target.extent(); - - let (index, _) = factory - .families() - .iter() - .enumerate() - .find(|(index, family)| { - let graphics = family.capability().subset(gfx_hal::QueueType::Graphics); - let presentation = factory.target_support(family.index(), &target); - graphics && presentation - }).ok_or_else(|| format_err!("Can't find queue capable of graphics and presentation"))?; - - let family_index = gfx_hal::queue::QueueFamilyId(index as u32); - - let mesh = Mesh::new() - .with_vertices(self.vertices) - .with_prim_type(vk::PrimitiveTopology::TRIANGLE_LIST) - .build(gfx_hal::queue::QueueFamilyId(0), factory)?; - - let render_pass = unsafe { - // Seems OK. - // TODO: Provide better safety explanation. - factory.device().create_render_pass( - &vk::RenderPassCreateInfo::builder() - .attachments(&[ - vk::AttachmentDescription::builder() - .format(target.format()) - .samples(vk::SampleCountFlags::TYPE_1) - .load_op(vk::AttachmentLoadOp::CLEAR) - .store_op(vk::AttachmentStoreOp::STORE) - .stencil_load_op(vk::AttachmentLoadOp::DONT_CARE) - .stencil_store_op(vk::AttachmentStoreOp::DONT_CARE) - .initial_layout(vk::ImageLayout::UNDEFINED) - .final_layout(vk::ImageLayout::PRESENT_SRC_KHR) - .build(), - vk::AttachmentDescription::builder() - .format(vk::Format::D32_SFLOAT) - .load_op(vk::AttachmentLoadOp::CLEAR) - .store_op(vk::AttachmentStoreOp::DONT_CARE) - .stencil_load_op(vk::AttachmentLoadOp::DONT_CARE) - .stencil_store_op(vk::AttachmentStoreOp::DONT_CARE) - .initial_layout(vk::ImageLayout::UNDEFINED) - .final_layout(vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL) - .build(), - ]).subpasses(&[vk::SubpassDescription::builder() - .pipeline_bind_point(vk::PipelineBindPoint::GRAPHICS) - .color_attachments(&[vk::AttachmentReference::builder() - .attachment(0) - .layout(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL) - .build()]).depth_stencil_attachment( - &vk::AttachmentReference::builder() - .attachment(1) - .layout(vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL) - .build(), - ).build()]).dependencies(&[ - vk::SubpassDependency::builder() - .src_subpass(!0) - .src_stage_mask(gfx_hal::pso::PipelineStage::TOP_OF_PIPE) - .src_access_mask(vk::AccessFlags::empty()) - .dst_subpass(0) - .dst_access_mask(vk::AccessFlags::COLOR_ATTACHMENT_WRITE) - .dst_stage_mask(gfx_hal::pso::PipelineStage::COLOR_ATTACHMENT_OUTPUT) - .build(), - vk::SubpassDependency::builder() - .src_subpass(0) - .src_access_mask(vk::AccessFlags::COLOR_ATTACHMENT_WRITE) - .src_stage_mask(gfx_hal::pso::PipelineStage::COLOR_ATTACHMENT_OUTPUT) - .dst_subpass(!0) - .dst_stage_mask(gfx_hal::pso::PipelineStage::BOTTOM_OF_PIPE) - .dst_access_mask(vk::AccessFlags::empty()) - .build(), - ]).build(), - None, - ) - }?; - - let layout = unsafe { - factory - .device() - .create_pipeline_layout(&vk::PipelineLayoutCreateInfo::builder().build(), None) - }?; - - let (vertex, fragment) = unsafe { - let vertex = factory.device().create_shader_module( - &vk::ShaderModuleCreateInfo::builder() - .code(VertexShader::SPIRV) - .build(), - None, - )?; - - let fragment = factory.device().create_shader_module( - &vk::ShaderModuleCreateInfo::builder() - .code(FragmentShader::SPIRV) - .build(), - None, - )?; - - (vertex, fragment) - }; - - let pipeline = unsafe { - let mut pipelines = - factory - .device() - .create_graphics_pipelines( - vk::PipelineCache::null(), - &[ - vk::GraphicsPipelineCreateInfo::builder() - .stages(&[ - vk::PipelineShaderStageCreateInfo::builder() - .stage(vk::ShaderStageFlags::VERTEX) - .module(vertex) - .name(CStr::from_bytes_with_nul_unchecked(b"main\0")) - .build(), - vk::PipelineShaderStageCreateInfo::builder() - .stage(vk::ShaderStageFlags::FRAGMENT) - .module(fragment) - .name(CStr::from_bytes_with_nul_unchecked(b"main\0")) - .build(), - ]).vertex_input_state( - &vk::PipelineVertexInputStateCreateInfo::builder() - // .vertex_binding_descriptions(&[ - // vk::VertexInputBindingDescription::builder() - // .binding(0) - // .stride(PosColor::VERTEX.stride) - // .input_rate(vk::VertexInputRate::VERTEX) - // .build(), - // ]) - // .vertex_attribute_descriptions( - // &PosColor::VERTEX.attributes.iter().enumerate().map(|(location, attribute)| - // vk::VertexInputAttributeDescription::builder() - // .location(location as u32) - // .binding(0) - // .format(attribute.format) - // .offset(attribute.offset) - // .build() - // ).collect::>() - // ) - .build(), - ).input_assembly_state( - &vk::PipelineInputAssemblyStateCreateInfo::builder() - .topology(vk::PrimitiveTopology::TRIANGLE_LIST) - .build(), - ).viewport_state( - &vk::PipelineViewportStateCreateInfo::builder() - .viewports(&[vk::Viewport::builder() - .width(extent.width as f32) - .height(extent.height as f32) - .min_depth(0.0) - .max_depth(1.0) - .build()]).scissors(&[vk::Rect2D::builder() - .extent(extent) - .build()]).build(), - ).rasterization_state( - &vk::PipelineRasterizationStateCreateInfo::builder() - .build(), - ).multisample_state( - &vk::PipelineMultisampleStateCreateInfo::builder() - .rasterization_samples(vk::SampleCountFlags::TYPE_1) - .build(), - ).depth_stencil_state( - &vk::PipelineDepthStencilStateCreateInfo::builder() - .depth_test_enable(1) - .depth_write_enable(1) - .depth_compare_op(vk::CompareOp::LESS) - .depth_bounds_test_enable(1) - .min_depth_bounds(0.0) - .max_depth_bounds(1.0) - .build(), - ).color_blend_state( - &vk::PipelineColorBlendStateCreateInfo::builder() - .attachments(&[ - vk::PipelineColorBlendAttachmentState::builder() - .blend_enable(1) - .src_color_blend_factor( - vk::BlendFactor::ONE_MINUS_DST_ALPHA, - ).dst_color_blend_factor(vk::BlendFactor::DST_ALPHA) - .color_blend_op(vk::BlendOp::ADD) - .src_alpha_blend_factor( - vk::BlendFactor::ONE_MINUS_DST_ALPHA, - ).dst_alpha_blend_factor(vk::BlendFactor::ONE) - .alpha_blend_op(vk::BlendOp::ADD) - .color_write_mask(vk::ColorComponentFlags::all()) - .build() - ], - ) - .build(), - ).layout(layout) - .render_pass(render_pass) - .base_pipeline_index(-1) - .build(), - ], - None, - ).map_err(|(_, error)| error)?; - - pipelines.remove(0) - }; - - let framebuffers = unsafe { - target - .images() - .iter() - .map(|&image| { - let depth = factory.create_image( - vk::ImageCreateInfo::builder() - .image_type(vk::ImageType::TYPE_2D) - .format(vk::Format::D32_SFLOAT) - .extent(gfx_hal::image::Extent { - width: target.extent().width, - height: target.extent().height, - depth: 1, - }).mip_levels(1) - .array_layers(1) - .samples(vk::SampleCountFlags::TYPE_1) - .tiling(vk::ImageTiling::OPTIMAL) - .usage(vk::ImageUsageFlags::DEPTH_STENCIL_ATTACHMENT) - .sharing_mode(vk::SharingMode::EXCLUSIVE) - .initial_layout(vk::ImageLayout::UNDEFINED) - .build(), - 1, - Data, - )?; - let depth_view = factory.device().create_image_view( - &vk::ImageViewCreateInfo::builder() - .image(depth.raw()) - .view_type(vk::ImageViewType::TYPE_2D) - .format(vk::Format::D32_SFLOAT) - .subresource_range( - vk::ImageSubresourceRange::builder() - .aspect_mask(vk::ImageAspectFlags::COLOR) - .level_count(1) - .layer_count(1) - .build(), - ).build(), - None, - )?; - let color_view = factory.device().create_image_view( - &vk::ImageViewCreateInfo::builder() - .image(image) - .view_type(vk::ImageViewType::TYPE_2D) - .format(target.format()) - .subresource_range( - vk::ImageSubresourceRange::builder() - .aspect_mask(vk::ImageAspectFlags::COLOR) - .level_count(1) - .layer_count(1) - .build(), - ).build(), - None, - )?; - let framebuffer = factory.device().create_framebuffer( - &vk::FramebufferCreateInfo::builder() - .render_pass(render_pass) - .attachments(&[color_view, depth_view]) - .width(target.extent().width) - .height(target.extent().height) - .layers(1) - .build(), - None, - )?; - - let mut command_pool = unsafe { - let ref family = factory.families()[family_index.0 as usize]; - family - .create_pool(factory.device(), NoIndividualReset)? - .from_queue_type() - .unwrap() - }; - - let indirect_buffer = factory.create_buffer( - vk::BufferCreateInfo::builder() - .size(std::mem::size_of::() as u64) - .usage(vk::BufferUsageFlags::INDIRECT_BUFFER) - .build(), - 1, - Dynamic, - )?; - - let command_buffer = command_pool - .allocate_buffers(factory.device(), PrimaryLevel, 1) - .remove(0); - let command_buffer = command_buffer.begin(factory.device(), MultiShot(())); - - unsafe { - // Unsafe command recording. - factory.device().cmd_begin_render_pass( - command_buffer.raw(), - &vk::RenderPassBeginInfo::builder() - .render_pass(render_pass) - .framebuffer(framebuffer) - .render_area(vk::Rect2D::builder().extent(target.extent()).build()) - .clear_values(&[ - vk::ClearValue { - color: vk::ClearColorValue { - uint32: [0, 0, 0, 255], - }, - }, - vk::ClearValue { - depth_stencil: vk::ClearDepthStencilValue { - depth: 1.0, - stencil: 0, - }, - }, - ]).build(), - vk::SubpassContents::INLINE, - ); - - factory.device().cmd_bind_pipeline( - command_buffer.raw(), - vk::PipelineBindPoint::GRAPHICS, - pipeline, - ); - - factory.device().cmd_bind_descriptor_sets( - command_buffer.raw(), - vk::PipelineBindPoint::GRAPHICS, - layout, - 0, - &[], // &[descriptor_set], - &[], - ); - - factory.device().cmd_draw_indirect( - command_buffer.raw(), - indirect_buffer.raw(), - 0, - 1, - 0, - ); - - factory.device().cmd_end_render_pass(command_buffer.raw()); - }; - - let command_buffer = command_buffer.finish(factory.device()); - let command_buffer = Some(command_buffer.submit().1); - - Ok(FramebufferEtc { - depth, - depth_view, - color_view, - framebuffer, - acquire: factory.create_semaphore(), - release: factory.create_semaphore(), - fence: factory.create_fence(true), - command_buffer, - command_pool, - indirect_buffer, - indirect_buffer_dirty: true, - }) - }).collect::, Error>>() - }?; - - Ok(SimpleRenderer { - mesh, - // texture: unimplemented!(), - target, - family_index, - render_pass, - layout, - pipeline, - framebuffers, - acquire: factory.create_semaphore(), - count: self.count, - }) - } -} - -fn main() -> Result<(), failure::Error> { - env_logger::Builder::from_default_env() - .default_format_timestamp_nanos(true) - .filter_module("simple", log::LevelFilter::Trace) - .init(); - - let config: Config = Default::default(); - - let mut factory: Factory = Factory::new(config)?; - - let mut event_loop = EventsLoop::new(); - - let window = WindowBuilder::new() - .with_title("Rendy example") - .build(&event_loop)?; - - event_loop.poll_events(|_| ()); - - let renderer_builder = SimpleRendererBuilder { - window, - vertices: vec![ - PosColor { - position: [0.0, -0.5, 0.5].into(), - color: [1.0, 0.0, 0.0, 1.0].into(), - }, - PosColor { - position: [-0.5, 0.5, 0.5].into(), - color: [0.0, 1.0, 0.0, 1.0].into(), - }, - PosColor { - position: [0.5, 0.5, 0.5].into(), - color: [0.0, 0.0, 1.0, 1.0].into(), - }, - ], - count: 300_000, - }; - - let mut renderer = renderer_builder.build(&mut factory, &mut ())?; - - // trace!("Start rendering"); - let mut counter = 0..; - let started = Instant::now(); - let duration = Duration::new(10, 0); - counter - .by_ref() - .take_while(|_| started.elapsed() < duration) - .for_each(|_| { - event_loop.poll_events(|_| ()); - renderer.run(&mut factory, &mut ()); - // std::thread::sleep(Duration::new(0, 1_000_000)); - }); - - let total_micros = duration.as_secs() * 1_000_000 + duration.subsec_micros() as u64; - - info!( - "Rendered {} frames for {}.{:03} secs. FPS: {}", - counter.start, - duration.as_secs(), - duration.subsec_millis(), - counter.start * 1_000_000 / total_micros - ); - // trace!("Stop rendering"); - - renderer.dispose(&mut factory, &mut ()); - // trace!("Render disposed"); - - factory.dispose(); - // trace!("Factory disposed"); - Ok(()) -} diff --git a/rendy/examples/simple.vert b/rendy/examples/simple.vert deleted file mode 100644 index 4d87a540..00000000 --- a/rendy/examples/simple.vert +++ /dev/null @@ -1,26 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable -// layout(set = 0, binding = 1, rgba32f) uniform imageBuffer bunnies; - -vec2 positions[6] = vec2[]( - vec2(0.0, 0.0), - vec2(1.0, 0.0), - vec2(1.0, 1.0), - vec2(1.0, 1.0), - vec2(0.0, 1.0), - vec2(0.0, 0.0) -); - -layout(location = 0) out vec2 uv; - -void main() { - float isin = sin(gl_InstanceIndex * 3469); - float icos = cos(gl_InstanceIndex * 7901); - vec2 vertex = positions[gl_VertexIndex]; - vec4 bunny = vec4(isin, icos, 0.0, 0.0);// imageLoad(bunnies, gl_InstanceIndex); - vec2 pos = bunny.rg; - pos += vertex * 0.003; - pos = pos / 1.003 * 2.0 - 1.0; - uv = vertex; - gl_Position = vec4(pos, isin * icos, 1.0); -} diff --git a/rendy/examples/triangles.rs b/rendy/examples/triangles.rs index d8d186c5..bb906779 100644 --- a/rendy/examples/triangles.rs +++ b/rendy/examples/triangles.rs @@ -19,6 +19,9 @@ use winit::{ EventsLoop, WindowBuilder, }; +#[cfg(feature = "empty")] +type Backend = rendy::empty::Backend; + #[cfg(feature = "dx12")] type Backend = rendy::dx12::Backend; diff --git a/rendy/examples/window.rs b/rendy/examples/window.rs deleted file mode 100644 index 344911d9..00000000 --- a/rendy/examples/window.rs +++ /dev/null @@ -1,45 +0,0 @@ - -use std::time::{Duration, Instant}; - -#[cfg(feature = "dx12")] -type Backend = rendy::dx12::Backend; - -#[cfg(feature = "metal")] -type Backend = rendy::metal::Backend; - -#[cfg(feature = "vulkan")] -type Backend = rendy::vulkan::Backend; - -type Factory = rendy::factory::Factory; - -fn main() -> Result<(), failure::Error> { - let started = Instant::now(); - - env_logger::init(); - - let config: rendy::factory::Config = Default::default(); - - let factory: Factory = Factory::new(config)?; - - let mut event_loop = winit::EventsLoop::new(); - - let window = winit::WindowBuilder::new() - .with_title("Rendy example") - .build(&event_loop)?; - - event_loop.poll_events(|_| ()); - - let target = factory.create_target(window, 3, gfx_hal::image::Usage::empty())?; - - while started.elapsed() < Duration::new(5, 0) { - event_loop.poll_events(|_| ()); - std::thread::sleep(Duration::new(0, 1_000_000)); - } - - unsafe { - factory.destroy_target(target); - } - - factory.dispose(); - Ok(()) -} diff --git a/rendy/src/lib.rs b/rendy/src/lib.rs index becd3937..077e043a 100644 --- a/rendy/src/lib.rs +++ b/rendy/src/lib.rs @@ -9,6 +9,11 @@ pub extern crate rendy_resource as resource; pub extern crate rendy_shader as shader; pub extern crate rendy_wsi as wsi; +pub extern crate gfx_hal as hal; + +#[cfg(feature = "gfx-backend-empty")] +pub extern crate gfx_backend_empty as empty; + #[cfg(feature = "gfx-backend-dx12")] pub extern crate gfx_backend_dx12 as dx12; diff --git a/resource/src/escape.rs b/resource/src/escape.rs index 00889c04..abd2a2c9 100644 --- a/resource/src/escape.rs +++ b/resource/src/escape.rs @@ -51,11 +51,11 @@ impl Drop for Inner { /// /// # Example /// -/// ```no_run +/// ``` /// # extern crate rendy_resource; /// # use rendy_resource::*; /// -/// fn foo(buffer: Buffer) { +/// fn foo(buffer: Buffer) { /// let kp: KeepAlive = buffer.keep_alive(); /// /// // `kp` keeps this buffer from being destroyed. diff --git a/wsi/Cargo.toml b/wsi/Cargo.toml index 7150944f..574f8cb4 100644 --- a/wsi/Cargo.toml +++ b/wsi/Cargo.toml @@ -4,6 +4,7 @@ version = "0.1.0" authors = ["omni-viral "] [features] +empty = ["gfx-backend-empty"] dx12 = ["gfx-backend-dx12"] metal = ["gfx-backend-metal"] vulkan = ["gfx-backend-vulkan"] @@ -11,6 +12,7 @@ vulkan = ["gfx-backend-vulkan"] [dependencies] derivative = "1.0" failure = "0.1" +gfx-backend-empty = { git = "https://github.com/gfx-rs/gfx", optional = true } gfx-backend-dx12 = { git = "https://github.com/gfx-rs/gfx", optional = true } gfx-backend-metal = { git = "https://github.com/gfx-rs/gfx", optional = true } gfx-backend-vulkan = { git = "https://github.com/gfx-rs/gfx", optional = true } diff --git a/wsi/src/lib.rs b/wsi/src/lib.rs index d6871cb6..05b74357 100644 --- a/wsi/src/lib.rs +++ b/wsi/src/lib.rs @@ -1,5 +1,12 @@ +#[cfg(feature = "empty")] +mod gfx_backend_empty { + pub(super) fn create_surface(instance: &gfx_backend_empty::Instance, window: &winit::Window) -> gfx_backend_empty::Surface { + unimplemented!() + } +} + #[cfg(feature = "metal")] mod gfx_backend_metal { pub(super) fn create_surface(instance: &gfx_backend_metal::Instance, window: &winit::Window) -> gfx_backend_metal::Surface { @@ -43,6 +50,7 @@ macro_rules! create_surface_for_backend { ($instance:ident, $window:ident) => {{ create_surface_for_backend!(match $instance, $window + | gfx_backend_empty @ cfg(feature = "empty") | gfx_backend_dx12 @ cfg(feature = "dx12") | gfx_backend_metal @ cfg(feature = "metal") | gfx_backend_vulkan @ cfg(feature = "vulkan") @@ -127,7 +135,7 @@ where .max(capabilities.image_count.start); log::info!("Surface capabilities: {:#?}. Pick {} images", capabilities.image_count, image_count); - assert!(capabilities.usage.contains(usage)); + assert!(capabilities.usage.contains(usage), "Surface supports {:?}, but {:?} was requested"); let (swapchain, backbuffer) = device.create_swapchain( &mut self.raw,