Skip to content

Commit

Permalink
Resource manager revamp.
Browse files Browse the repository at this point in the history
  • Loading branch information
facundo-villa committed Aug 18, 2023
1 parent 9e89196 commit ac7f0c3
Show file tree
Hide file tree
Showing 13 changed files with 329 additions and 181 deletions.
7 changes: 5 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
**/target
**/assets
**/resources
*.db
*.db.*
*.db.*
.byte
.byte-engine
.byte-editor
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion src/camera.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{Vec3f, orchestrator::{Property, EntityHandle, self, Component, Entity}};
use crate::{Vec3f, orchestrator::{Property, self, Component, Entity}};

#[derive(component_derive::Component)]
/// Camera struct
Expand Down
2 changes: 1 addition & 1 deletion src/file_tracker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub struct FileTracker {

impl FileTracker {
pub fn new(orchestrator: orchestrator::OrchestratorReference) -> FileTracker {
let db = polodb_core::Database::open_file("files.db").unwrap();
let db = polodb_core::Database::open_file(".byte-editor/files.db").unwrap();

let (tx, rx) = std::sync::mpsc::channel();

Expand Down
37 changes: 33 additions & 4 deletions src/render_domain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ pub struct VisibilityWorldRenderDomain {
mesh_resources: HashMap<&'static str, u32>,

/// Maps resource ids to shaders
shaders: std::collections::HashMap<u64, render_system::ShaderHandle>,
/// The hash and the shader handle are stored to determine if the shader has changed
shaders: std::collections::HashMap<u64, (u64, render_system::ShaderHandle)>,
}

impl VisibilityWorldRenderDomain {
Expand Down Expand Up @@ -223,25 +224,53 @@ impl VisibilityWorldRenderDomain {
let mut resource_manager = resource_manager.get_mut();
let resource_manager: &mut resource_manager::ResourceManager = resource_manager.downcast_mut().unwrap();

let resource_request = resource_manager.get_resource_info(mesh.resource_id);
let resource_request = resource_manager.request_resource(mesh.resource_id);

let resource_request = if let Some(resource_info) = resource_request { resource_info } else { return; };

let vertex_buffer = render_system.get_mut_buffer_slice(None, self.vertices_buffer);
let index_buffer = render_system.get_mut_buffer_slice(None, self.indices_buffer);

let resource = resource_manager.load_resource_into_buffer(&resource_request, vertex_buffer, index_buffer); // TODO: add offset
let resource = resource_manager.load_resource(&resource_request, None, None);

self.mesh_resources.insert(mesh.resource_id, self.index_count);

let resource_info = resource_request.resource;

self.index_count += resource_info.index_count;

let material = resource_manager.get("cube.json");
let material = resource_manager.get("cube");

let material = if let Some(s) = material { s } else { return; };

for resource in material.0.get_array("resources").unwrap() {
let resource = resource.as_document().unwrap();
let class = resource.get_str("class").unwrap();

match class {
"Shader" => {
let shader_name = resource.get_str("name").unwrap();
let hash = resource.get_i64("hash").unwrap() as u64;
let resource_id = resource.get_i64("id").unwrap() as u64;

if let Some((old_hash, old_shader)) = self.shaders.get(&resource_id) {
if *old_hash == hash { continue; }
}

let offset = resource.get_i64("offset").unwrap() as usize;
let size = resource.get_i64("size").unwrap() as usize;

let new_shader = render_system.add_shader(crate::render_system::ShaderSourceType::SPIRV, &material.1[offset..(offset + size)]);

self.shaders.insert(resource_id, (hash, new_shader));
}
"Material" => {
// TODO: update pipeline
}
_ => {}
}
}

let result = resource_manager.get("cube");

let result = if let Some(s) = result { s } else { return; };
Expand Down
6 changes: 6 additions & 0 deletions src/render_system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ pub fn select_by_score<T>(values: &[T], score: impl Fn(&T) -> i64) -> Option<&T>
best_value
}

/// Handle to a Pipeline Layout
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub struct PipelineLayoutHandle(u32);

Expand Down Expand Up @@ -59,18 +60,23 @@ struct Texture {
role: String,
}

/// Handle to a Sampler
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub struct SamplerHandle(u32);

struct Sampler {
sampler: render_backend::Sampler,
}

/// Possible types of a shader source
pub enum ShaderSourceType {
/// GLSL code string
GLSL,
/// SPIR-V binary
SPIRV,
}

/// Primitive GPU/shader data types.
#[derive(Hash, Clone, Copy)]
pub enum DataTypes {
Float,
Expand Down
4 changes: 2 additions & 2 deletions src/resource_manager/image_resource_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ impl ResourceHandler for ImageResourceHandler {
}
}

fn process(&self, bytes: Vec<u8>) -> Result<(Document, Vec<u8>), String> {
fn process(&self, bytes: Vec<u8>) -> Result<Vec<(Document, Vec<u8>)>, String> {
let mut decoder = png::Decoder::new(bytes.as_slice());
decoder.set_transformations(png::Transformations::EXPAND);
let mut reader = decoder.read_info().unwrap();
Expand Down Expand Up @@ -59,7 +59,7 @@ impl ResourceHandler for ImageResourceHandler {
"compression": "BC7",
};

Ok((resource_document, intel_tex_2::bc7::compress_blocks(&settings, &rgba_surface)))
Ok(vec![(resource_document, intel_tex_2::bc7::compress_blocks(&settings, &rgba_surface))])
}
}

Expand Down
94 changes: 51 additions & 43 deletions src/resource_manager/material_resource_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,77 +26,85 @@ impl ResourceHandler for MaterialResourcerHandler {
}
}

fn process(&self, bytes: Vec<u8>) -> Result<(Document, Vec<u8>), String> {
fn process(&self, bytes: Vec<u8>) -> Result<Vec<(Document, Vec<u8>)>, String> {
let material_json = json::parse(std::str::from_utf8(&bytes).unwrap()).unwrap();

let t = material_json["type"].as_str().unwrap();
let vertex = material_json["vertex"].as_str().unwrap();
let fragment = material_json["fragment"].as_str().unwrap();

let vertex_path = "resources/".to_string() + vertex;
let fragment_path = "resources/".to_string() + fragment;
fn treat_shader(path: &str, t: &str) -> (Document, Vec<u8>) {
let path = "resources/".to_string() + path;
let shader_code = std::fs::read_to_string(path).unwrap();
let shader = beshader_compiler::parse(beshader_compiler::tokenize(&shader_code));

let vertex_shader_code = std::fs::read_to_string(vertex_path).unwrap();
let fragment_shader_code = std::fs::read_to_string(fragment_path).unwrap();
let mut shader_spec = json::object! { glsl: { version: "450" } };

let vertex_shader = beshader_compiler::parse(beshader_compiler::tokenize(&vertex_shader_code));
let fragment_shader = beshader_compiler::parse(beshader_compiler::tokenize(&fragment_shader_code));
let common = crate::rendering::common_shader_generator::CommonShaderGenerator::new();

let mut shader_spec = json::object! { glsl: { version: "450" } };
let c = common.process();

let common = crate::rendering::common_shader_generator::CommonShaderGenerator::new();
shader_spec["root"][c.0] = c.1;

let c = common.process();
let visibility = crate::rendering::visibility_shader_generator::VisibilityShaderGenerator::new();

shader_spec["root"][c.0] = c.1;
let v = visibility.process();

let visibility = crate::rendering::visibility_shader_generator::VisibilityShaderGenerator::new();
shader_spec["root"][c.0][v.0] = v.1;

let v = visibility.process();
let shader_generator = shader_generator::ShaderGenerator::new();

shader_spec["root"][c.0][v.0] = v.1;
let glsl = shader_generator.generate(&shader_spec, &json::object!{ path: "Common.Visibility", type: t });

let shader_generator = shader_generator::ShaderGenerator::new();
let compiler = shaderc::Compiler::new().unwrap();
let mut options = shaderc::CompileOptions::new().unwrap();

let glsl = shader_generator.generate(&shader_spec, &json::object!{ path: "Common.Visibility", type: "fragment" });
options.set_optimization_level(shaderc::OptimizationLevel::Performance);
options.set_target_env(shaderc::TargetEnv::Vulkan, shaderc::EnvVersion::Vulkan1_2 as u32);
options.set_generate_debug_info();
options.set_target_spirv(shaderc::SpirvVersion::V1_5);
options.set_invert_y(true);

let compiler = shaderc::Compiler::new().unwrap();
let mut options = shaderc::CompileOptions::new().unwrap();
let binary = compiler.compile_into_spirv(&glsl, shaderc::ShaderKind::InferFromSource, "shader_name", "main", Some(&options));

options.set_optimization_level(shaderc::OptimizationLevel::Performance);
options.set_target_env(shaderc::TargetEnv::Vulkan, shaderc::EnvVersion::Vulkan1_2 as u32);
options.set_generate_debug_info();
options.set_target_spirv(shaderc::SpirvVersion::V1_5);
options.set_invert_y(true);
let compilation_artifact = match binary { Ok(binary) => { binary } Err(error) => { panic!(); } };

let binary = compiler.compile_into_spirv(&glsl, shaderc::ShaderKind::InferFromSource, "shader_name", "main", Some(&options));
if compilation_artifact.get_num_warnings() > 0 {
println!("Shader warnings: {}", compilation_artifact.get_warning_messages());
}

let shader_stage: String = glsl.find("#pragma shader_stage(").map(|index| glsl[index + 21..].split(')').next().unwrap().to_string()).unwrap_or(String::from(""));
let result_shader_bytes = compilation_artifact.as_binary_u8();

let shader_stage = match shader_stage.as_str() {
"vertex" => { crate::render_backend::ShaderTypes::Vertex },
"fragment" => { crate::render_backend::ShaderTypes::Fragment },
_ => { crate::render_backend::ShaderTypes::Vertex },
};

let compilation_artifact = match binary { Ok(binary) => { binary } Err(error) => { return Err(error.to_string()); } };
let mut hasher = DefaultHasher::new();

if compilation_artifact.get_num_warnings() > 0 {
println!("Shader warnings: {}", compilation_artifact.get_warning_messages());
}
std::hash::Hash::hash(&result_shader_bytes, &mut hasher);

let result_shader_bytes = compilation_artifact.as_binary_u8();
let hash = hasher.finish() as i64;

let mut hasher = DefaultHasher::new();
let resource = polodb_core::bson::doc!{
"class": "Shader",
"hash": hash
};

std::hash::Hash::hash(&result_shader_bytes, &mut hasher);

let hash = hasher.finish() as i64;
(resource, Vec::from(result_shader_bytes))
}

let resource = polodb_core::bson::doc!{
"hash": hash
let a = treat_shader(vertex, "vertex");
let b = treat_shader(fragment, "fragment");

let material_resource_document = polodb_core::bson::doc!{
"class": "Material",
"required_resources": [
{
"path": vertex,
},
{
"path": fragment,
}
],
"resource": {}
};

Ok((resource, Vec::from(result_shader_bytes)))
Ok(vec![a, b])
}
}
4 changes: 2 additions & 2 deletions src/resource_manager/mesh_resource_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ impl ResourceHandler for MeshResourceHandler {
}
}

fn process(&self, bytes: Vec<u8>) -> Result<(Document, Vec<u8>), String> {
fn process(&self, bytes: Vec<u8>) -> Result<Vec<(Document, Vec<u8>)>, String> {
let (gltf, buffers, _) = gltf::import_slice(bytes.as_slice()).unwrap();

let mut buf: Vec<u8> = Vec::with_capacity(4096 * 1024 * 3);
Expand Down Expand Up @@ -101,7 +101,7 @@ impl ResourceHandler for MeshResourceHandler {

let serialized_mesh = mesh.serialize(polodb_core::bson::Serializer::new()).unwrap();

Ok((serialized_mesh.as_document().unwrap().clone(), buf))
Ok(vec![(serialized_mesh.as_document().unwrap().clone(), buf)])
}
}

Expand Down
Loading

0 comments on commit ac7f0c3

Please sign in to comment.