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;
|
type Context;
|
||||||
|
|
||||||
/// Consume the object and return the compiled output of the shader.
|
/// 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(
|
fn compile(
|
||||||
self,
|
self,
|
||||||
options: Self::Options,
|
options: Self::Options,
|
||||||
|
@ -139,6 +142,10 @@ where
|
||||||
) -> Result<ShaderReflection, ShaderReflectError> {
|
) -> Result<ShaderReflection, ShaderReflectError> {
|
||||||
self.backend.reflect(pass_number, semantics)
|
self.backend.reflect(pass_number, semantics)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn validate(&mut self) -> Result<(), ShaderReflectError> {
|
||||||
|
self.backend.validate()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ReflectShader + ?Sized> ReflectShader for Box<T> {
|
impl<T: ReflectShader + ?Sized> ReflectShader for Box<T> {
|
||||||
|
@ -149,6 +156,10 @@ impl<T: ReflectShader + ?Sized> ReflectShader for Box<T> {
|
||||||
) -> Result<ShaderReflection, ShaderReflectError> {
|
) -> Result<ShaderReflection, ShaderReflectError> {
|
||||||
(**self).reflect(pass_number, semantics)
|
(**self).reflect(pass_number, semantics)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn validate(&mut self) -> Result<(), ShaderReflectError> {
|
||||||
|
(**self).validate()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<O, T> CompileShader<T> for Box<O>
|
impl<O, T> CompileShader<T> for Box<O>
|
||||||
|
|
|
@ -72,6 +72,10 @@ impl ReflectShader for WriteSpirV {
|
||||||
) -> Result<ShaderReflection, ShaderReflectError> {
|
) -> Result<ShaderReflection, ShaderReflectError> {
|
||||||
self.reflect.reflect(pass_number, semantics)
|
self.reflect.reflect(pass_number, semantics)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn validate(&mut self) -> Result<(), ShaderReflectError> {
|
||||||
|
self.reflect.validate()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CompileShader<SPIRV> for WriteSpirV {
|
impl CompileShader<SPIRV> for WriteSpirV {
|
||||||
|
|
|
@ -160,7 +160,7 @@ impl<T> CrossReflect<T>
|
||||||
where
|
where
|
||||||
T: spirv_cross2::compile::CompilableTarget,
|
T: spirv_cross2::compile::CompilableTarget,
|
||||||
{
|
{
|
||||||
fn validate(
|
fn validate_semantics(
|
||||||
&self,
|
&self,
|
||||||
vertex_res: &AllResources,
|
vertex_res: &AllResources,
|
||||||
fragment_res: &AllResources,
|
fragment_res: &AllResources,
|
||||||
|
@ -714,7 +714,7 @@ where
|
||||||
) -> Result<ShaderReflection, ShaderReflectError> {
|
) -> Result<ShaderReflection, ShaderReflectError> {
|
||||||
let vertex_res = self.vertex.shader_resources()?.all_resources()?;
|
let vertex_res = self.vertex.shader_resources()?.all_resources()?;
|
||||||
let fragment_res = self.fragment.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 vertex_ubo = vertex_res.uniform_buffers.first();
|
||||||
let fragment_ubo = fragment_res.uniform_buffers.first();
|
let fragment_ubo = fragment_res.uniform_buffers.first();
|
||||||
|
@ -797,6 +797,23 @@ where
|
||||||
meta,
|
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)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -25,6 +25,9 @@ pub trait ReflectShader {
|
||||||
pass_number: usize,
|
pass_number: usize,
|
||||||
semantics: &ShaderSemantics,
|
semantics: &ShaderSemantics,
|
||||||
) -> Result<ShaderReflection, ShaderReflectError>;
|
) -> Result<ShaderReflection, ShaderReflectError>;
|
||||||
|
|
||||||
|
/// Validate the shader without doing reflection against a set of semantics.
|
||||||
|
fn validate(&mut self) -> Result<(), ShaderReflectError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub use semantics::ShaderReflection;
|
pub use semantics::ShaderReflection;
|
||||||
|
|
|
@ -239,7 +239,7 @@ impl ValidateTypeSemantics<&TypeInner> for TextureSemantics {
|
||||||
|
|
||||||
impl NagaReflect {
|
impl NagaReflect {
|
||||||
fn reflect_ubos(
|
fn reflect_ubos(
|
||||||
&mut self,
|
&self,
|
||||||
vertex_ubo: Option<Handle<GlobalVariable>>,
|
vertex_ubo: Option<Handle<GlobalVariable>>,
|
||||||
fragment_ubo: Option<Handle<GlobalVariable>>,
|
fragment_ubo: Option<Handle<GlobalVariable>>,
|
||||||
) -> Result<Option<BufferReflection<u32>>, ShaderReflectError> {
|
) -> Result<Option<BufferReflection<u32>>, ShaderReflectError> {
|
||||||
|
@ -429,7 +429,7 @@ impl NagaReflect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate(&self) -> Result<(), ShaderReflectError> {
|
fn validate_semantics(&self) -> Result<(), ShaderReflectError> {
|
||||||
// Verify types
|
// Verify types
|
||||||
if self.vertex.global_variables.iter().any(|(_, gv)| {
|
if self.vertex.global_variables.iter().any(|(_, gv)| {
|
||||||
let ty = &self.vertex.types[gv.ty];
|
let ty = &self.vertex.types[gv.ty];
|
||||||
|
@ -882,7 +882,7 @@ impl ReflectShader for NagaReflect {
|
||||||
pass_number: usize,
|
pass_number: usize,
|
||||||
semantics: &ShaderSemantics,
|
semantics: &ShaderSemantics,
|
||||||
) -> Result<ShaderReflection, ShaderReflectError> {
|
) -> Result<ShaderReflection, ShaderReflectError> {
|
||||||
self.validate()?;
|
self.validate_semantics()?;
|
||||||
|
|
||||||
// Validate verifies that there's only one uniform block.
|
// Validate verifies that there's only one uniform block.
|
||||||
let vertex_ubo = self
|
let vertex_ubo = self
|
||||||
|
@ -1012,6 +1012,36 @@ impl ReflectShader for NagaReflect {
|
||||||
meta,
|
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)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -219,7 +219,10 @@ impl ShaderSemantics {
|
||||||
/// Create pass semantics for a single pass in the given shader preset.
|
/// Create pass semantics for a single pass in the given shader preset.
|
||||||
///
|
///
|
||||||
/// This is meant as a convenience function for reflection use only.
|
/// 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
|
where
|
||||||
E: From<ShaderReflectError>,
|
E: From<ShaderReflectError>,
|
||||||
E: From<PreprocessError>,
|
E: From<PreprocessError>,
|
||||||
|
@ -268,6 +271,4 @@ impl ShaderSemantics {
|
||||||
texture_semantics,
|
texture_semantics,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue