pathfinder: data binding

This commit is contained in:
Carter Anderson 2020-05-11 20:12:48 -07:00
parent 0dd55f2c40
commit 4eb562975f
37 changed files with 303 additions and 177 deletions

4
.vscode/launch.json vendored
View File

@ -33,11 +33,11 @@
"cargo": { "cargo": {
"args": [ "args": [
"build", "build",
"--example=scene", "--example=pathfinder",
"--package=bevy" "--package=bevy"
], ],
"filter": { "filter": {
"name": "scene", "name": "pathfinder",
"kind": "example" "kind": "example"
} }
}, },

View File

@ -2,18 +2,21 @@ use bevy_asset::{AssetStorage, Handle};
use bevy_render::{ use bevy_render::{
pass::{ pass::{
LoadOp, PassDescriptor, RenderPassColorAttachmentDescriptor, LoadOp, PassDescriptor, RenderPassColorAttachmentDescriptor,
RenderPassDepthStencilAttachmentDescriptor, StoreOp, TextureAttachment, RenderPassDepthStencilAttachmentDescriptor, StoreOp, TextureAttachment, RenderPass,
}, },
pipeline::{ pipeline::{
state_descriptors::{ state_descriptors::{
BlendDescriptor, BlendFactor, BlendOperation, ColorStateDescriptor, ColorWrite, BlendDescriptor, BlendFactor, BlendOperation, ColorStateDescriptor, ColorWrite,
CompareFunction, DepthStencilStateDescriptor, StencilOperation, CompareFunction, DepthStencilStateDescriptor, StencilOperation,
StencilStateFaceDescriptor, StencilStateFaceDescriptor, RasterizationStateDescriptor, PrimitiveTopology,
}, },
InputStepMode, PipelineDescriptor, VertexAttributeDescriptor, VertexBufferDescriptor, InputStepMode, PipelineDescriptor, VertexAttributeDescriptor, VertexBufferDescriptor,
VertexFormat, VertexFormat,
}, },
render_resource::{BufferInfo, BufferUsage, RenderResource, RenderResourceAssignments}, render_resource::{
BufferInfo, BufferUsage, RenderResource, RenderResourceAssignment,
RenderResourceAssignments,
},
renderer::RenderContext, renderer::RenderContext,
shader::{Shader, ShaderSource, ShaderStage, ShaderStages}, shader::{Shader, ShaderSource, ShaderStage, ShaderStages},
texture::{ texture::{
@ -31,7 +34,9 @@ use pathfinder_gpu::{
VertexAttrClass, VertexAttrDescriptor, VertexAttrType, VertexAttrClass, VertexAttrDescriptor, VertexAttrType,
}; };
use pathfinder_resources::ResourceLoader; use pathfinder_resources::ResourceLoader;
use std::{borrow::Cow, cell::RefCell, collections::HashMap, mem, rc::Rc, time::Duration, ops::Range}; use std::{
borrow::Cow, cell::RefCell, collections::HashMap, mem, rc::Rc, time::Duration,
};
use zerocopy::AsBytes; use zerocopy::AsBytes;
pub struct BevyPathfinderDevice<'a> { pub struct BevyPathfinderDevice<'a> {
@ -40,6 +45,7 @@ pub struct BevyPathfinderDevice<'a> {
samplers: RefCell<HashMap<u8, RenderResource>>, samplers: RefCell<HashMap<u8, RenderResource>>,
main_color_texture: RenderResource, main_color_texture: RenderResource,
main_depth_stencil_texture: RenderResource, main_depth_stencil_texture: RenderResource,
default_sampler: RenderResource,
} }
impl<'a> BevyPathfinderDevice<'a> { impl<'a> BevyPathfinderDevice<'a> {
@ -49,21 +55,182 @@ impl<'a> BevyPathfinderDevice<'a> {
main_color_texture: RenderResource, main_color_texture: RenderResource,
main_depth_stencil_texture: RenderResource, main_depth_stencil_texture: RenderResource,
) -> Self { ) -> Self {
let default_sampler = render_context.resources().create_sampler(&SamplerDescriptor::default());
BevyPathfinderDevice { BevyPathfinderDevice {
render_context: RefCell::new(render_context), render_context: RefCell::new(render_context),
shaders: RefCell::new(shaders), shaders: RefCell::new(shaders),
samplers: RefCell::new(HashMap::new()), samplers: RefCell::new(HashMap::new()),
main_color_texture, main_color_texture,
main_depth_stencil_texture, main_depth_stencil_texture,
default_sampler,
} }
} }
pub fn prepare_to_draw(&self, render_state: &RenderState<BevyPathfinderDevice>) { pub fn setup_uniforms(
let pass_descriptor = self.create_pass_descriptor(render_state); &self,
self.setup_pipline_descriptor(render_state, &pass_descriptor, &render_state.vertex_array.requested_descriptors.borrow()); render_state: &RenderState<BevyPathfinderDevice>,
// TODO: setup uniforms render_resource_assignments: &mut RenderResourceAssignments,
let mut render_context = self.render_context.borrow_mut(); ) {
let mut render_resource_assignments = RenderResourceAssignments::default(); let mut uniform_buffer_data = Vec::new();
let mut uniform_buffer_ranges = Vec::new();
for (bevy_uniform, uniform_data) in render_state.uniforms.iter() {
let start_index = uniform_buffer_data.len();
match *uniform_data {
UniformData::Float(value) => uniform_buffer_data
.write_f32::<NativeEndian>(value)
.unwrap(),
UniformData::IVec2(vector) => {
uniform_buffer_data
.write_i32::<NativeEndian>(vector.x())
.unwrap();
uniform_buffer_data
.write_i32::<NativeEndian>(vector.y())
.unwrap();
}
UniformData::IVec3(values) => {
uniform_buffer_data
.write_i32::<NativeEndian>(values[0])
.unwrap();
uniform_buffer_data
.write_i32::<NativeEndian>(values[1])
.unwrap();
uniform_buffer_data
.write_i32::<NativeEndian>(values[2])
.unwrap();
}
UniformData::Int(value) => uniform_buffer_data
.write_i32::<NativeEndian>(value)
.unwrap(),
UniformData::Mat2(matrix) => {
uniform_buffer_data
.write_f32::<NativeEndian>(matrix.x())
.unwrap();
uniform_buffer_data
.write_f32::<NativeEndian>(matrix.y())
.unwrap();
uniform_buffer_data
.write_f32::<NativeEndian>(matrix.z())
.unwrap();
uniform_buffer_data
.write_f32::<NativeEndian>(matrix.w())
.unwrap();
}
UniformData::Mat4(matrix) => {
for column in &matrix {
uniform_buffer_data
.write_f32::<NativeEndian>(column.x())
.unwrap();
uniform_buffer_data
.write_f32::<NativeEndian>(column.y())
.unwrap();
uniform_buffer_data
.write_f32::<NativeEndian>(column.z())
.unwrap();
uniform_buffer_data
.write_f32::<NativeEndian>(column.w())
.unwrap();
}
}
UniformData::Vec2(vector) => {
uniform_buffer_data
.write_f32::<NativeEndian>(vector.x())
.unwrap();
uniform_buffer_data
.write_f32::<NativeEndian>(vector.y())
.unwrap();
}
UniformData::Vec3(array) => {
uniform_buffer_data
.write_f32::<NativeEndian>(array[0])
.unwrap();
uniform_buffer_data
.write_f32::<NativeEndian>(array[1])
.unwrap();
uniform_buffer_data
.write_f32::<NativeEndian>(array[2])
.unwrap();
}
UniformData::Vec4(vector) => {
uniform_buffer_data
.write_f32::<NativeEndian>(vector.x())
.unwrap();
uniform_buffer_data
.write_f32::<NativeEndian>(vector.y())
.unwrap();
uniform_buffer_data
.write_f32::<NativeEndian>(vector.z())
.unwrap();
uniform_buffer_data
.write_f32::<NativeEndian>(vector.w())
.unwrap();
}
UniformData::TextureUnit(index) => {
let texture = &render_state.textures[index as usize];
render_resource_assignments.set(
&bevy_uniform.name,
RenderResourceAssignment::Texture(texture.handle),
);
let sampler_resource = if let Some(sampler_resource) = *texture.sampler_resource.borrow() {
// NOTE: this assumes theres is only one sampler
// TODO: see if we need more than one sampler
sampler_resource
} else {
self.default_sampler
};
render_resource_assignments.set(
"uSampler",
RenderResourceAssignment::Sampler(sampler_resource),
);
uniform_buffer_ranges.push(None);
continue;
}
UniformData::ImageUnit(_) => panic!("image unit not currently supported"),
}
let end_index = uniform_buffer_data.len();
while uniform_buffer_data.len() % 256 != 0 {
uniform_buffer_data.push(0);
}
uniform_buffer_ranges.push(Some(start_index..end_index));
}
let buffer_resource = self
.render_context
.borrow()
.resources()
.create_buffer_with_data(
BufferInfo {
buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM,
..Default::default()
},
&uniform_buffer_data,
);
for ((bevy_uniform, _data), range) in render_state
.uniforms
.iter()
.zip(uniform_buffer_ranges.iter())
{
if let Some(range) = range {
render_resource_assignments.set(
&bevy_uniform.name,
RenderResourceAssignment::Buffer {
dynamic_index: None,
range: range.start as u64..range.end as u64,
resource: buffer_resource,
},
)
}
}
}
pub fn setup_vertex_buffers(
&self,
render_state: &RenderState<BevyPathfinderDevice>,
render_resource_assignments: &mut RenderResourceAssignments,
) {
for (i, vertex_buffer) in render_state for (i, vertex_buffer) in render_state
.vertex_array .vertex_array
.vertex_buffers .vertex_buffers
@ -78,14 +245,45 @@ impl<'a> BevyPathfinderDevice<'a> {
indices_resource = Some(index_buffer.handle.borrow().unwrap()); indices_resource = Some(index_buffer.handle.borrow().unwrap());
} }
} }
render_resource_assignments.set_vertex_buffer(get_vertex_buffer_name(i), resource, indices_resource); render_resource_assignments.set_vertex_buffer(
get_vertex_buffer_name(i),
resource,
indices_resource,
);
} }
}
// if let Some(ref index_buffer) = *render_state.vertex_array.index_buffer.borrow() { pub fn setup_bind_groups(
// let resource = index_buffer.handle.borrow().unwrap(); &self,
// pass.set_index_buffer(resource, 0); pipeline_descriptor: &PipelineDescriptor,
// } render_resource_assignments: &mut RenderResourceAssignments,
render_context.begin_pass( ) {
let bind_groups = &pipeline_descriptor.get_layout().unwrap().bind_groups;
let render_context = self.render_context.borrow();
let render_resources = render_context.resources();
for bind_group in bind_groups.iter() {
render_resource_assignments.update_render_resource_set_id(bind_group);
render_resources.setup_bind_groups(pipeline_descriptor, &render_resource_assignments);
}
}
pub fn draw<F>(&self, render_state: &RenderState<BevyPathfinderDevice>, draw_func: F) where F: Fn(&mut dyn RenderPass) {
let pass_descriptor = self.create_pass_descriptor(render_state);
self.setup_pipline_descriptor(
render_state,
&pass_descriptor,
&render_state.vertex_array.requested_descriptors.borrow(),
);
let mut render_resource_assignments = RenderResourceAssignments::default();
self.setup_uniforms(render_state, &mut render_resource_assignments);
self.setup_bind_groups(
&render_state.program.pipeline_descriptor.borrow(),
&mut render_resource_assignments,
);
self.setup_vertex_buffers(render_state, &mut render_resource_assignments);
println!("pass {:#?}", pass_descriptor);
println!("pipeline {:#?}", render_state.program.pipeline_descriptor);
self.render_context.borrow_mut().begin_pass(
&pass_descriptor, &pass_descriptor,
&render_resource_assignments, &render_resource_assignments,
&mut |pass| { &mut |pass| {
@ -105,6 +303,9 @@ impl<'a> BevyPathfinderDevice<'a> {
let pipeline_descriptor = render_state.program.pipeline_descriptor.borrow(); let pipeline_descriptor = render_state.program.pipeline_descriptor.borrow();
pass.set_render_resources(&pipeline_descriptor, &render_resource_assignments); pass.set_render_resources(&pipeline_descriptor, &render_resource_assignments);
println!("{:#?}", &render_resource_assignments);
pass.set_pipeline(render_state.program.pipeline_handle);
draw_func(pass);
}, },
) )
} }
@ -125,7 +326,7 @@ impl<'a> BevyPathfinderDevice<'a> {
// } // }
// }, // },
// ); // );
Some(TextureFormat::Bgra8UnormSrgb) Some(TextureFormat::Rgba16Float)
} }
pub fn setup_pipline_descriptor( pub fn setup_pipline_descriptor(
@ -143,15 +344,23 @@ impl<'a> BevyPathfinderDevice<'a> {
{ {
return; return;
} }
let mut pipeline_descriptor = render_state.program.pipeline_descriptor.borrow_mut(); let mut pipeline_descriptor = render_state.program.pipeline_descriptor.borrow_mut();
pipeline_descriptor.primitive_topology = match render_state.primitive {
pathfinder_gpu::Primitive::Triangles => PrimitiveTopology::TriangleList,
pathfinder_gpu::Primitive::Lines => PrimitiveTopology::LineList,
};
pipeline_descriptor.rasterization_state = Some(RasterizationStateDescriptor::default());
{ {
let mut layout = pipeline_descriptor.get_layout_mut().unwrap(); let mut layout = pipeline_descriptor.get_layout_mut().unwrap();
let mut i = 0; let mut i = 0;
let mut descriptors = Vec::with_capacity(requested_vertex_descriptors.len()); let mut descriptors = Vec::with_capacity(requested_vertex_descriptors.len());
loop { loop {
if let Some(descriptor) = requested_vertex_descriptors.get(&i) { if let Some(descriptor) = requested_vertex_descriptors.get(&i) {
descriptors.push(descriptor.clone()); let mut descriptor = descriptor.clone();
i += 1; descriptor.attributes.sort_by_key(|a| a.shader_location);
descriptors.push(descriptor);
i += 1;
} else { } else {
break; break;
} }
@ -247,6 +456,7 @@ impl<'a> BevyPathfinderDevice<'a> {
descriptor.stencil_front = stencil_descriptor.clone(); descriptor.stencil_front = stencil_descriptor.clone();
descriptor.stencil_back = stencil_descriptor; descriptor.stencil_back = stencil_descriptor;
} }
pipeline_descriptor.depth_stencil_state = Some(descriptor);
} }
self.render_context self.render_context
@ -269,9 +479,10 @@ impl<'a> BevyPathfinderDevice<'a> {
depth_texture = Some(self.main_depth_stencil_texture); depth_texture = Some(self.main_depth_stencil_texture);
self.main_color_texture self.main_color_texture
} }
RenderTarget::Framebuffer(framebuffer) => framebuffer.handle, RenderTarget::Framebuffer(framebuffer) => {println!("{:?} {:?}", framebuffer.texture_descriptor, framebuffer.handle); framebuffer.handle },
}; };
println!("color main {:?} {:?}", self.main_color_texture, color_texture);
let mut color_attachment = RenderPassColorAttachmentDescriptor { let mut color_attachment = RenderPassColorAttachmentDescriptor {
attachment: TextureAttachment::RenderResource(color_texture), attachment: TextureAttachment::RenderResource(color_texture),
clear_color: Color::WHITE, clear_color: Color::WHITE,
@ -317,114 +528,6 @@ impl<'a> BevyPathfinderDevice<'a> {
sample_count: 1, sample_count: 1,
} }
} }
fn create_uniform_buffer(&self, uniforms: &[(&BevyUniform, UniformData)]) -> UniformBuffer {
let (mut uniform_buffer_data, mut uniform_buffer_ranges) = (vec![], vec![]);
for &(_, uniform_data) in uniforms.iter() {
let start_index = uniform_buffer_data.len();
match uniform_data {
UniformData::Float(value) => uniform_buffer_data
.write_f32::<NativeEndian>(value)
.unwrap(),
UniformData::IVec2(vector) => {
uniform_buffer_data
.write_i32::<NativeEndian>(vector.x())
.unwrap();
uniform_buffer_data
.write_i32::<NativeEndian>(vector.y())
.unwrap();
}
UniformData::IVec3(values) => {
uniform_buffer_data
.write_i32::<NativeEndian>(values[0])
.unwrap();
uniform_buffer_data
.write_i32::<NativeEndian>(values[1])
.unwrap();
uniform_buffer_data
.write_i32::<NativeEndian>(values[2])
.unwrap();
}
UniformData::Int(value) => uniform_buffer_data
.write_i32::<NativeEndian>(value)
.unwrap(),
UniformData::Mat2(matrix) => {
uniform_buffer_data
.write_f32::<NativeEndian>(matrix.x())
.unwrap();
uniform_buffer_data
.write_f32::<NativeEndian>(matrix.y())
.unwrap();
uniform_buffer_data
.write_f32::<NativeEndian>(matrix.z())
.unwrap();
uniform_buffer_data
.write_f32::<NativeEndian>(matrix.w())
.unwrap();
}
UniformData::Mat4(matrix) => {
for column in &matrix {
uniform_buffer_data
.write_f32::<NativeEndian>(column.x())
.unwrap();
uniform_buffer_data
.write_f32::<NativeEndian>(column.y())
.unwrap();
uniform_buffer_data
.write_f32::<NativeEndian>(column.z())
.unwrap();
uniform_buffer_data
.write_f32::<NativeEndian>(column.w())
.unwrap();
}
}
UniformData::Vec2(vector) => {
uniform_buffer_data
.write_f32::<NativeEndian>(vector.x())
.unwrap();
uniform_buffer_data
.write_f32::<NativeEndian>(vector.y())
.unwrap();
}
UniformData::Vec3(array) => {
uniform_buffer_data
.write_f32::<NativeEndian>(array[0])
.unwrap();
uniform_buffer_data
.write_f32::<NativeEndian>(array[1])
.unwrap();
uniform_buffer_data
.write_f32::<NativeEndian>(array[2])
.unwrap();
}
UniformData::Vec4(vector) => {
uniform_buffer_data
.write_f32::<NativeEndian>(vector.x())
.unwrap();
uniform_buffer_data
.write_f32::<NativeEndian>(vector.y())
.unwrap();
uniform_buffer_data
.write_f32::<NativeEndian>(vector.z())
.unwrap();
uniform_buffer_data
.write_f32::<NativeEndian>(vector.w())
.unwrap();
}
UniformData::TextureUnit(_) | UniformData::ImageUnit(_) => {}
}
// TODO: this padding might not be necessary
let end_index = uniform_buffer_data.len();
while uniform_buffer_data.len() % 256 != 0 {
uniform_buffer_data.push(0);
}
uniform_buffer_ranges.push(start_index..end_index);
}
UniformBuffer {
data: uniform_buffer_data,
ranges: uniform_buffer_ranges,
}
}
} }
pub struct BevyTimerQuery {} pub struct BevyTimerQuery {}
@ -496,7 +599,7 @@ impl<'a> Device for BevyPathfinderDevice<'a> {
pathfinder_gpu::TextureFormat::RGBA16F => TextureFormat::Rgba16Float, pathfinder_gpu::TextureFormat::RGBA16F => TextureFormat::Rgba16Float,
pathfinder_gpu::TextureFormat::RGBA32F => TextureFormat::Rgba32Float, pathfinder_gpu::TextureFormat::RGBA32F => TextureFormat::Rgba32Float,
}, },
usage: TextureUsage::WRITE_ALL, // TODO: this might be overly safe usage: TextureUsage::WRITE_ALL | TextureUsage::SAMPLED, // TODO: this might be overly safe
}; };
BevyTexture { BevyTexture {
handle: self handle: self
@ -576,6 +679,7 @@ impl<'a> Device for BevyPathfinderDevice<'a> {
fragment: Some(fragment), fragment: Some(fragment),
}); });
descriptor.reflect_layout(&self.shaders.borrow(), false, None, None); descriptor.reflect_layout(&self.shaders.borrow(), false, None, None);
println!("orig {:?}", descriptor);
BevyProgram { BevyProgram {
pipeline_descriptor: RefCell::new(descriptor), pipeline_descriptor: RefCell::new(descriptor),
pipeline_handle: Handle::new(), pipeline_handle: Handle::new(),
@ -595,6 +699,7 @@ impl<'a> Device for BevyPathfinderDevice<'a> {
.find(|a| a.name == attribute_name) .find(|a| a.name == attribute_name)
.cloned(); .cloned();
if attribute.is_some() { if attribute.is_some() {
println!("pre {:?}", attribute);
return attribute.map(|a| BevyVertexAttr { return attribute.map(|a| BevyVertexAttr {
attr: RefCell::new(a), attr: RefCell::new(a),
}); });
@ -605,7 +710,7 @@ impl<'a> Device for BevyPathfinderDevice<'a> {
} }
fn get_uniform(&self, _program: &BevyProgram, name: &str) -> Self::Uniform { fn get_uniform(&self, _program: &BevyProgram, name: &str) -> Self::Uniform {
BevyUniform { BevyUniform {
name: name.to_string(), name: format!("u{}", name),
} }
} }
fn bind_buffer( fn bind_buffer(
@ -629,7 +734,7 @@ impl<'a> Device for BevyPathfinderDevice<'a> {
bevy_attr: &BevyVertexAttr, bevy_attr: &BevyVertexAttr,
descriptor: &VertexAttrDescriptor, descriptor: &VertexAttrDescriptor,
) { ) {
println!("configure"); // println!("configure: {:?} {:?}")
let format = match (descriptor.class, descriptor.attr_type, descriptor.size) { let format = match (descriptor.class, descriptor.attr_type, descriptor.size) {
(VertexAttrClass::Int, VertexAttrType::I8, 2) => VertexFormat::Char2, (VertexAttrClass::Int, VertexAttrType::I8, 2) => VertexFormat::Char2,
// (VertexAttrClass::Int, VertexAttrType::I8, 3) => VertexFormat::Char3, // (VertexAttrClass::Int, VertexAttrType::I8, 3) => VertexFormat::Char3,
@ -906,22 +1011,25 @@ impl<'a> Device for BevyPathfinderDevice<'a> {
fn end_commands(&self) { fn end_commands(&self) {
// NOTE: the Bevy Render Graph handles command buffer submission // NOTE: the Bevy Render Graph handles command buffer submission
} }
fn draw_arrays(&self, _index_count: u32, render_state: &RenderState<Self>) { fn draw_arrays(&self, index_count: u32, render_state: &RenderState<Self>) {
self.prepare_to_draw(render_state); self.draw(render_state, |pass| {
println!("draw_arrays"); pass.draw(0..index_count, 0..1);
});
} }
fn draw_elements(&self, _index_count: u32, render_state: &RenderState<Self>) { fn draw_elements(&self, index_count: u32, render_state: &RenderState<Self>) {
self.prepare_to_draw(render_state); self.draw(render_state, |pass| {
println!("draw_elements"); pass.draw_indexed( 0..index_count, 0, 0..1);
});
} }
fn draw_elements_instanced( fn draw_elements_instanced(
&self, &self,
_index_count: u32, index_count: u32,
_instance_count: u32, instance_count: u32,
render_state: &RenderState<Self>, render_state: &RenderState<Self>,
) { ) {
self.prepare_to_draw(render_state); self.draw(render_state, |pass| {
println!("draw_elements_instanced"); pass.draw_indexed( 0..index_count, 0, 0..instance_count);
});
} }
fn create_timer_query(&self) -> Self::TimerQuery { fn create_timer_query(&self) -> Self::TimerQuery {
// TODO: maybe not needed // TODO: maybe not needed
@ -1073,15 +1181,10 @@ impl ToBevyCompareFunction for pathfinder_gpu::StencilFunc {
} }
} }
struct UniformBuffer { pub const PATHFINDER_VERTEX_BUFFER_0: &'static str = "P0";
data: Vec<u8>, pub const PATHFINDER_VERTEX_BUFFER_1: &'static str = "P1";
ranges: Vec<Range<usize>>, pub const PATHFINDER_VERTEX_BUFFER_2: &'static str = "P2";
} pub const PATHFINDER_VERTEX_BUFFER_3: &'static str = "P3";
pub const PATHFINDER_VERTEX_BUFFER_0: &'static str = "P0";
pub const PATHFINDER_VERTEX_BUFFER_1: &'static str = "P1";
pub const PATHFINDER_VERTEX_BUFFER_2: &'static str = "P2";
pub const PATHFINDER_VERTEX_BUFFER_3: &'static str = "P3";
pub fn get_vertex_buffer_name(index: usize) -> &'static str { pub fn get_vertex_buffer_name(index: usize) -> &'static str {
match index { match index {
@ -1091,4 +1194,4 @@ pub fn get_vertex_buffer_name(index: usize) -> &'static str {
3 => PATHFINDER_VERTEX_BUFFER_3, 3 => PATHFINDER_VERTEX_BUFFER_3,
_ => panic!("encountered unknown vertex buffer index"), _ => panic!("encountered unknown vertex buffer index"),
} }
} }

View File

@ -1,12 +1,14 @@
use super::{LoadOp, StoreOp}; use super::{LoadOp, StoreOp};
use crate::{render_resource::RenderResource, Color}; use crate::{render_resource::RenderResource, Color};
#[derive(Debug, Clone)]
pub enum TextureAttachment { pub enum TextureAttachment {
RenderResource(RenderResource), RenderResource(RenderResource),
Name(String), Name(String),
Input(String), Input(String),
} }
#[derive(Debug, Clone)]
pub struct RenderPassColorAttachmentDescriptor { pub struct RenderPassColorAttachmentDescriptor {
/// The actual color attachment. /// The actual color attachment.
pub attachment: TextureAttachment, pub attachment: TextureAttachment,
@ -24,6 +26,7 @@ pub struct RenderPassColorAttachmentDescriptor {
pub clear_color: Color, pub clear_color: Color,
} }
#[derive(Debug, Clone)]
pub struct RenderPassDepthStencilAttachmentDescriptor { pub struct RenderPassDepthStencilAttachmentDescriptor {
pub attachment: TextureAttachment, pub attachment: TextureAttachment,
pub depth_load_op: LoadOp, pub depth_load_op: LoadOp,
@ -35,6 +38,7 @@ pub struct RenderPassDepthStencilAttachmentDescriptor {
} }
// A set of pipeline bindings and draw calls with color and depth outputs // A set of pipeline bindings and draw calls with color and depth outputs
#[derive(Debug, Clone)]
pub struct PassDescriptor { pub struct PassDescriptor {
pub color_attachments: Vec<RenderPassColorAttachmentDescriptor>, pub color_attachments: Vec<RenderPassColorAttachmentDescriptor>,
pub depth_stencil_attachment: Option<RenderPassDepthStencilAttachmentDescriptor>, pub depth_stencil_attachment: Option<RenderPassDepthStencilAttachmentDescriptor>,

View File

@ -13,6 +13,7 @@ pub trait RenderPass {
fn set_pipeline(&mut self, pipeline_handle: Handle<PipelineDescriptor>); fn set_pipeline(&mut self, pipeline_handle: Handle<PipelineDescriptor>);
fn set_viewport(&mut self, x: f32, y: f32, w: f32, h: f32, min_depth: f32, max_depth: f32); fn set_viewport(&mut self, x: f32, y: f32, w: f32, h: f32, min_depth: f32, max_depth: f32);
fn set_stencil_reference(&mut self, reference: u32); fn set_stencil_reference(&mut self, reference: u32);
fn draw(&mut self, vertices: Range<u32>, instances: Range<u32>);
fn draw_indexed(&mut self, indices: Range<u32>, base_vertex: i32, instances: Range<u32>); fn draw_indexed(&mut self, indices: Range<u32>, base_vertex: i32, instances: Range<u32>);
// TODO: try to somehow take into account the "set" pipeline instead of passing it in here // TODO: try to somehow take into account the "set" pipeline instead of passing it in here
fn set_render_resources( fn set_render_resources(

View File

@ -7,10 +7,7 @@ use super::{
BindType, PipelineLayout, VertexBufferDescriptors, BindType, PipelineLayout, VertexBufferDescriptors,
}; };
use crate::{ use crate::{
render_resource::{ render_resource::{RenderResourceAssignment, RenderResourceAssignments},
BufferInfo, RenderResourceAssignment, RenderResourceAssignments, ResourceInfo,
},
renderer::RenderResourceContext,
shader::{Shader, ShaderStages}, shader::{Shader, ShaderStages},
texture::TextureFormat, texture::TextureFormat,
}; };
@ -170,16 +167,17 @@ impl PipelineDescriptor {
layout.sync_vertex_buffer_descriptors(vertex_buffer_descriptors); layout.sync_vertex_buffer_descriptors(vertex_buffer_descriptors);
} }
if let Some(render_resource_assignments) = render_resource_assignments if let Some(render_resource_assignments) = render_resource_assignments {
{
// set binding uniforms to dynamic if render resource assignments use dynamic // set binding uniforms to dynamic if render resource assignments use dynamic
// TODO: this breaks down if different assignments have different "dynamic" status or if the dynamic status changes. // TODO: this breaks down if different assignments have different "dynamic" status or if the dynamic status changes.
// the fix would be to add "dynamic bindings" to the existing shader_def sets. this would ensure new pipelines are generated // the fix would be to add "dynamic bindings" to the existing shader_def sets. this would ensure new pipelines are generated
// for all permutations of dynamic/non-dynamic // for all permutations of dynamic/non-dynamic
for bind_group in layout.bind_groups.iter_mut() { for bind_group in layout.bind_groups.iter_mut() {
for binding in bind_group.bindings.iter_mut() { for binding in bind_group.bindings.iter_mut() {
if let Some(RenderResourceAssignment::Buffer { dynamic_index: Some(_), .. }) = if let Some(RenderResourceAssignment::Buffer {
render_resource_assignments.get(&binding.name) dynamic_index: Some(_),
..
}) = render_resource_assignments.get(&binding.name)
{ {
if let BindType::Uniform { if let BindType::Uniform {
ref mut dynamic, .. ref mut dynamic, ..

View File

@ -1,7 +1,6 @@
use super::{state_descriptors::PrimitiveTopology, PipelineDescriptor, VertexBufferDescriptors}; use super::{state_descriptors::PrimitiveTopology, PipelineDescriptor, VertexBufferDescriptors};
use crate::{ use crate::{
render_resource::{RenderResourceAssignments, RenderResourceAssignmentsId}, render_resource::{RenderResourceAssignments, RenderResourceAssignmentsId},
renderer::{RenderResourceContext, RenderResources},
shader::{Shader, ShaderSource}, shader::{Shader, ShaderSource},
Renderable, Renderable,
}; };

View File

@ -3,7 +3,7 @@ use crate::{
render_graph::{CommandQueue, Node, ResourceSlots, SystemNode}, render_graph::{CommandQueue, Node, ResourceSlots, SystemNode},
render_resource::{ render_resource::{
BufferInfo, BufferUsage, RenderResource, RenderResourceAssignment, BufferInfo, BufferUsage, RenderResource, RenderResourceAssignment,
RenderResourceAssignments, RenderResourceAssignmentsId, ResourceInfo, RenderResourceAssignments, RenderResourceAssignmentsId,
}, },
renderer::{RenderContext, RenderResourceContext, RenderResources}, renderer::{RenderContext, RenderResourceContext, RenderResources},
shader::{AsUniforms, FieldBindType}, shader::{AsUniforms, FieldBindType},

View File

@ -14,6 +14,22 @@ pub struct SamplerDescriptor {
pub compare_function: CompareFunction, pub compare_function: CompareFunction,
} }
impl Default for SamplerDescriptor {
fn default() -> Self {
SamplerDescriptor {
address_mode_u: AddressMode::ClampToEdge,
address_mode_v: AddressMode::ClampToEdge,
address_mode_w: AddressMode::ClampToEdge,
mag_filter: FilterMode::Nearest,
min_filter: FilterMode::Linear,
mipmap_filter: FilterMode::Nearest,
lod_min_clamp: -100.0,
lod_max_clamp: 100.0,
compare_function: CompareFunction::Always,
}
}
}
impl From<&Texture> for SamplerDescriptor { impl From<&Texture> for SamplerDescriptor {
fn from(_texture: &Texture) -> Self { fn from(_texture: &Texture) -> Self {
SamplerDescriptor { SamplerDescriptor {

View File

@ -46,6 +46,11 @@ impl<'a> RenderPass for WgpuRenderPass<'a> {
.draw_indexed(indices, base_vertex, instances); .draw_indexed(indices, base_vertex, instances);
} }
fn draw(&mut self, vertices: Range<u32>, instances: Range<u32>) {
self.render_pass
.draw(vertices, instances);
}
fn set_render_resources( fn set_render_resources(
&mut self, &mut self,
pipeline_descriptor: &PipelineDescriptor, pipeline_descriptor: &PipelineDescriptor,

View File

@ -5,10 +5,10 @@
uniform vec4 uTileSize[1]; uniform vec4 uTileSize[1];
uniform vec4 uFramebufferSize[1]; uniform vec4 uFramebufferSize[1];
layout(location = 5) in uint aTileIndex; layout(location = 5) in uint aTileIndex;
layout(location = 1) in uint aFromPx; layout(location = 3) in uint aFromPx;
layout(location = 3) in vec2 aFromSubpx; layout(location = 1) in vec2 aFromSubpx;
layout(location = 2) in uint aToPx; layout(location = 4) in uint aToPx;
layout(location = 4) in vec2 aToSubpx; layout(location = 2) in vec2 aToSubpx;
layout(location = 0) in uvec2 aTessCoord; layout(location = 0) in uvec2 aTessCoord;
out vec2 vFrom; out vec2 vFrom;
out vec2 vTo; out vec2 vTo;

View File

@ -5,10 +5,10 @@
uniform vec4 uTileSize[1]; uniform vec4 uTileSize[1];
uniform vec4 uFramebufferSize[1]; uniform vec4 uFramebufferSize[1];
layout(location = 5) in uint aTileIndex; layout(location = 5) in uint aTileIndex;
layout(location = 1) in uint aFromPx; layout(location = 3) in uint aFromPx;
layout(location = 3) in vec2 aFromSubpx; layout(location = 1) in vec2 aFromSubpx;
layout(location = 2) in uint aToPx; layout(location = 4) in uint aToPx;
layout(location = 4) in vec2 aToSubpx; layout(location = 2) in vec2 aToSubpx;
layout(location = 0) in uvec2 aTessCoord; layout(location = 0) in uvec2 aTessCoord;
layout(location = 0) out vec2 vFrom; layout(location = 0) out vec2 vFrom;
layout(location = 1) out vec2 vTo; layout(location = 1) out vec2 vTo;

View File

@ -26,10 +26,10 @@ struct main0_out
struct main0_in struct main0_in
{ {
uint2 aTessCoord [[attribute(0)]]; uint2 aTessCoord [[attribute(0)]];
uint aFromPx [[attribute(1)]]; float2 aFromSubpx [[attribute(1)]];
uint aToPx [[attribute(2)]]; float2 aToSubpx [[attribute(2)]];
float2 aFromSubpx [[attribute(3)]]; uint aFromPx [[attribute(3)]];
float2 aToSubpx [[attribute(4)]]; uint aToPx [[attribute(4)]];
uint aTileIndex [[attribute(5)]]; uint aTileIndex [[attribute(5)]];
}; };

Binary file not shown.

View File

@ -24,10 +24,10 @@ layout(std140, set=0, binding=1) uniform uTileSize {
}; };
in uvec2 aTessCoord; in uvec2 aTessCoord;
in uint aFromPx;
in uint aToPx;
in vec2 aFromSubpx; in vec2 aFromSubpx;
in vec2 aToSubpx; in vec2 aToSubpx;
in uint aFromPx;
in uint aToPx;
in uint aTileIndex; in uint aTileIndex;
out vec2 vFrom; out vec2 vFrom;