reflect: allow validation of shaders without reflecting against semantics
This commit is contained in:
parent
31ece05246
commit
bac09ad2a3
|
@ -32,6 +32,9 @@ pub trait CompileShader<T: OutputTarget> {
|
|||
type Context;
|
||||
|
||||
/// Consume the object and return the compiled output of the shader.
|
||||
///
|
||||
/// The shader should either be reflected or validated as
|
||||
/// [ReflectShader] before being compiled, or the results may not be valid.
|
||||
fn compile(
|
||||
self,
|
||||
options: Self::Options,
|
||||
|
@ -139,6 +142,10 @@ where
|
|||
) -> Result<ShaderReflection, ShaderReflectError> {
|
||||
self.backend.reflect(pass_number, semantics)
|
||||
}
|
||||
|
||||
fn validate(&mut self) -> Result<(), ShaderReflectError> {
|
||||
self.backend.validate()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ReflectShader + ?Sized> ReflectShader for Box<T> {
|
||||
|
@ -149,6 +156,10 @@ impl<T: ReflectShader + ?Sized> ReflectShader for Box<T> {
|
|||
) -> Result<ShaderReflection, ShaderReflectError> {
|
||||
(**self).reflect(pass_number, semantics)
|
||||
}
|
||||
|
||||
fn validate(&mut self) -> Result<(), ShaderReflectError> {
|
||||
(**self).validate()
|
||||
}
|
||||
}
|
||||
|
||||
impl<O, T> CompileShader<T> for Box<O>
|
||||
|
|
|
@ -72,6 +72,10 @@ impl ReflectShader for WriteSpirV {
|
|||
) -> Result<ShaderReflection, ShaderReflectError> {
|
||||
self.reflect.reflect(pass_number, semantics)
|
||||
}
|
||||
|
||||
fn validate(&mut self) -> Result<(), ShaderReflectError> {
|
||||
self.reflect.validate()
|
||||
}
|
||||
}
|
||||
|
||||
impl CompileShader<SPIRV> for WriteSpirV {
|
||||
|
|
|
@ -160,7 +160,7 @@ impl<T> CrossReflect<T>
|
|||
where
|
||||
T: spirv_cross2::compile::CompilableTarget,
|
||||
{
|
||||
fn validate(
|
||||
fn validate_semantics(
|
||||
&self,
|
||||
vertex_res: &AllResources,
|
||||
fragment_res: &AllResources,
|
||||
|
@ -714,7 +714,7 @@ where
|
|||
) -> Result<ShaderReflection, ShaderReflectError> {
|
||||
let vertex_res = self.vertex.shader_resources()?.all_resources()?;
|
||||
let fragment_res = self.fragment.shader_resources()?.all_resources()?;
|
||||
self.validate(&vertex_res, &fragment_res)?;
|
||||
self.validate_semantics(&vertex_res, &fragment_res)?;
|
||||
|
||||
let vertex_ubo = vertex_res.uniform_buffers.first();
|
||||
let fragment_ubo = fragment_res.uniform_buffers.first();
|
||||
|
@ -797,6 +797,23 @@ where
|
|||
meta,
|
||||
})
|
||||
}
|
||||
|
||||
fn validate(&mut self) -> Result<(), ShaderReflectError> {
|
||||
let vertex_res = self.vertex.shader_resources()?.all_resources()?;
|
||||
let fragment_res = self.fragment.shader_resources()?.all_resources()?;
|
||||
self.validate_semantics(&vertex_res, &fragment_res)?;
|
||||
let vertex_ubo = vertex_res.uniform_buffers.first();
|
||||
let fragment_ubo = fragment_res.uniform_buffers.first();
|
||||
|
||||
self.reflect_ubos(vertex_ubo, fragment_ubo)?;
|
||||
|
||||
let vertex_push = vertex_res.push_constant_buffers.first();
|
||||
let fragment_push = fragment_res.push_constant_buffers.first();
|
||||
|
||||
self.reflect_push_constant_buffer(vertex_push, fragment_push)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -25,6 +25,9 @@ pub trait ReflectShader {
|
|||
pass_number: usize,
|
||||
semantics: &ShaderSemantics,
|
||||
) -> Result<ShaderReflection, ShaderReflectError>;
|
||||
|
||||
/// Validate the shader without doing reflection against a set of semantics.
|
||||
fn validate(&mut self) -> Result<(), ShaderReflectError>;
|
||||
}
|
||||
|
||||
pub use semantics::ShaderReflection;
|
||||
|
|
|
@ -239,7 +239,7 @@ impl ValidateTypeSemantics<&TypeInner> for TextureSemantics {
|
|||
|
||||
impl NagaReflect {
|
||||
fn reflect_ubos(
|
||||
&mut self,
|
||||
&self,
|
||||
vertex_ubo: Option<Handle<GlobalVariable>>,
|
||||
fragment_ubo: Option<Handle<GlobalVariable>>,
|
||||
) -> Result<Option<BufferReflection<u32>>, ShaderReflectError> {
|
||||
|
@ -429,7 +429,7 @@ impl NagaReflect {
|
|||
}
|
||||
}
|
||||
|
||||
fn validate(&self) -> Result<(), ShaderReflectError> {
|
||||
fn validate_semantics(&self) -> Result<(), ShaderReflectError> {
|
||||
// Verify types
|
||||
if self.vertex.global_variables.iter().any(|(_, gv)| {
|
||||
let ty = &self.vertex.types[gv.ty];
|
||||
|
@ -882,7 +882,7 @@ impl ReflectShader for NagaReflect {
|
|||
pass_number: usize,
|
||||
semantics: &ShaderSemantics,
|
||||
) -> Result<ShaderReflection, ShaderReflectError> {
|
||||
self.validate()?;
|
||||
self.validate_semantics()?;
|
||||
|
||||
// Validate verifies that there's only one uniform block.
|
||||
let vertex_ubo = self
|
||||
|
@ -1012,6 +1012,36 @@ impl ReflectShader for NagaReflect {
|
|||
meta,
|
||||
})
|
||||
}
|
||||
|
||||
fn validate(&mut self) -> Result<(), ShaderReflectError> {
|
||||
self.validate_semantics()?;
|
||||
let vertex_push = self
|
||||
.vertex
|
||||
.global_variables
|
||||
.iter()
|
||||
.find_map(|(handle, gv)| {
|
||||
if gv.space == AddressSpace::PushConstant {
|
||||
Some(handle)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
|
||||
let fragment_push = self
|
||||
.fragment
|
||||
.global_variables
|
||||
.iter()
|
||||
.find_map(|(handle, gv)| {
|
||||
if gv.space == AddressSpace::PushConstant {
|
||||
Some(handle)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
|
||||
self.reflect_push_constant_buffer(vertex_push, fragment_push)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -219,7 +219,10 @@ impl ShaderSemantics {
|
|||
/// Create pass semantics for a single pass in the given shader preset.
|
||||
///
|
||||
/// This is meant as a convenience function for reflection use only.
|
||||
pub fn create_pass_semantics<E>(preset: &ShaderPreset, index: usize) -> Result<ShaderSemantics, E>
|
||||
pub fn create_pass_semantics<E>(
|
||||
preset: &ShaderPreset,
|
||||
index: usize,
|
||||
) -> Result<ShaderSemantics, E>
|
||||
where
|
||||
E: From<ShaderReflectError>,
|
||||
E: From<PreprocessError>,
|
||||
|
@ -268,6 +271,4 @@ impl ShaderSemantics {
|
|||
texture_semantics,
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue