Skip to content

Commit

Permalink
Merge 'gfx-components' into master: Split gfx_hal implementation into…
Browse files Browse the repository at this point in the history
… modules
  • Loading branch information
MattRyder committed Apr 13, 2019
1 parent fd698ba commit 3d4c64a
Show file tree
Hide file tree
Showing 20 changed files with 2,127 additions and 1,152 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Expand Up @@ -23,5 +23,5 @@ before_install:
- sudo apt-get install -y clang-3.9

script:
- cargo build --verbose --all --features=empty
- travis_wait cargo build --verbose --all --features=empty
- cargo test --verbose --all --features=empty
846 changes: 476 additions & 370 deletions Cargo.lock

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions Cargo.toml
Expand Up @@ -20,17 +20,17 @@ path = "src/bin.rs"

[dependencies]
assimp = "0.3.1"
cgmath = "0.16.1"
env_logger = "0.6.0"
cgmath = "0.17.0"
env_logger = "0.6.1"
error-chain = "0.12.0"
image = "0.20.1"
image = "0.21.1"
log = "0.4.6"
shaderc = "0.3.12"
winit = "0.18.0"
shaderc = "0.3.16"
winit ="0.19.1"

gfx-hal = "0.1.0"
gfx-backend-empty = { version = "0.1.0", optional = true }
gfx-backend-dx12 = { version = "0.1.0", optional = true }
gfx-backend-empty = { version = "0.1.1", optional = true }
gfx-backend-dx12 = { version = "0.1.3", optional = true }
gfx-backend-gl = { version = "0.1.0", optional = true }
gfx-backend-metal = { version = "0.1.0", optional = true }
gfx-backend-vulkan = { version = "0.1.0", optional = true }
32 changes: 32 additions & 0 deletions src/graphics/adapter.rs
@@ -0,0 +1,32 @@
use gfx_hal::*;

/// Defines the capabilities of a single graphics adapter
pub struct AdapterState<B: Backend> {
pub adapter: Option<Adapter<B>>,
pub mem_types: Vec<MemoryType>,
pub limits: Limits,
}

impl<B: Backend> AdapterState<B> {
pub fn new(adapters: &mut Vec<Adapter<B>>) -> Self {
for adapter in adapters.iter() {
info!("Available {:?}", adapter.info);
}

// TODO: Iterate and choose the most optimal adapter
warn!("Choosing Adapter(0) by default.");

let adapter = adapters.remove(0);

let mem_types = adapter.physical_device.memory_properties().memory_types;
let limits = adapter.physical_device.limits();

info!("Adapter Limits: {:?}", &limits);

AdapterState {
adapter: Some(adapter),
mem_types,
limits,
}
}
}
74 changes: 74 additions & 0 deletions src/graphics/backend.rs
@@ -0,0 +1,74 @@
use gfx_hal::format::{AsFormat, Rgba8Srgb};
use gfx_hal::*;
use graphics::adapter::AdapterState;
use graphics::window::WindowState;

pub type ColorFormat = Rgba8Srgb;

pub trait SurfaceTrait {
#[cfg(feature = "gl")]
fn get_window_t(&self) -> &gfx_backend::glutin::GlWindow;
}

impl SurfaceTrait for <gfx_backend::Backend as gfx_hal::Backend>::Surface {
#[cfg(feature = "gl")]
fn get_window_t(&self) -> &gfx_backend::glutin::GlWindow {
self.get_window()
}
}

pub struct BackendState<B: Backend> {
pub surface: B::Surface,
pub adapter_state: AdapterState<B>,

#[cfg(any(feature = "vulkan", feature = "dx12", feature = "metal"))]
pub window: Window,
}

impl<B: Backend> BackendState<B> {

#[cfg(any(feature = "vulkan", feature = "dx12", feature = "metal"))]
pub fn new(window_state: &mut WindowState) -> (BackendState<gfx_backend::Backend>, gfx_backend::Instance) {
let window = window_state.window_builder.take().unwrap().build(&window_state.event_loop).unwrap();

let instance = gfx_backend::Instance::create("libcorporation", 1);
let surface = instance.create_surface(&window);
let mut adapters = instance.enumerate_adapters();

let backend_state = BackendState {
adapter_state: AdapterState::new(&mut adapters),
surface,
window,
};

(backend_state, instance)
}

#[cfg(feature = "gl")]
pub fn new(window_state: &mut WindowState) -> (BackendState<gfx_backend::Backend>, ()) {
let window = {
let builder = gfx_backend::config_context(gfx_backend::glutin::ContextBuilder::new(), ColorFormat::SELF, None).with_vsync(true);

gfx_backend::glutin::GlWindow::new(
window_state.window_builder.take().unwrap(),
builder,
window_state.borrow_event_loop(),
).unwrap()
};

let surface = gfx_backend::Surface::from_window(window);
let mut adapters = surface.enumerate_adapters();

let backend_state = BackendState {
adapter_state: AdapterState::new(&mut adapters),
surface
};

(backend_state, ())
}

#[cfg(feature = "empty")]
pub fn new(window_state: &mut WindowState) {

}
}
135 changes: 135 additions & 0 deletions src/graphics/buffer.rs
@@ -0,0 +1,135 @@
use gfx_hal::memory as m;
use gfx_hal::*;
use graphics::adapter::AdapterState;
use graphics::device::DeviceState;
use graphics::image::Image;
use std::cell::RefCell;
use std::rc::Rc;

pub struct BufferState<B: Backend, C: Capability> {
device_state: Rc<RefCell<DeviceState<B, C>>>,
memory: Option<B::Memory>,
pub buffer: Option<B::Buffer>,
size: u64,
}

impl<B: Backend, C: Capability> BufferState<B, C> {
pub unsafe fn new<T>(
device_state: Rc<RefCell<DeviceState<B, C>>>,
buffer_source: &[T],
buffer_usage: buffer::Usage,
memory_types: &[MemoryType],
) -> Self
where
T: Copy,
{
let stride = std::mem::size_of::<T>() as u64;
let upload_size = buffer_source.len() as u64 * stride;

let device = &device_state.borrow().device;

let mut buffer = device.create_buffer(upload_size, buffer_usage).unwrap();

let (memory, memory_size) = Self::allocate_buffer_memory(device, &buffer, memory_types, m::Properties::CPU_VISIBLE);

device.bind_buffer_memory(&memory, 0, &mut buffer).unwrap();

// Write the data to the buffer
{
let mut data_target = device.acquire_mapping_writer::<T>(&memory, 0..memory_size).unwrap();
data_target[0..buffer_source.len()].copy_from_slice(&buffer_source);
device.release_mapping_writer(data_target).unwrap();
}

BufferState {
device_state: Rc::clone(&device_state),
memory: Some(memory),
buffer: Some(buffer),
size: memory_size,
}
}

/// Locates an available space in memory for the buffer depending on buffer requirements and memory property
pub fn find_buffer_memory(memory_types: &[MemoryType], memory_requirements: &m::Requirements, property: m::Properties) -> MemoryTypeId {
memory_types
.iter()
.enumerate()
.position(|(id, mem_type)| memory_requirements.type_mask & (1 << id) != 0 && mem_type.properties.contains(property))
.unwrap()
.into()
}

unsafe fn allocate_buffer_memory(
device: &B::Device,
buffer: &B::Buffer,
memory_types: &[MemoryType],
memory_property: m::Properties,
) -> (B::Memory, u64) {
let buffer_mem_requirements = device.get_buffer_requirements(&buffer);

let size = buffer_mem_requirements.size;

let upload_type = Self::find_buffer_memory(memory_types, &buffer_mem_requirements, memory_property);

let memory = device.allocate_memory(upload_type, size).unwrap();

(memory, size)
}

pub unsafe fn new_texture(
device_state: Rc<RefCell<DeviceState<B, C>>>,
device: &B::Device,
adapter_state: &AdapterState<B>,
image: &Image,
buffer_usage: buffer::Usage,
) -> Self {
let row_alignment_mask = adapter_state.limits.min_buffer_copy_pitch_alignment as u32 - 1;

let upload_size = image.get_upload_size(row_alignment_mask);

let mut buffer = device.create_buffer(upload_size, buffer_usage).unwrap();

let (memory, memory_size) = Self::allocate_buffer_memory(device, &buffer, &adapter_state.mem_types, m::Properties::CPU_VISIBLE);

device.bind_buffer_memory(&memory, 0, &mut buffer).unwrap();

{
let mut data_target = device.acquire_mapping_writer::<u8>(&memory, 0..memory_size).unwrap();

let (_width, height) = image.get_dimensions();

let img = &image.get_image().clone().into_raw();
let row_pitch = image.row_pitch(row_alignment_mask);

// Parse each row of the texture into the buffer:
for y in 0..(height as usize) {
let row_range = image.row_range(y);
let row = &(img)[row_range.start..row_range.end];

let dst_base = y * row_pitch as usize;
data_target[dst_base..dst_base + row.len()].copy_from_slice(row);
}

device.release_mapping_writer(data_target).unwrap();
}

BufferState {
device_state: Rc::clone(&device_state),
memory: Some(memory),
buffer: Some(buffer),
size: upload_size,
}
}

pub fn get_buffer(&self) -> &B::Buffer {
self.buffer.as_ref().unwrap()
}

pub fn get_buffer_view(&self) -> buffer::IndexBufferView<B> {
buffer::IndexBufferView {
buffer: self.buffer.as_ref().unwrap(),
offset: 0,
index_type: IndexType::U16,
}
}
}

0 comments on commit 3d4c64a

Please sign in to comment.