wasm32: non-spirv shader specialization (#843)
wasm32: non-spirv shader specialization
This commit is contained in:
		
							parent
							
								
									18195bfa91
								
							
						
					
					
						commit
						515d750004
					
				@ -70,6 +70,7 @@ pub struct PipelineCompiler {
 | 
				
			|||||||
impl PipelineCompiler {
 | 
					impl PipelineCompiler {
 | 
				
			||||||
    fn compile_shader(
 | 
					    fn compile_shader(
 | 
				
			||||||
        &mut self,
 | 
					        &mut self,
 | 
				
			||||||
 | 
					        render_resource_context: &dyn RenderResourceContext,
 | 
				
			||||||
        shaders: &mut Assets<Shader>,
 | 
					        shaders: &mut Assets<Shader>,
 | 
				
			||||||
        shader_handle: &Handle<Shader>,
 | 
					        shader_handle: &Handle<Shader>,
 | 
				
			||||||
        shader_specialization: &ShaderSpecialization,
 | 
					        shader_specialization: &ShaderSpecialization,
 | 
				
			||||||
@ -102,7 +103,8 @@ impl PipelineCompiler {
 | 
				
			|||||||
                .iter()
 | 
					                .iter()
 | 
				
			||||||
                .cloned()
 | 
					                .cloned()
 | 
				
			||||||
                .collect::<Vec<String>>();
 | 
					                .collect::<Vec<String>>();
 | 
				
			||||||
            let compiled_shader = shader.get_spirv_shader(Some(&shader_def_vec));
 | 
					            let compiled_shader =
 | 
				
			||||||
 | 
					                render_resource_context.get_specialized_shader(shader, Some(&shader_def_vec));
 | 
				
			||||||
            let specialized_handle = shaders.add(compiled_shader);
 | 
					            let specialized_handle = shaders.add(compiled_shader);
 | 
				
			||||||
            let weak_specialized_handle = specialized_handle.clone_weak();
 | 
					            let weak_specialized_handle = specialized_handle.clone_weak();
 | 
				
			||||||
            specialized_shaders.push(SpecializedShader {
 | 
					            specialized_shaders.push(SpecializedShader {
 | 
				
			||||||
@ -141,6 +143,7 @@ impl PipelineCompiler {
 | 
				
			|||||||
        let source_descriptor = pipelines.get(source_pipeline).unwrap();
 | 
					        let source_descriptor = pipelines.get(source_pipeline).unwrap();
 | 
				
			||||||
        let mut specialized_descriptor = source_descriptor.clone();
 | 
					        let mut specialized_descriptor = source_descriptor.clone();
 | 
				
			||||||
        specialized_descriptor.shader_stages.vertex = self.compile_shader(
 | 
					        specialized_descriptor.shader_stages.vertex = self.compile_shader(
 | 
				
			||||||
 | 
					            render_resource_context,
 | 
				
			||||||
            shaders,
 | 
					            shaders,
 | 
				
			||||||
            &specialized_descriptor.shader_stages.vertex,
 | 
					            &specialized_descriptor.shader_stages.vertex,
 | 
				
			||||||
            &pipeline_specialization.shader_specialization,
 | 
					            &pipeline_specialization.shader_specialization,
 | 
				
			||||||
@ -151,6 +154,7 @@ impl PipelineCompiler {
 | 
				
			|||||||
            .as_ref()
 | 
					            .as_ref()
 | 
				
			||||||
            .map(|fragment| {
 | 
					            .map(|fragment| {
 | 
				
			||||||
                self.compile_shader(
 | 
					                self.compile_shader(
 | 
				
			||||||
 | 
					                    render_resource_context,
 | 
				
			||||||
                    shaders,
 | 
					                    shaders,
 | 
				
			||||||
                    fragment,
 | 
					                    fragment,
 | 
				
			||||||
                    &pipeline_specialization.shader_specialization,
 | 
					                    &pipeline_specialization.shader_specialization,
 | 
				
			||||||
 | 
				
			|||||||
@ -148,4 +148,8 @@ impl RenderResourceContext for HeadlessRenderResourceContext {
 | 
				
			|||||||
    fn get_aligned_texture_size(&self, size: usize) -> usize {
 | 
					    fn get_aligned_texture_size(&self, size: usize) -> usize {
 | 
				
			||||||
        size
 | 
					        size
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn get_specialized_shader(&self, shader: &Shader, _macros: Option<&[String]>) -> Shader {
 | 
				
			||||||
 | 
					        shader.clone()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -29,6 +29,7 @@ pub trait RenderResourceContext: Downcast + Send + Sync + 'static {
 | 
				
			|||||||
    fn create_buffer_with_data(&self, buffer_info: BufferInfo, data: &[u8]) -> BufferId;
 | 
					    fn create_buffer_with_data(&self, buffer_info: BufferInfo, data: &[u8]) -> BufferId;
 | 
				
			||||||
    fn create_shader_module(&self, shader_handle: &Handle<Shader>, shaders: &Assets<Shader>);
 | 
					    fn create_shader_module(&self, shader_handle: &Handle<Shader>, shaders: &Assets<Shader>);
 | 
				
			||||||
    fn create_shader_module_from_source(&self, shader_handle: &Handle<Shader>, shader: &Shader);
 | 
					    fn create_shader_module_from_source(&self, shader_handle: &Handle<Shader>, shader: &Shader);
 | 
				
			||||||
 | 
					    fn get_specialized_shader(&self, shader: &Shader, macros: Option<&[String]>) -> Shader;
 | 
				
			||||||
    fn remove_buffer(&self, buffer: BufferId);
 | 
					    fn remove_buffer(&self, buffer: BufferId);
 | 
				
			||||||
    fn remove_texture(&self, texture: TextureId);
 | 
					    fn remove_texture(&self, texture: TextureId);
 | 
				
			||||||
    fn remove_sampler(&self, sampler: SamplerId);
 | 
					    fn remove_sampler(&self, sampler: SamplerId);
 | 
				
			||||||
 | 
				
			|||||||
@ -5,12 +5,10 @@ mod shader_defs;
 | 
				
			|||||||
#[cfg(not(target_arch = "wasm32"))]
 | 
					#[cfg(not(target_arch = "wasm32"))]
 | 
				
			||||||
mod shader_reflect;
 | 
					mod shader_reflect;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[cfg(target_arch = "wasm32")]
 | 
					 | 
				
			||||||
#[path = "shader_reflect_wasm.rs"]
 | 
					 | 
				
			||||||
mod shader_reflect;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub use shader::*;
 | 
					pub use shader::*;
 | 
				
			||||||
pub use shader_defs::*;
 | 
					pub use shader_defs::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[cfg(not(target_arch = "wasm32"))]
 | 
				
			||||||
pub use shader_reflect::*;
 | 
					pub use shader_reflect::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::pipeline::{BindGroupDescriptor, VertexBufferDescriptor};
 | 
					use crate::pipeline::{BindGroupDescriptor, VertexBufferDescriptor};
 | 
				
			||||||
 | 
				
			|||||||
@ -23,7 +23,7 @@ impl Into<bevy_glsl_to_spirv::ShaderType> for ShaderStage {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[cfg(all(not(target_os = "ios"), not(target_arch = "wasm32")))]
 | 
					#[cfg(all(not(target_os = "ios"), not(target_arch = "wasm32")))]
 | 
				
			||||||
fn glsl_to_spirv(
 | 
					pub fn glsl_to_spirv(
 | 
				
			||||||
    glsl_source: &str,
 | 
					    glsl_source: &str,
 | 
				
			||||||
    stage: ShaderStage,
 | 
					    stage: ShaderStage,
 | 
				
			||||||
    shader_defs: Option<&[String]>,
 | 
					    shader_defs: Option<&[String]>,
 | 
				
			||||||
@ -43,7 +43,7 @@ impl Into<shaderc::ShaderKind> for ShaderStage {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[cfg(target_os = "ios")]
 | 
					#[cfg(target_os = "ios")]
 | 
				
			||||||
fn glsl_to_spirv(
 | 
					pub fn glsl_to_spirv(
 | 
				
			||||||
    glsl_source: &str,
 | 
					    glsl_source: &str,
 | 
				
			||||||
    stage: ShaderStage,
 | 
					    stage: ShaderStage,
 | 
				
			||||||
    shader_defs: Option<&[String]>,
 | 
					    shader_defs: Option<&[String]>,
 | 
				
			||||||
@ -121,17 +121,15 @@ impl Shader {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[allow(unused_variables)]
 | 
					    #[cfg(not(target_arch = "wasm32"))]
 | 
				
			||||||
    pub fn get_spirv_shader(&self, macros: Option<&[String]>) -> Shader {
 | 
					    pub fn get_spirv_shader(&self, macros: Option<&[String]>) -> Shader {
 | 
				
			||||||
        Shader {
 | 
					        Shader {
 | 
				
			||||||
            #[cfg(not(target_arch = "wasm32"))]
 | 
					 | 
				
			||||||
            source: ShaderSource::Spirv(self.get_spirv(macros)),
 | 
					            source: ShaderSource::Spirv(self.get_spirv(macros)),
 | 
				
			||||||
            #[cfg(target_arch = "wasm32")]
 | 
					 | 
				
			||||||
            source: self.source.clone(),
 | 
					 | 
				
			||||||
            stage: self.stage,
 | 
					            stage: self.stage,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[cfg(not(target_arch = "wasm32"))]
 | 
				
			||||||
    pub fn reflect_layout(&self, enforce_bevy_conventions: bool) -> Option<ShaderLayout> {
 | 
					    pub fn reflect_layout(&self, enforce_bevy_conventions: bool) -> Option<ShaderLayout> {
 | 
				
			||||||
        if let ShaderSource::Spirv(ref spirv) = self.source {
 | 
					        if let ShaderSource::Spirv(ref spirv) = self.source {
 | 
				
			||||||
            Some(ShaderLayout::from_spirv(
 | 
					            Some(ShaderLayout::from_spirv(
 | 
				
			||||||
@ -142,6 +140,11 @@ impl Shader {
 | 
				
			|||||||
            panic!("Cannot reflect layout of non-SpirV shader. Try compiling this shader to SpirV first using self.get_spirv_shader()");
 | 
					            panic!("Cannot reflect layout of non-SpirV shader. Try compiling this shader to SpirV first using self.get_spirv_shader()");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[cfg(target_arch = "wasm32")]
 | 
				
			||||||
 | 
					    pub fn reflect_layout(&self, _enforce_bevy_conventions: bool) -> Option<ShaderLayout> {
 | 
				
			||||||
 | 
					        panic!("Cannot reflect layout on wasm32");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// All stages in a shader program
 | 
					/// All stages in a shader program
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +0,0 @@
 | 
				
			|||||||
use crate::shader::ShaderLayout;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl ShaderLayout {
 | 
					 | 
				
			||||||
    pub fn from_spirv(_spirv_data: &[u32], _bevy_conventions: bool) -> ShaderLayout {
 | 
					 | 
				
			||||||
        panic!("reflecting shader layout from spirv data is not available");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -12,7 +12,7 @@ use bevy_render::{
 | 
				
			|||||||
        BindGroup, BufferId, BufferInfo, RenderResourceBinding, RenderResourceContext,
 | 
					        BindGroup, BufferId, BufferInfo, RenderResourceBinding, RenderResourceContext,
 | 
				
			||||||
        RenderResourceId, SamplerId, TextureId,
 | 
					        RenderResourceId, SamplerId, TextureId,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    shader::Shader,
 | 
					    shader::{glsl_to_spirv, Shader, ShaderSource},
 | 
				
			||||||
    texture::{Extent3d, SamplerDescriptor, TextureDescriptor},
 | 
					    texture::{Extent3d, SamplerDescriptor, TextureDescriptor},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use bevy_utils::tracing::trace;
 | 
					use bevy_utils::tracing::trace;
 | 
				
			||||||
@ -569,4 +569,15 @@ impl RenderResourceContext for WgpuRenderResourceContext {
 | 
				
			|||||||
            size
 | 
					            size
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn get_specialized_shader(&self, shader: &Shader, macros: Option<&[String]>) -> Shader {
 | 
				
			||||||
 | 
					        let spirv_data = match shader.source {
 | 
				
			||||||
 | 
					            ShaderSource::Spirv(ref bytes) => bytes.clone(),
 | 
				
			||||||
 | 
					            ShaderSource::Glsl(ref source) => glsl_to_spirv(&source, shader.stage, macros),
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        Shader {
 | 
				
			||||||
 | 
					            source: ShaderSource::Spirv(spirv_data),
 | 
				
			||||||
 | 
					            ..*shader
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user